IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 18, 2010, 2:25:38 PM (16 years ago)
Author:
Paul Price
Message:

Discovered a race condition in the threading process. The thread process was: psThreadJobAlloc, populate job with arguments, psThreadJobAddPending, psFree the job. This is not thread-safe, because we're decrementing the job's reference counter while the reference count is also being fiddled within the thread system (psThread.c; by pulling the job off the 'pending' queue and putting it on the 'done' queue). The reference count fiddling within the thread system was protected by a mutex, but the external free was not. Therefore, I'm pulling the free into the thread system so it can be protected (without the user having to worry about locks to do the simple case). This means that the user should no longer touch the job once he hands it over to the thread system (unless it's protected by calls to psThreadLock/psThreadUnlock, or it's on the other side of psThreadPoolWait from all the adds so that the threads aren't doing anything).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/psphotBlendFit.c

    r28013 r28405  
    1515    // loop over the available readouts
    1616    for (int i = 0; i < num; i++) {
    17         if (!psphotBlendFitReadout (config, view, filerule, i, recipe)) {
     17        if (!psphotBlendFitReadout (config, view, filerule, i, recipe)) {
    1818            psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (non-linear) for %s entry %d", filerule, i);
    19             return false;
    20         }
     19            return false;
     20        }
    2121    }
    2222    return true;
     
    4848
    4949    if (!sources->n) {
    50         psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping blend fit");
    51         return true;
     50        psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping blend fit");
     51        return true;
    5252    }
    5353
     
    8787    sources = psArraySort (sources, pmSourceSortBySN);
    8888    if (!sources->n) {
    89         psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping blend");
    90         return true;
     89        psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping blend");
     90        return true;
    9191    }
    9292
     
    103103        for (int j = 0; j < cells->n; j++) {
    104104
    105             // allocate a job -- if threads are not defined, this just runs the job
    106             psThreadJob *job = psThreadJobAlloc ("PSPHOT_BLEND_FIT");
    107             psArray *newSources = psArrayAllocEmpty(16);
    108 
    109             psArrayAdd(job->args, 1, readout);
    110             psArrayAdd(job->args, 1, recipe);
    111             psArrayAdd(job->args, 1, cells->data[j]); // sources
    112             psArrayAdd(job->args, 1, psf);
    113             psArrayAdd(job->args, 1, newSources); // return for new sources
    114             psFree (newSources);
    115 
    116             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfit
    117             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npsf
    118             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next
    119             PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
    120 
    121             if (!psThreadJobAddPending(job)) {
    122                 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    123                 psFree (job);
    124                 return NULL;
    125             }
    126             psFree(job);
     105            // allocate a job -- if threads are not defined, this just runs the job
     106            psThreadJob *job = psThreadJobAlloc ("PSPHOT_BLEND_FIT");
     107            psArray *newSources = psArrayAllocEmpty(16);
     108
     109            psArrayAdd(job->args, 1, readout);
     110            psArrayAdd(job->args, 1, recipe);
     111            psArrayAdd(job->args, 1, cells->data[j]); // sources
     112            psArrayAdd(job->args, 1, psf);
     113            psArrayAdd(job->args, 1, newSources); // return for new sources
     114            psFree (newSources);
     115
     116            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfit
     117            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npsf
     118            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next
     119            PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
     120
     121            if (!psThreadJobAddPending(job)) {
     122                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     123                return NULL;
     124            }
    127125
    128126# if (0)
     
    152150        }
    153151
    154         // wait for the threads to finish and manage results
    155         if (!psThreadPoolWait (false)) {
    156             psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
    157             return NULL;
    158         }
    159 
    160         // we have only supplied one type of job, so we can assume the types here
    161         psThreadJob *job = NULL;
    162         while ((job = psThreadJobGetDone()) != NULL) {
    163             if (job->args->n < 1) {
    164                 fprintf (stderr, "error with job\n");
    165             } else {
    166                 psScalar *scalar = NULL;
    167                 scalar = job->args->data[5];
    168                 Nfit += scalar->data.S32;
    169                 scalar = job->args->data[6];
    170                 Npsf += scalar->data.S32;
    171                 scalar = job->args->data[7];
    172                 Next += scalar->data.S32;
    173                 scalar = job->args->data[8];
    174                 Nfail += scalar->data.S32;
    175 
    176                 // add these back onto sources
    177                 psArray *newSources = job->args->data[4];
    178                 for (int j = 0; j < newSources->n; j++) {
    179                     psArrayAdd (sources, 16, newSources->data[j]);
    180                 }
    181             }
    182             psFree(job);
     152        // wait for the threads to finish and manage results
     153        if (!psThreadPoolWait (false)) {
     154            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     155            return NULL;
     156        }
     157
     158        // we have only supplied one type of job, so we can assume the types here
     159        psThreadJob *job = NULL;
     160        while ((job = psThreadJobGetDone()) != NULL) {
     161            if (job->args->n < 1) {
     162                fprintf (stderr, "error with job\n");
     163            } else {
     164                psScalar *scalar = NULL;
     165                scalar = job->args->data[5];
     166                Nfit += scalar->data.S32;
     167                scalar = job->args->data[6];
     168                Npsf += scalar->data.S32;
     169                scalar = job->args->data[7];
     170                Next += scalar->data.S32;
     171                scalar = job->args->data[8];
     172                Nfail += scalar->data.S32;
     173
     174                // add these back onto sources
     175                psArray *newSources = job->args->data[4];
     176                for (int j = 0; j < newSources->n; j++) {
     177                    psArrayAdd (sources, 16, newSources->data[j]);
     178                }
     179            }
     180            psFree(job);
    183181            }
    184182    }
     
    278276                psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);
    279277                Next ++;
    280                 source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
     278                source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
    281279                continue;
    282280            }
     
    286284                psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);
    287285                Npsf ++;
    288                 source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
     286                source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
    289287                continue;
    290288            }
Note: See TracChangeset for help on using the changeset viewer.