- Timestamp:
- Oct 21, 2024 8:46:49 PM (6 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/incdep.c
r3565 r3619 97 97 * Structures and Typedefs * 98 98 *******************************************************************************/ 99 struct incdep_worker_data 100 { 101 int worker_tid; /* -1 for main, index for the others. */ 102 unsigned int done_count; /* workers increment this */ 103 unsigned int flushed_count; /* main thread: flushed done count. */ 104 unsigned int todo_count; /* main thread: queued on todo */ 105 }; 106 99 107 struct incdep_variable_in_set 100 108 { … … 195 203 196 204 /* the list of files that needs reading. */ 197 static struct incdep * volatile incdep_head_todo; 198 static struct incdep * volatile incdep_tail_todo; 205 static struct incdep * volatile incdep_head_todo = NULL; 206 static struct incdep * volatile incdep_tail_todo = NULL; 207 static unsigned int volatile incdep_count_todo = 0; 199 208 200 209 /* the number of files that are currently being read. */ 201 static int volatile incdep_num_reading ;210 static int volatile incdep_num_reading = 0; 202 211 203 212 /* the list of files that have been read. */ 204 static struct incdep * volatile incdep_head_done; 205 static struct incdep * volatile incdep_tail_done; 213 static struct incdep * volatile incdep_head_done = NULL; 214 static struct incdep * volatile incdep_tail_done = NULL; 215 static unsigned int volatile incdep_count_done = 0; 206 216 207 217 … … 233 243 static malloc_zone_t *incdep_zone; 234 244 #endif 245 246 /* Worker specific data, the extra entry is for the main thread. 247 TODO: Move all parallel arrays in here to avoid unnecessary cacheline 248 sharing between worker threads. */ 249 static struct incdep_worker_data incdep_worker_data[INCDEP_MAX_THREADS + 1]; 235 250 236 251 … … 396 411 #elif defined (__OS2__) 397 412 _fmutex_request (&incdep_mtx, 0); 413 #elif !defined(CONFIG_WITHOUT_THREADS) 414 # error Misconfig? 398 415 #endif 399 416 } … … 585 602 incdep_worker (int thrd) 586 603 { 604 struct incdep_worker_data *thrd_data = &incdep_worker_data[thrd]; 605 thrd_data->worker_tid = thrd; 606 587 607 incdep_lock (); 588 608 … … 591 611 /* get job from the todo list. */ 592 612 613 struct incdep *tmp; 593 614 struct incdep *cur = incdep_head_todo; 594 615 if (!cur) … … 598 619 } 599 620 if (cur->next) 600 incdep_head_todo = cur->next; 621 { 622 assert (incdep_count_todo > 1); 623 assert (cur != incdep_tail_todo); 624 incdep_head_todo = cur->next; 625 } 601 626 else 602 incdep_head_todo = incdep_tail_todo = NULL; 627 { 628 assert (incdep_count_todo == 1); 629 assert (cur == incdep_tail_todo); 630 incdep_head_todo = incdep_tail_todo = NULL; 631 } 632 incdep_count_todo--; 603 633 incdep_num_reading++; 604 634 … … 620 650 incdep_num_reading--; 621 651 cur->next = NULL; 622 if (incdep_tail_done) 623 incdep_tail_done->next = cur; 652 tmp = incdep_tail_done; 653 if (tmp) 654 { 655 tmp->next = cur; 656 assert (incdep_count_done > 0); 657 } 624 658 else 625 incdep_head_done = cur; 659 { 660 assert (!incdep_head_done); 661 assert (incdep_count_done == 0); 662 incdep_head_done = cur; 663 } 626 664 incdep_tail_done = cur; 665 incdep_count_done++; 666 667 thrd_data->done_count++; 627 668 628 669 incdep_signal_done (); … … 866 907 { 867 908 unsigned i; 909 unsigned total_done = 0; 868 910 869 911 if (!incdep_initialized) … … 892 934 strcache2_term (&incdep_dep_strcaches[i]); 893 935 strcache2_term (&incdep_var_strcaches[i]); 936 937 /* accounting */ 938 total_done += incdep_worker_data[i].done_count; 894 939 } 895 940 incdep_num_threads = 0; 941 942 /* sanity check */ 943 if (total_done != incdep_worker_data[INCDEP_MAX_THREADS].flushed_count) 944 fprintf (stderr, "kmk/incdep: warning: total_done=%#x does not equal flushed_count=%#x!\n", 945 total_done, incdep_worker_data[INCDEP_MAX_THREADS].flushed_count); 946 if (total_done != incdep_worker_data[INCDEP_MAX_THREADS].todo_count) 947 fprintf (stderr, "kmk/incdep: warning: total_done=%#x does not equal todo_count=%#x!\n", 948 total_done, incdep_worker_data[INCDEP_MAX_THREADS].todo_count); 896 949 897 950 /* destroy the lock and condition variables / event objects. */ … … 2090 2143 incdep_flush_it (floc *f) 2091 2144 { 2145 struct incdep_worker_data *thrd_data = &incdep_worker_data[INCDEP_MAX_THREADS]; 2146 2092 2147 incdep_lock (); 2093 2148 for (;;) 2094 2149 { 2095 struct incdep *cur = incdep_head_done; 2150 struct incdep *cur = incdep_head_done; 2151 unsigned int count = incdep_count_done; 2096 2152 2097 2153 /* if the done list is empty, grab a todo list entry. */ 2098 if (!cur && incdep_head_todo)2154 if (!cur) 2099 2155 { 2100 2156 cur = incdep_head_todo; 2101 if (cur->next) 2102 incdep_head_todo = cur->next; 2103 else 2104 incdep_head_todo = incdep_tail_todo = NULL; 2105 incdep_unlock (); 2106 2107 incdep_read_file (cur, f); 2108 eval_include_dep_file (cur, f); 2109 incdep_freeit (cur); 2110 2111 incdep_lock (); 2112 continue; 2157 if (cur) 2158 { 2159 if (cur->next) 2160 { 2161 assert (incdep_count_todo > 1); 2162 assert (cur != incdep_tail_todo); 2163 incdep_head_todo = cur->next; 2164 } 2165 else 2166 { 2167 assert (incdep_count_todo == 1); 2168 assert (cur == incdep_tail_todo); 2169 incdep_head_todo = incdep_tail_todo = NULL; 2170 } 2171 incdep_count_todo--; 2172 thrd_data->todo_count--; 2173 incdep_unlock (); 2174 2175 incdep_read_file (cur, f); 2176 eval_include_dep_file (cur, f); 2177 incdep_freeit (cur); 2178 2179 incdep_lock (); 2180 continue; 2181 } 2113 2182 } 2114 2183 … … 2126 2195 /* we grab the entire done list and work thru it. */ 2127 2196 incdep_head_done = incdep_tail_done = NULL; 2197 incdep_count_done = 0; 2198 2128 2199 incdep_unlock (); 2129 2200 … … 2131 2202 { 2132 2203 struct incdep *next = cur->next; 2204 assert (count > 0); 2133 2205 #ifdef PARSE_IN_WORKER 2134 2206 incdep_flush_recorded_instructions (cur); … … 2137 2209 #endif 2138 2210 incdep_freeit (cur); 2211 thrd_data->flushed_count++; 2212 count--; 2139 2213 cur = next; 2140 2214 } 2215 assert (count == 0); 2141 2216 2142 2217 incdep_lock (); … … 2151 2226 eval_include_dep (const char *names, floc *f, enum incdep_op op) 2152 2227 { 2228 struct incdep_worker_data *thrd_data = &incdep_worker_data[INCDEP_MAX_THREADS]; 2153 2229 struct incdep *head = 0; 2154 2230 struct incdep *tail = 0; 2155 2231 struct incdep *cur; 2232 unsigned int count = 0; 2156 2233 const char *names_iterator = names; 2157 2234 const char *name; … … 2200 2277 head = cur; 2201 2278 tail = cur; 2279 count++; 2202 2280 } 2203 2281 … … 2222 2300 else 2223 2301 { 2302 struct incdep *tmp; 2303 2224 2304 /* initialize the worker threads and related stuff the first time around. */ 2225 2305 … … 2231 2311 incdep_lock (); 2232 2312 2233 if (incdep_tail_todo) 2234 incdep_tail_todo->next = head; 2313 tmp = incdep_tail_todo; 2314 if (tmp) 2315 { 2316 assert (incdep_count_todo > 0); 2317 assert (incdep_head_todo != NULL); 2318 tmp->next = head; 2319 } 2235 2320 else 2236 incdep_head_todo = head; 2321 { 2322 assert (incdep_count_todo == 0); 2323 assert (incdep_head_todo == NULL); 2324 incdep_head_todo = head; 2325 } 2237 2326 incdep_tail_todo = tail; 2327 incdep_count_todo += count; 2328 thrd_data->todo_count += count; 2238 2329 2239 2330 incdep_signal_todo ();
Note:
See TracChangeset
for help on using the changeset viewer.