IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 24, 2010, 2:59:09 PM (16 years ago)
Author:
Paul Price
Message:

Merging trunk in advance of reintegrating into trunk.

Location:
branches/pap
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/pap

  • branches/pap/psLib/src/sys/psThread.c

    r28140 r28484  
    77#include <unistd.h>
    88#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
     15static void **bt_buffer = NULL;         // Backtrace buffer
     16static int bt_size = 0;                 // Backtrace buffer size
     17#endif
    918
    1019#include "psAssert.h"
     
    2938static psList *pending = NULL;          // queue of pending jobs
    3039static psList *done = NULL;             // queue of done jobs
     40static pthread_t *threads = NULL;       // array of the POSIX thread handles
    3141static psArray *pool = NULL;            // array of defined threads
    3242static psHash *tasks = NULL;            // List of defined tasks
     
    8999bool psThreadJobAddPending(psThreadJob *job)
    90100{
    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);
    92109
    93110    // if we failed to call psThreadPoolInit, or we called it with nThreads == 0,
     
    100117        }
    101118        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);
    107120        return task->function(job);
    108121    }
     
    113126    }
    114127    psListAdd(pending, PS_LIST_TAIL, job);
     128    psFree(job);
    115129    psThreadUnlock();
    116130
     
    209223
    210224        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
    211244        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);
    213248        bool status = task->function(job); // Status of executing task
    214249
     
    234269bool psThreadPoolInit(int nThreads)
    235270{
    236     if (pool) {
     271    if (pool || threads) {
    237272        psAbort("psThreadsInit already called");
    238273    }
     
    245280
    246281    pool = psArrayAlloc(nThreads);
     282    threads = psAlloc(nThreads * sizeof(pthread_t));
    247283    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        }
    251288    }
    252289    return true;
     
    280317        return true;
    281318    }
     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
    282327
    283328    while (1) {
     
    326371bool psThreadPoolFinalize(void)
    327372{
     373    psThreadLock();
    328374    psFree(pending);
    329375    pending = NULL;
     
    335381    pool = NULL;
    336382
     383    psFree(threads);
     384    threads = NULL;
     385
    337386    psFree(tasks);
    338387    tasks = NULL;
     
    340389    psFree(tsd);
    341390    tsd = NULL;
     391
     392#ifdef HAVE_BACKTRACE
     393    if (bt_buffer) {
     394        psFree(bt_buffer);
     395    }
     396#endif
     397
     398    psThreadUnlock();
    342399
    343400    return true;
Note: See TracChangeset for help on using the changeset viewer.