static void doWork(Crew *crew, Work *work) { int status; struct stat filestat; struct dirent *dirbuf; status = lstat(work->path, &filestat); if (status != 0) return; if (S_ISDIR(filestat.st_mode)) { DIR *pDir = opendir(work->path); if (pDir == NULL) { return; } while ((dirbuf = readdir(pDir)) != NULL) { if (strcmp(dirbuf->d_name, ".") == 0 || strcmp(dirbuf->d_name, "..") == 0) { continue; } status = pthread_mutex_lock(&crew->mutex); if (status != 0) return; addWork(crew, work->path, dirbuf->d_name, work->string); status = pthread_cond_signal(&crew->go); if (status != 0) return; status = pthread_mutex_unlock(&crew->mutex); if (status != 0) return; } } else if (S_ISREG(filestat.st_mode)) { findStr(work); } }
BOOL LLImageWorker::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard) { // For most codecs, only mDiscardLevel data is available. // (see LLImageDXT for exception) if (discard >= 0 && discard != mFormattedImage->getDiscardLevel()) { llerrs << "Request for invalid discard level" << llendl; } checkWork(); if (mDecodedType == -2) { return TRUE; // aborted, done } if (mDecodedType != channel) { if (!haveWork()) { addWork(channel, mPriority); } return FALSE; } else { llassert_always(!haveWork()); llassert_always(mDecodedType == channel); raw = mDecodedImage; // smart pointer acquires ownership of data mDecodedImage = NULL; return TRUE; } }
int main(int argc,char* argv[]) { pthread_mutex_init(&m,NULL); int i; addWork(11); addWork(22); addWork(33); addWork(44); pthread_t ids[3]={0}; for(i=0;i<3;++i){ pthread_create(ids+i,NULL,workFunc,NULL); } sleep(20); pthread_mutex_destroy(&m); return 0; }
void workerThread (State *s) { taskID work; watchList *tasksToNotify, next; bool canQueue; do { task = getWork(dispatch); /* Do stuff */ atomicWrite(status[work] = INPROGRESS); doStuff(work); atomicWrite(status[work] = DONE); /* NOTE : Race condition */ tasksToNotify = getWatches(work); while (tasksToNotify != NULL) { next = tasksToNotify->tail; canQueue = TRUE; foreach (dep in dep[tasksToNotify->id]) { /* OPT : Watch ordering */ if (atomicRead(status[dep]) != DONE) { /* NOTE : Race condition */ if (moveWatch(watch[dep],tasksToNotify)) { canQueue = FALSE; break; } else { /* Have hit the race condition, try the next option */ assert(atomicRead(status[dep]) == DONE); } } } if (canQueue) { /* OPT : Save one work item */ addWork(*dispatch,tasksToNotify->id); deleteWatch(tasksToNotify); } tasksToNotify = next; } } while (1); /* NOTE : some kind of control for thread exit needed */ return; }
int startCrew(Crew *crew, char *path, char *string) { int status = 0; status = pthread_mutex_lock(&crew->mutex); if (status != 0) return status; while (crew->work_count > 0) { status = pthread_cond_wait(&crew->done, &crew->mutex); if (status != 0) { pthread_mutex_unlock(&crew->mutex); return status; } } addWork(crew, path, NULL, string); status = pthread_cond_signal(&crew->go); if (status != 0) { crew->first = NULL; crew->last = NULL; crew->work_count--; pthread_mutex_unlock(&crew->mutex); return status; } while (crew->work_count > 0) { status = pthread_cond_wait(&crew->done, &crew->mutex); if (status != 0) { perror("pthread_cond_wait done"); exit(EXIT_FAILURE); } } status = pthread_mutex_unlock(&crew->mutex); if (status != 0) { perror("unlock crew mutex"); exit(EXIT_FAILURE); } return 0; }
void mainThread (State *s) { /* Set up the DAG */ if (s->firstRun || s->updateNeeded) { dep = buildDAG(s); /* OPT : Dispatch order */ /* Other : Update anything that is indexed by task * (i.e. all arrays given length ID) */ } /* Reset the data structure */ foreach (id in ID) { watch[id] = NULL; } /* Initialise the dispatch queue */ foreach (id in ID) { /* OPT : Dispatch order */ if (dep[id] == EMPTYSET) { atomicWrite(status[id] = AVAILABLE); addWork(*dispatch,id); } else { atomicWrite(status[id] = WAITING); initialiseWatch(&watch[choose(dep[id])], id); /* OPT : Watch ordering */ } } /* INV : Data structure access invariants start here */ /* INV : Status only decrease from now */ /* INV : Watch list for id contains a subset of the things that depend on id */ /* INV : Each id appears in at most one watch list */ /* INV : doNotAdd only appears at the head of a watch list */ /* INV : if (watch[id] == doNotAdd) then { status[id] == DONE; } */ waitForWorkToBeCompleted(*dispatch); return; }
handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }