/** * 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 */ }
/** * Get a worker context from the worker id */ workerctx_t *LpelWorkerGetContext(int id) { workerctx_t *wc = NULL; if (id >= 0 && id < num_workers) { wc = WORKER_PTR(id); } /* create a new worker context for a wrapper */ if (id == -1) { wc = (workerctx_t *) malloc( sizeof( workerctx_t)); wc->wid = -1; wc->terminate = 0; /* Wrapper is excluded from scheduling module */ wc->sched = NULL; wc->wraptask = NULL; wc->mon = NULL; /* mailbox */ wc->mailbox = LpelMailboxCreate(); /* LIFO of free tasks */ atomic_init( &wc->free_tasks, NULL); (void) pthread_create( &wc->thread, NULL, WorkerThread, wc); (void) pthread_detach( wc->thread); } assert((wc != NULL) && "The worker of the requested id does not exist."); return wc; }
/** * Get a worker context from the worker id */ workerctx_t *LpelWorkerGetContext(int id) { workerctx_t *wc = NULL; if (id >= 0 && id < num_workers) { wc = WORKER_PTR(id); } /* create a new worker context for a wrapper */ if (id == LPEL_MAP_OTHERS) { wc = (workerctx_t *) malloc( sizeof( workerctx_t)); wc->wid = LPEL_MAP_OTHERS; wc->terminate = 0; /* Wrapper is excluded from scheduling module */ wc->sched = NULL; wc->wraptask = NULL; wc->mon = NULL; /* mailbox */ wc->mailbox = LpelMailboxCreate(0); /* taskqueue of free tasks */ //LpelTaskqueueInit( &wc->free_tasks); (void) pthread_create( &wc->thread, NULL, WorkerThread, wc); (void) pthread_detach( wc->thread); } assert(wc != NULL); return wc; }
void LpelWorkerSpawn(void) { int i; /* create worker threads */ for( i=0; i<num_workers; i++) { workerctx_t *wc = WORKER_PTR(i); /* spawn joinable thread */ (void) pthread_create( &wc->thread, NULL, WorkerThread, wc); } }
void LpelWorkerBroadcast(workermsg_t *msg) { int i; workerctx_t *wc; for( i=0; i<num_workers; i++) { wc = WORKER_PTR(i); /* send */ LpelMailboxSend(wc->mailbox, msg); } }
/** * Initialise worker globally * * * @param size size of the worker set, i.e., the total number of workers */ void LpelWorkersInit(int size) { int i, res; assert(0 <= size); num_workers = size; #ifndef HAVE___THREAD /* init key for thread specific data */ pthread_key_create(&workerctx_key, NULL); #endif /* HAVE___THREAD */ /* initialize spmdext module */ res = LpelSpmdInit(num_workers); /* allocate worker context table */ workers = (workerctx_t **) malloc( num_workers * sizeof(workerctx_t*) ); /* allocate worker contexts */ for (i=0; i<num_workers; i++) { workers[i] = (workerctx_t *) malloc( sizeof(workerctx_t) ); } /* prepare data structures */ for( i=0; i<num_workers; i++) { workerctx_t *wc = WORKER_PTR(i); wc->wid = i; wc->num_tasks = 0; wc->terminate = 0; wc->sched = LpelSchedCreate( i); wc->wraptask = NULL; #ifdef USE_LOGGING if (MON_CB(worker_create)) { wc->mon = MON_CB(worker_create)(wc->wid); } else { wc->mon = NULL; } #else wc->mon = NULL; #endif /* mailbox */ wc->mailbox = LpelMailboxCreate(0); /* taskqueue of free tasks */ //LpelTaskqueueInit( &wc->free_tasks); } assert(res==0); }