/* * task_begin() * * Overview * A process constructing a new task calls task_begin() to initialize the * task, by attaching itself as a member. * * Return values * None. * * Caller's context * pidlock and p_lock must be held across the call to task_begin(). */ void task_begin(task_t *tk, proc_t *p) { timestruc_t ts; task_usage_t *tu; rctl_entity_p_t e; ASSERT(MUTEX_HELD(&pidlock)); ASSERT(MUTEX_HELD(&p->p_lock)); mutex_enter(&tk->tk_usage_lock); tu = tk->tk_usage; gethrestime(&ts); tu->tu_startsec = (uint64_t)ts.tv_sec; tu->tu_startnsec = (uint64_t)ts.tv_nsec; mutex_exit(&tk->tk_usage_lock); /* * Join process to the task as a member. */ task_attach(tk, p); /* * Now that the linkage from process to task is complete, do the * required callback for the task rctl set. */ e.rcep_p.task = tk; e.rcep_t = RCENTITY_TASK; (void) rctl_set_dup(NULL, NULL, p, &e, tk->tk_rctls, NULL, RCD_CALLBACK); }
static struct snobj *handle_attach_task(struct snobj *q) { const char *m_name; const char *tc_name; task_id_t tid; struct module *m; struct task *t; m_name = snobj_eval_str(q, "name"); if (!m_name) return snobj_err(EINVAL, "Missing 'name' field"); if ((m = find_module(m_name)) == NULL) return snobj_err(ENOENT, "No module '%s' found", m_name); tid = snobj_eval_uint(q, "taskid"); if (tid >= MAX_TASKS_PER_MODULE) return snobj_err(EINVAL, "'taskid' must be between 0 and %d", MAX_TASKS_PER_MODULE - 1); if ((t = m->tasks[tid]) == NULL) return snobj_err(ENOENT, "Task %s:%hu does not exist", m_name, tid); tc_name = snobj_eval_str(q, "tc"); if (tc_name) { struct tc *c; c = ns_lookup(NS_TYPE_TC, tc_name); if (!c) return snobj_err(ENOENT, "No TC '%s' found", tc_name); task_attach(t, c); } else { int wid; /* TODO: worker_id_t */ if (task_is_attached(t)) return snobj_err(EBUSY, "Task %s:%hu is already " "attached to a TC", m_name, tid); wid = snobj_eval_uint(q, "wid"); if (wid >= MAX_WORKERS) return snobj_err(EINVAL, "'wid' must be between 0 and %d", MAX_WORKERS - 1); if (!is_worker_active(wid)) return snobj_err(EINVAL, "Worker %d does not exist", wid); assign_default_tc(wid, t); } return NULL; }