void sched_add(thread_t *td) { // log("Add '%s' {%p} thread to scheduler", td->td_name, td); if (td == PCPU_GET(idle_thread)) return; td->td_state = TDS_READY; td->td_slice = SLICE; cs_enter(); runq_add(&runq, td); if (td->td_prio > thread_self()->td_prio) thread_self()->td_flags |= TDF_NEEDSWITCH; cs_leave(); }
/* * Capture the information passed and add it to the job list. * Arranges for the low level work to be handled by the runq and meth classes. * Returns a reference of 0 or greater to the work record inserted * in the job table, which can be used with job_rm(). Otherwise returns -1 * if there was a failure or -2 if successfully completed the job without * the need of a job entry. * * Job_tab follows an insertion order only. The runq and meth classes * should be initialised before this is called. Additionally, the requested * methods should be present in the meth class before hand. If a runtime * loadable method is to be used, use meth_load() before calling the add. * * All strings are copied by this routine, the caller does not have to * keep them allocated. */ int job_add(long start, /* time job should start following * job_init() (may be negative) */ long interval, /* time in between jobs (seconds); if 0 ?? */ long phase, /* execution order at each time point */ long count, /* number of times to run job or 0 to * repeat indefinately */ char *key, /* job identification string */ char *origin, /* origin of job */ char *result, /* route for results (p-url spec) */ char *error, /* route for errors (p-url spec) */ int keep, /* keep most recent number of datum */ char *method, /* String representation of method */ char *command /* Command for method */ ) { struct job_work *work; int r, klen, clen, rlen, elen; METHID meth; struct meth_invoke *runarg; char *mem; /* The job class does its stuff by calling meth_run() at times * set up in runq. In this method we create the arguments to * meth and submit the work to runq, using meth_run() as the * callback. */ /* Obtain the method id to use in the method_run callback */ if (method == NULL || *method == '\0') { elog_printf(ERROR, "no method in job %s", key); return -1; } meth = meth_lookup(method); if (meth == NULL) { elog_printf(ERROR, "unknown method %s in job %s", method, key); return -1; } /* Compose an argument buffer for meth_add() using struct meth_invoke */ klen = strlen(key); clen = strlen(command); rlen = strlen(result); elen = strlen(error); runarg = xnmalloc(sizeof(struct meth_invoke) + klen + clen + rlen + elen +4); mem = ((char *) runarg) + sizeof(struct meth_invoke); runarg->key = strcpy(mem, key); runarg->run = meth; mem += klen + 1; runarg->command = strcpy(mem, command); mem += clen + 1; runarg->res_purl = strcpy(mem, result); mem += rlen + 1; runarg->err_purl = strcpy(mem, error); runarg->keep = keep; /* Debug the call */ elog_printf(DEBUG, "job added: %d %d %d %d %s %s %s %s %d %8s %s", start, interval, phase, count, key, origin, result, error, keep, method, command); /* Add the work */ r = runq_add(job_start_t+start, interval, phase, count, key, meth_startrun_s, meth_execute_s, meth_isrunning_s, meth_endrun_s, runarg, sizeof(struct meth_invoke)); if (r == -1 || r == -2) { if (r == -1) { elog_printf(ERROR, "bad parameter in job %s", key); return -1; } else return -2; } /* Save the information for ourselves */ work = xnmalloc(sizeof(struct job_work)); work->origin = xnstrdup(origin); work->runarg = runarg; work->runq = r; r = itree_append(job_tab, work); return r; }