/** * Cleanup worker contexts * */ void LpelWorkerCleanup(void) { workerctx_t *wc; /* wait on workers */ for(int i = 0; i < num_workers; i++) { wc = WORKER_PTR(i); /* wait for the worker to finish */ (void) pthread_join( wc->thread, NULL); } /* cleanup the data structures */ for(int i = 0; i < num_workers; i++) { wc = WORKER_PTR(i); LpelMailboxDestroy(wc->mailbox); LpelSchedDestroy( wc->sched); PlacementDestroyWorker(wc->placement_data); free(wc); } /* free workers table */ free( workers); /* cleanup spmdext module */ LpelSpmdCleanup(); #ifndef HAVE___THREAD pthread_key_delete(workerctx_key); #endif /* HAVE___THREAD */ }
/* * clean up for both worker and master */ void LpelWorkersCleanup(void) { int i; workerctx_t *wc; for(i=0; i<num_workers; i++) { wc = workers[i]; /* wait for the worker to finish */ (void) pthread_join(wc->thread, NULL); } /* wait for the master to finish */ (void) pthread_join(master->thread, NULL); /* clean up master's mailbox */ cleanupMasterMb(); LpelMailboxDestroy(master->mailbox); LpelTaskqueueDestroy(master->ready_tasks); /* cleanup the data structures */ for(i=0; i<num_workers; i++) { wc = workers[i]; LpelMailboxDestroy(wc->mailbox); LpelWorkerDestroyStream(wc); LpelWorkerDestroySd(wc); free(wc); } /* free workers tables */ free(workers); free(master->waitworkers); /* clean up local vars used in worker operations */ cleanupLocalVar(); free(master); }
void cleanupLocalVar(){ #ifndef HAVE___THREAD pthread_key_delete(workerctx_key); #endif /* HAVE___THREAD */ /* free wrappers */ workerctx_t *wp = freewrappers; workerctx_t *next; while (wp != NULL) { next = wp->next; LpelMailboxDestroy(wp->mailbox); LpelWorkerDestroyStream(wp); LpelWorkerDestroySd(wp); free(wp); wp = next; } PRODLOCK_DESTROY(&lockwrappers); /* mailboxes */ free(workermbs); }
/** * Thread function for workers (and wrappers) */ static void *WorkerThread( void *arg) { workerctx_t *wc = (workerctx_t *)arg; lpel_task_t *t; #ifdef HAVE___THREAD workerctx_cur = wc; #else /* HAVE___THREAD */ /* set pointer to worker context as TSD */ pthread_setspecific(workerctx_key, wc); #endif /* HAVE___THREAD */ #ifdef USE_MCTX_PCL int res = co_thread_init(); assert( 0 == res); wc->mctx = co_current(); #endif wc->current_task = NULL; /* no task marked for deletion */ wc->marked_del = NULL; /* assign to cores */ LpelThreadAssign( wc->wid); /*******************************************************/ if ( wc->wid >= 0) { WorkerLoop( wc); } else { WrapperLoop( wc); } /*******************************************************/ #ifdef USE_LOGGING /* cleanup monitoring */ if (wc->mon && MON_CB(worker_destroy)) { MON_CB(worker_destroy)(wc->mon); } #endif /* destroy all the free tasks */ while ((t = LpelPopTask(free, &wc->free_tasks))) { LpelTaskDestroy(t); } /* on a wrapper, we also can cleanup more*/ if (wc->wid < 0) { /* clean up the mailbox for the worker */ LpelMailboxDestroy(wc->mailbox); /* free the worker context */ free( wc); } #ifdef USE_MCTX_PCL co_thread_cleanup(); #endif return NULL; }