/*----------------------------------------------------------------------------* * NAME * timerAlloc * * DESCRIPTION * A helper function for allocating timer containers which are * taken from the thread-specific free list or allocated using * pnew(). * * RETURNS * TimerType * * *----------------------------------------------------------------------------*/ static TimerType *timerAlloc(ThreadInstanceType *thread) { TimerType *timer; /* * If there is a timer on the free list, pick * the one in front (order doesn't matter on the * free list and the first is more likely to be * in cache). * * If there is no timer on the free list and we * have not yet exceeded the limit, allocate a * new one and insert it to the timer list. * * If the limit is exceeded, we panic. */ if (thread->timerFreeList != NULL) { timer = thread->timerFreeList; thread->timerFreeList = timer->next; } else if (thread->timers < _SCHED_TIMER_POOL_LIMIT) { thread->timers++; timer = pnew(TimerType); timer->id = thread->timers; thread->timer[timer->id] = timer; } else { timer = NULL; // Panic(_TECH_FW, _PANIC_FW_UNKNOWN_TASK, "Timer limit exceeded"); } return timer; }
/*----------------------------------------------------------------------------* * NAME * messageAlloc * * DESCRIPTION * A helper function for allocating message containers which are * taken from the thread-specific free list or allocated using * pnew(). * * RETURNS * MessageQueueEntryType * * *----------------------------------------------------------------------------*/ static MessageQueueEntryType *messageAlloc(ThreadInstanceType *thread) { MessageQueueEntryType *message; /* * If there is a message on the free list, pick * the one in front (order doesn't matter on the * free list and the first is more likely to be * in cache), and allocate a new one otherwise. */ if (thread->messageFreeList != NULL) { message = thread->messageFreeList; thread->messageFreeList = message->next; thread->messageFreeListLength--; } else { message = pnew(MessageQueueEntryType); } return message; }
/*----------------------------------------------------------------------------* * NAME * do_put_message * * DESCRIPTION * Does the actual work of SchedMessagePut(). * * RETURNS * - * *----------------------------------------------------------------------------*/ static void do_put_message(Task dst, uint16 mi, void *mv) { ThreadInstanceType *src_thread; Task currentTask; uint16 qi; uint8 src_index, dest_index; src_index = GetThreadIndex(); if (src_index < _SCHED_MAX_SEGMENTS) { src_thread = &instance->thread[src_index]; currentTask = src_thread->currentTask; } else { src_thread = NULL; currentTask = _SCHED_TASK_ID; } /* Get segment and task index */ dest_index = QUEUE_EXTRACT_SEGMENT(dst); qi = QUEUE_EXTRACT_INDEX(dst); if (dest_index < _SCHED_MAX_SEGMENTS) { /* this message is destined for another sched task */ MessageQueueEntryType *message; ThreadInstanceType *dest_thread = &instance->thread[dest_index]; if (!dest_thread->inUse || (qi >= dest_thread->numberOfTasks)) { /* Task index is out-of-bounds */ GENERROR(("dest_thread->numberOfTasks=%d,qi=%d\n", dest_thread->numberOfTasks, qi)); GENERROR(("Invalid receiver task")); return; // Panic(_TECH_FW, _PANIC_FW_UNKNOWN_TASK, "Invalid receiver task"); } /* Package the message for queue storage. */ if (currentTask != _SCHED_TASK_ID) { message = messageAlloc(src_thread); } else { message = pnew(MessageQueueEntryType); } message->next = NULL; message->event = mi; message->sender = currentTask; message->message = mv; if (src_index == dest_index) { /* message to the calling thread */ TaskDefinitionType *task; task = &dest_thread->tasks[qi]; /* Store the message on the end of the task's message chain. */ if (task->messageQueueLast == NULL) { task->messageQueueFirst = message; task->messageQueueLast = message; } else { task->messageQueueLast->next = message; task->messageQueueLast = message; } dest_thread->pendingMessages++; } else { /* message to another thread than the calling */ message->receiver = qi; MutexLock(&dest_thread->qMutex); if (dest_thread->extMsgQueueLast == NULL) { dest_thread->extMsgQueueFirst = message; dest_thread->extMsgQueueLast = message; } else { dest_thread->extMsgQueueLast->next = message; dest_thread->extMsgQueueLast = message; } MutexUnlock(&dest_thread->qMutex); EventSet(&dest_thread->eventHandle, EXT_MSG_EVENT); } } else { /* this message is destined for an external receiver */ if (externalSend != NULL) { /* Message flagged for remote scheduler/thread thingy */ externalSend(dst, mi, mv); } else { /* Not handler for this segment! */ // Panic(_TECH_FW, _PANIC_FW_UNKNOWN_TASK, // "Invalid destination queue or no external send function registered"); } } }
int waitup(int echildok, int *retstatus) { Envy *e; int pid; int slot; Symtab *s; Word *w; Job *j; char buf[ERRLEN]; Bufblock *bp; int uarg = 0; int done; Node *n; Process *p; extern int runerrs; /* first check against the proces slist */ if(retstatus) for(p = phead; p; p = p->f) if(p->pid == *retstatus){ *retstatus = p->status; pdelete(p); return(-1); } again: /* rogue processes */ pid = waitfor(buf); if(pid == -1){ if(echildok > 0) return(1); else { fprintf(stderr, "mk: (waitup %d) ", echildok); perror("mk wait"); Exit(); } } if(DEBUG(D_EXEC)) printf("waitup got pid=%d, status='%s'\n", pid, buf); if(retstatus && pid == *retstatus){ *retstatus = buf[0]? 1:0; return(-1); } slot = pidslot(pid); if(slot < 0){ if(DEBUG(D_EXEC)) fprintf(stderr, "mk: wait returned unexpected process %d\n", pid); pnew(pid, buf[0]? 1:0); goto again; } j = events[slot].job; usage(); nrunning--; events[slot].pid = -1; if(buf[0]){ e = buildenv(j, slot); bp = newbuf(); shprint(j->r->recipe, e, bp); front(bp->start); fprintf(stderr, "mk: %s: exit status=%s", bp->start, buf); freebuf(bp); for(n = j->n, done = 0; n; n = n->next) if(n->flags&DELETE){ if(done++ == 0) fprintf(stderr, ", deleting"); fprintf(stderr, " '%s'", n->name); delete(n->name); } fprintf(stderr, "\n"); if(kflag){ runerrs++; uarg = 1; } else { jobs = 0; Exit(); } } for(w = j->t; w; w = w->next){ if((s = symlook(w->s, S_NODE, 0)) == 0) continue; /* not interested in this node */ update(uarg, (Node *)s->value); } if(nrunning < nproclimit) sched(); return(0); }
Animation AnimationBuilder::spawnJobs(std::string &err, int maxTime){ FractalLogger::getSingleton()->write(id, "Fractal Is Animated: Note Detailed progress not reported.\n"); FractalLogger::getSingleton()->write(id, "Building Animation Data...\n"); unsigned long genStart = time(NULL); Animation anim; anim.baseID = id; anim.timeStarted = genStart; if(maxTime > 0){ anim.timeMustStop = time(NULL) + maxTime; }else{ anim.timeMustStop = 0; } if(!p->getJson().isMember("anim") || !p->getJson()["anim"].isObject()){ err += "No JSON Object Anim\n"; return anim; } Json::Value animData = p->getJson()["anim"]; p->getJson()["anim"] = Json::ValueType::nullValue; p->getJson()["basic"]["anim"]["selected"] = "no"; if(!animData.isMember("frames") || !animData["frames"].isInt()){ err += "anim.frames does not exist or non-int\n"; return anim; } if(animData["frames"].asInt() < 1){ err += "anim.frames out of bounds\n"; return anim; } anim.frames = animData["frames"].asInt(); if(!animData.isMember("fps") || !animData["fps"].isInt()){ err += "anim.fps does not exist or non-int\n"; return anim; } if(animData["fps"].asInt() < 1){ err += "anim.fps out of bounds\n"; return anim; } anim.fps = animData["fps"].asInt(); if(!animData.isMember("keyframes") || !animData["keyframes"].isArray()){ err += "anim.keyframes does not exist or non-array\n"; return anim; } if(!SchemaManager::getSingleton()->validateAnimationParam(animData["keyframes"], anim.frames, err)){ err += "Keyframe Validation Reported Error(s)!\n"; return anim; } // first job will render frame one -- we need to render all others ParamsFile pnew(p->getJson().toStyledString(), false); // copy json data to interpolate buildAnimatedParams(animData, &pnew); for(int i=2; i<=anim.frames; i++){ pnew.getJson()["internal"]["thisframe"] = i; std::string savepath = DirectoryManager::getSingleton()->getRootDirectory()+"renders/"; savepath = concat(savepath, anim.baseID) + concat(".frame.", i) + ".job"; interpolateFrame(pnew, i); pnew.saveToFile(savepath); anim.frameQueue.push_back(savepath); } p->getJson()["internal"]["thisframe"] = 1; p->getJson()["anim"] = animData; p->getJson()["basic"]["anim"]["selected"] = "yes"; // restore it :D // finally revalidate the parameters in case we messed up err += SchemaManager::getSingleton()->validateParamaters(p->getJson()); if(err == ""){ genStart = time(NULL) - genStart; FractalLogger::getSingleton()->write(id, concat("Animation Data Built: Took ", (float)genStart/1000)+" seconds!\n"); } return anim; }
void ML_multi_QuasiNewton::dfpmin(v_ratep_type& p, const double gtol, int& iter, double& fret, ptr_eval_func func, ptr_eval_gradient_func dfunc // double func(const v_ratep_type& p), // void dfunc(const v_ratep_type& in, // v_ratep_type& out) ) { // from Press et al 2002 const int ITMAX = 200; const double EPS=std::numeric_limits<double>::epsilon(); const double TOLX = 4.0*EPS, STPMX = 100.0; bool check; int i, its, j; double den, fac, fad, fae, fp, stpmax, sum=0.0, sumdg, sumxi, temp, test; int n = p.size(); v_ratep_type dg(n), g(n), hdg(n), pnew(n), xi(n); std::vector<v_ratep_type> hessin; hessin.resize(n); for (int i = 0; i < n; ++i) hessin[i].resize(n); fp = (this->*func)(p); // fp = func(p); (this->*dfunc)(p, g); // dfunc(p, g); for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) hessin[i][j] = 0.0; hessin[i][i] = 1.0; xi[i] = -g[i]; sum += p[i]*p[i]; } stpmax = STPMX * MAX(std::sqrt(sum), double(n)); for (its = 0; its < ITMAX; ++its) { iter = its; lnsrch(p, fp, g, xi, pnew, fret, stpmax, check, func); fp = fret; for (i = 0; i < n; ++i) { xi[i] = pnew[i] - p[i]; p[i] = pnew[i]; } test = 0.0; for (i = 0; i < n; ++i) { temp = std::abs(xi[i]) / MAX(std::abs(p[i]), 1.0); if (temp > test) test = temp; } if (test < TOLX) return; for (i = 0; i < n; ++i) dg[i] = g[i]; (this->*dfunc)(p, g); // dfunc(p, g); test = 0.0; den = MAX(fret, 1.0); for (i = 0; i < n; ++i) { temp = std::abs(g[i])*MAX(std::abs(p[i]), 1.0)/den; if (temp > test) test = temp; } if (test < gtol) return; for (i = 0; i < n; ++i) dg[i] = g[i] - dg[i]; for (i = 0; i < n; ++i) { hdg[i] = 0.0; for (j = 0; j < n; ++j) hdg[i] += hessin[i][j]*dg[j]; } fac = fae = sumdg = sumxi = 0.0; for (i = 0; i < n; ++i) { fac += dg[i]*xi[i]; fae += dg[i]*hdg[i]; sumdg += SQR(dg[i]); sumxi += SQR(xi[i]); } if (fac > std::sqrt(EPS*sumdg*sumxi)) { fac = 1.0 / fac; fad = 1.0 / fae; for (i = 0; i < n; ++i) dg[i] = fac*xi[i] - fad*hdg[i]; for (i = 0; i < n; ++i) { for (j = i; j < n; ++j) { hessin[i][j] += fac*xi[i]*xi[j] - fad*hdg[i]*hdg[j] + fae*dg[i]*dg[j]; hessin[j][i] = hessin[i][j]; } } } for (i = 0; i < n; ++i) { xi[i] = 0.0; for (j = 0; j < n; ++j) xi[i] -= hessin[i][j]*g[j]; } } std::cerr << "dfpmin(): too many iterations" << std::endl; assert(false); }