IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 27, 2010, 11:14:33 AM (16 years ago)
Author:
Paul Price
Message:

Reworking the locking again, now it's a bit clearer in my mind. Added rules on what needs to be locked.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/sys/psThread.c

    r28138 r28140  
    2121#define TASK_BUCKETS 8                  // Number of hash buckets for task list
    2222
     23// Mutex covers:
     24// * pending queue
     25// * done queue
     26// * thread->busy states
    2327static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Mutex for locking threads
     28
    2429static psList *pending = NULL;          // queue of pending jobs
    2530static psList *done = NULL;             // queue of done jobs
     
    2833static psArray *tsd = NULL;             // Thread-specific data
    2934
    30 
    3135/***** basic thread functions *****/
    3236
     
    121125    }
    122126
    123     psThreadLock();
    124127    psThreadJob *job = psListGetAndRemove(pending, PS_LIST_HEAD);
    125     psThreadUnlock();
    126128    return job;
    127129}
     
    134136    }
    135137
    136     psThreadLock();
    137138    psThreadJob *job = psListGetAndRemove(done, PS_LIST_HEAD);
    138     psThreadUnlock();
    139139    return job;
    140140}
     
    198198        // we have to lock here so the job queue cannot be empty yet no threads busy
    199199        psThreadJob *job = NULL;        // Job to process
     200        psThreadLock();
    200201        while ((job = psThreadJobGetPending()) == NULL) {
     202            // Unlock while sleeping, then lock to read the pending queue again
     203            psThreadUnlock();
    201204            usleep(THREAD_WAIT);
     205            psThreadLock();
    202206        }
    203207        self->busy = true;
     208        psThreadUnlock();
    204209
    205210        psThreadTask *task = psHashLookup(tasks, job->type); // Task to execute job
     
    215220        psListAdd(done, PS_LIST_TAIL, job);
    216221        psFree(job);
    217         psThreadUnlock();
    218222
    219223        if (!status) {
     
    221225        }
    222226        self->busy = false;
     227        psThreadUnlock();
    223228    }
    224229}
     
    253258}
    254259
    255 // Harvest jobs from the
     260// Harvest jobs from the done list
    256261static void psThreadJobHarvest(void)
    257262{
     
    270275        // Ensure everything is harvested, if requested
    271276        if (harvest) {
     277            // No threads, no no need to lock
    272278            psThreadJobHarvest();
    273279        }
     
    284290        }
    285291
     292        psThreadLock();
     293
    286294        // Harvest jobs in the background, if requested
    287295        if (harvest) {
     
    289297        }
    290298
    291 #if 0 // Thread state doesn't matter, only the pending job queue
    292299        // are all threads idle?
    293300        for (int i = 0; i < pool->n; i++) {
     
    298305            }
    299306        }
    300 #endif
    301 
    302         psThreadLock();
    303         bool more = (pending && pending->head) ? true : false; // More to process?
    304         psThreadUnlock();
    305 
    306         if (!more) {
    307             // Nothing in the queue
     307
     308        if (!pending || !pending->head) {
     309            // Nothing in the queue and nothing more to add
    308310            // Ensure everything is harvested, if requested
    309311            if (harvest) {
    310312                psThreadJobHarvest();
    311313            }
     314            psThreadUnlock();
    312315            return true;
    313316        }
    314317
     318    SLEEP:
     319        psThreadUnlock();
    315320        usleep(THREAD_WAIT);
    316321    }
Note: See TracChangeset for help on using the changeset viewer.