void manager(struct stim_param *p) { static int num_of_call=0; num_of_call++; if( p->vars[p->neur_to][2] == 0) { proc_err("WARNING:stimpool.c: neur with bad fire strength: obj%u:neur%u:fire_strength = 0\n",4,p->nobj_props->nobj_id,p->neur_to); } int worker = (*p->nobj_props).nobj_id % num_of_workers; if(contracts[worker].pool_size<max_queue-1) { if(contracts[worker].pool_size+1==contracts[worker].current_job) { proc_err("ERROR:stimpool.c: OBJ ID: %u has a backed up work queue(!0), dropping job!!!\nCurrent Job #[%d]\n",2,(*p->nobj_props).nobj_id,contracts[worker].current_job ); } else { if(p != NULL) { copy_stim_param(*p,&work_pool[worker][contracts[worker].pool_size+1]); contracts[worker].pool_size++; } else { printf(" manager: received null stim_param\n"); } } } else {//at max queue number if(contracts[worker].current_job==0) {//next available job isn't done proc_err("ERROR:stimpool.c: OBJ ID: %u has a backed up work queue, dropping job!!!Current Job #[%d], max queue: %d\n",2,(*(*p).nobj_props).nobj_id,contracts[worker].current_job,max_queue ); } else { contracts[worker].pool_size=0; copy_stim_param(*p,&work_pool[worker][contracts[worker].pool_size]); } } }
// (num_of_threads to make) void init_workers(int num) { proc_err("\n=====Init Workers====\n",0); proc_err("Creating %d threads\n",0, num); int i = 0; int j =0; num_of_workers=num; workers=malloc(sizeof(workers[0])*num); contracts=malloc(sizeof(contracts[0])*num); work_pool=malloc(sizeof(struct stim_param*)*num);//alloc pool for each all threads for(i;i<num;++i) { j=0; contracts[i].id=i; contracts[i].fired=0; contracts[i].pool_size=-1; contracts[i].current_job=-1; contracts[i].time_to_sleep=1000;//has limited effect, workers only sleep when there are no jobs left in queue contracts[i].progress=0; contracts[i].progress_step=.0001; work_pool[i]=malloc(sizeof(struct stim_param)*max_queue);//alloc space for job proc_err("Debug:Creating stimpool worker thread\n",5); pthread_create(&workers[i],NULL,worker_thread,&contracts[i]); } }
void readinput(register pb_t *ppb) { register int i; resp_t *rp; /* ** Top Loop. ** Executed once for each complete block read. Normally ** only executed once, but can be more if an error ** block is read. ** ** We mark Qbuf first, so we can free any parameters ** when they are no longer needed (such as when they ** are passed to another process). */ Ctx.ctx_pmark = markbuf(Qbuf); #ifdef xCTR1 if (tTf(10, 0)) lprintf("readinput: mark %d, errfn %x, ppb %x\n", Ctx.ctx_pmark, Ctx.ctx_errfn, ppb); #endif rp = getresp(); for (;;) { /* prime the input (reads first block) */ pb_prime(ppb, PB_NOTYPE); #ifdef xCTR2 if (tTf(10, 1)) lprintf("readinput: type %d\n", ppb->pb_type); #endif /* if this is a response block, return immediately */ if (ppb->pb_type == PB_RESP) { i = pb_get(ppb, (char *) rp, sizeof(resp_t)); if (i != sizeof(resp_t)) syserr("readinput: resp_t sz %d", i); /* read_arg(ppb, &rp->resp_rval); */ break; } /* ** Parameter Loop. ** Wander through and start reading parameters. */ for (Ctx.ctx_pc = 0; Ctx.ctx_pc < PV_MAXPC; Ctx.ctx_pc++) { if (read_arg(ppb, &Ctx.ctx_pv[Ctx.ctx_pc]) == PV_EOF) break; } /* out of loop, check for vector overflow */ if (Ctx.ctx_pc >= PV_MAXPC) syserr("readinput: overflow"); /* check for error blocks */ if (ppb->pb_type == PB_ERR) { proc_err(ppb, Ctx.ctx_pc, Ctx.ctx_pv); syserr("readinput: proc_err"); } /* non-error block */ #ifdef xCM_DEBUG if (ppb->pb_type != PB_REG) syserr("readinput: pb_type %d", ppb->pb_type); #endif Ctx.ctx_resp = ppb->pb_resp; break; } #ifdef xCTR1 if (tTf(10, 4)) { lprintf("readinput: "); pb_dump(ppb, FALSE); } #endif }