Changeset 28484 for branches/pap/psLib/src/sys/psThread.c
- Timestamp:
- Jun 24, 2010, 2:59:09 PM (16 years ago)
- Location:
- branches/pap
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psLib/src/sys/psThread.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/pap
- Property svn:mergeinfo changed
-
branches/pap/psLib/src/sys/psThread.c
r28140 r28484 7 7 #include <unistd.h> 8 8 #include <string.h> 9 10 // Backtrace to help nail down bugs 11 #ifdef HAVE_BACKTRACE 12 #include <execinfo.h> 13 #include <stdlib.h> 14 #define BACKTRACE_BUFFER_SIZE 256 // Maximum size of backtrace 15 static void **bt_buffer = NULL; // Backtrace buffer 16 static int bt_size = 0; // Backtrace buffer size 17 #endif 9 18 10 19 #include "psAssert.h" … … 29 38 static psList *pending = NULL; // queue of pending jobs 30 39 static psList *done = NULL; // queue of done jobs 40 static pthread_t *threads = NULL; // array of the POSIX thread handles 31 41 static psArray *pool = NULL; // array of defined threads 32 42 static psHash *tasks = NULL; // List of defined tasks … … 89 99 bool psThreadJobAddPending(psThreadJob *job) 90 100 { 91 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 101 if (!job) { 102 // Asking for a no-op 103 return true; 104 } 105 106 psThreadTask *task = psHashLookup(tasks, job->type); // Task to execute job 107 psAssert(task, "Unable to find task %s", job->type); 108 psAssert(job->args->n == task->nArgs, "invalid number of arguments to %s", task->type); 92 109 93 110 // if we failed to call psThreadPoolInit, or we called it with nThreads == 0, … … 100 117 } 101 118 psListAdd(done, PS_LIST_TAIL, job); 102 103 // find the corresponding task and run it 104 psThreadTask *task = psHashLookup(tasks, job->type); // Task to execute job 105 psAssert(task, "Unable to find task %s", job->type); 106 psAssert(job->args->n == task->nArgs, "invalid number of arguments to %s", task->type); 119 psFree(job); 107 120 return task->function(job); 108 121 } … … 113 126 } 114 127 psListAdd(pending, PS_LIST_TAIL, job); 128 psFree(job); 115 129 psThreadUnlock(); 116 130 … … 209 223 210 224 psThreadTask *task = psHashLookup(tasks, job->type); // Task to execute job 225 #ifdef HAVE_BACKTRACE 226 if (!task && bt_buffer) { 227 psLogMsg("psLib.sys", PS_LOG_ABORT, "Backtrace of waiter:\n"); 228 char **strings = backtrace_symbols((void *const *)bt_buffer, bt_size); 229 psLogMsg("psLib.sys", PS_LOG_ABORT, "Backtrace depth: %d", bt_size); 230 for (int i = 0; i < bt_size; i++) { 231 char *caller = strchr(strings[i], '('); 232 if (caller) { 233 caller++; 234 size_t callerLength = abs(strchr(caller, '+') - caller); 235 psString name = psStringNCopy(caller, callerLength); 236 psLogMsg("psLib.sys", PS_LOG_ABORT, "Backtrace %d: %s", i, name); 237 psFree(name); 238 } else { 239 psLogMsg("psLib.sys", PS_LOG_ABORT, "Backtrace %d: (unknown)", i); 240 } 241 } 242 } 243 #endif 211 244 psAssert(task, "Couldn't find thread task %s", job->type); 212 psAssert(job->args->n == task->nArgs, "invalid number of arguments to %s (%ld supplied, expected %d)", task->type, job->args->n, task->nArgs); 245 psAssert(job->args->n == task->nArgs, 246 "invalid number of arguments to %s (%ld supplied, expected %d)", 247 task->type, job->args->n, task->nArgs); 213 248 bool status = task->function(job); // Status of executing task 214 249 … … 234 269 bool psThreadPoolInit(int nThreads) 235 270 { 236 if (pool ) {271 if (pool || threads) { 237 272 psAbort("psThreadsInit already called"); 238 273 } … … 245 280 246 281 pool = psArrayAlloc(nThreads); 282 threads = psAlloc(nThreads * sizeof(pthread_t)); 247 283 for (int i = 0; i < nThreads; i++) { 248 psThread *thread = psThreadAlloc(); // Thread for pool 249 pthread_create(&thread->pt, NULL, psThreadLauncher, thread); 250 pool->data[i] = thread; 284 psThread *thread = pool->data[i] = psThreadAlloc(); // Thread for pool 285 if (pthread_create(&threads[i], NULL, psThreadLauncher, thread)) { 286 psAbort("Unable to create thread"); 287 } 251 288 } 252 289 return true; … … 280 317 return true; 281 318 } 319 320 #ifdef HAVE_BACKTRACE 321 if (bt_buffer) { 322 psFree(bt_buffer); 323 } 324 bt_buffer = psAlloc(BACKTRACE_BUFFER_SIZE * sizeof(void *)); 325 bt_size = backtrace(bt_buffer, BACKTRACE_BUFFER_SIZE); 326 #endif 282 327 283 328 while (1) { … … 326 371 bool psThreadPoolFinalize(void) 327 372 { 373 psThreadLock(); 328 374 psFree(pending); 329 375 pending = NULL; … … 335 381 pool = NULL; 336 382 383 psFree(threads); 384 threads = NULL; 385 337 386 psFree(tasks); 338 387 tasks = NULL; … … 340 389 psFree(tsd); 341 390 tsd = NULL; 391 392 #ifdef HAVE_BACKTRACE 393 if (bt_buffer) { 394 psFree(bt_buffer); 395 } 396 #endif 397 398 psThreadUnlock(); 342 399 343 400 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
