void isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) { isc_boolean_t idle1, idle2; isc_task_t *task; /* * Send '*event' to '*taskp' and then detach '*taskp' from its * task. */ REQUIRE(taskp != NULL); task = *taskp; REQUIRE(VALID_TASK(task)); XTRACE("isc_task_sendanddetach"); LOCK(&task->lock); idle1 = task_send(task, eventp); idle2 = task_detach(task); UNLOCK(&task->lock); /* * If idle1, then idle2 shouldn't be true as well since we're holding * the task lock, and thus the task cannot switch from ready back to * idle. */ INSIST(!(idle1 && idle2)); if (idle1 || idle2) task_ready(task); *taskp = NULL; }
void* consoleDaemon(void* unused) { // Detach and register daemon with shutdown path. task_detach(); INITSERVICE::registerShutdownEvent(g_msgq, SYNC, INITSERVICE::CONSOLE_PRIORITY); // Create a default output UART device if there isn't already one. // - Some devices are registered via the CONSOLE_UART_DEFINE_DEVICE // macro and therefore don't need this. if (NULL == Uart::g_device) { Uart::g_device = new Uart(); Uart::g_device->initialize(); } while(1) { msg_t* msg = msg_wait(g_msgq); switch (msg->type) { case DISPLAY: { if (NULL != msg->extra_data) { char timestamp[11]; sprintf(timestamp, "%3d.%05d|", msg->data[0], // 5 Digits worth of ns. (msg->data[1]*100000)/NS_PER_SEC); _display(timestamp); _display( static_cast<const char*>(msg->extra_data)); free(msg->extra_data); } msg_free(msg); break; } case SYNC: { msg_respond(g_msgq, msg); break; } } } return NULL; }
//@todo: RTC 119832 void IpmiSEL::execute(void) { //Mark as an independent daemon so if it crashes we terminate. task_detach(); // Register shutdown events with init service. // Done at the "end" of shutdown processesing. // This will flush out any IPMI messages which were sent as // part of the shutdown processing. We chose MBOX priority // as we don't want to accidentally get this message after // interrupt processing has stopped in case we need intr to // finish flushing the pipe. INITSERVICE::registerShutdownEvent(iv_msgQ, IPMISEL::MSG_STATE_SHUTDOWN, INITSERVICE::MBOX_PRIORITY); barrier_wait(&iv_sync_start); while(true) { msg_t* msg = msg_wait(iv_msgQ); const IPMISEL::msg_type msg_type = static_cast<IPMISEL::msg_type>(msg->type); // Invert the "default" by checking here. This allows the compiler // to warn us if the enum has an unhadled case but still catch // runtime errors where msg_type is set out of bounds. assert(msg_type <= IPMISEL::MSG_LAST_TYPE, "msg_type %d not handled", msg_type); switch(msg_type) { case IPMISEL::MSG_SEND_ESEL: IPMISEL::process_esel(msg); //done with msg msg_free(msg); break; case IPMISEL::MSG_STATE_SHUTDOWN: IPMI_TRAC(INFO_MRK "ipmisel shutdown event"); //Respond that we are done shutting down. msg_respond(iv_msgQ, msg); break; } } // while(1) IPMI_TRAC(EXIT_MRK "message loop"); return; } // execute
void isc_task_detach(isc_task_t **taskp) { isc_task_t *task; isc_boolean_t was_idle; /* * Detach *taskp from its task. */ REQUIRE(taskp != NULL); task = *taskp; REQUIRE(VALID_TASK(task)); XTRACE("isc_task_detach"); LOCK(&task->lock); was_idle = task_detach(task); UNLOCK(&task->lock); if (was_idle) task_ready(task); *taskp = NULL; }
/* * task_change(task_t *, proc_t *) * * Overview * task_change() removes the specified process from its current task. The * process is then attached to the specified task. This routine is called * from settaskid() when process is being moved to a new task. * * Return values * None. * * Caller's context * pidlock and p_lock held across task_change() */ void task_change(task_t *newtk, proc_t *p) { task_t *oldtk = p->p_task; ASSERT(MUTEX_HELD(&pidlock)); ASSERT(MUTEX_HELD(&p->p_lock)); ASSERT(oldtk != NULL); ASSERT(oldtk->tk_memb_list != NULL); mutex_enter(&oldtk->tk_zone->zone_nlwps_lock); oldtk->tk_nlwps -= p->p_lwpcnt; oldtk->tk_nprocs--; mutex_exit(&oldtk->tk_zone->zone_nlwps_lock); mutex_enter(&newtk->tk_zone->zone_nlwps_lock); newtk->tk_nlwps += p->p_lwpcnt; newtk->tk_nprocs++; mutex_exit(&newtk->tk_zone->zone_nlwps_lock); task_detach(p); task_begin(newtk, p); exacct_move_mstate(p, oldtk, newtk); }
bool task_abort(Task *task) { bool success = task_cancel(task); task_detach(task); return success; }
bool task_finish(Task *task, void **result) { bool success = task_wait(task, result); task_detach(task); return success; }
/* * Remove zombie children from the process table. */ void freeproc(proc_t *p) { proc_t *q; task_t *tk; ASSERT(p->p_stat == SZOMB); ASSERT(p->p_tlist == NULL); ASSERT(MUTEX_HELD(&pidlock)); sigdelq(p, NULL, 0); if (p->p_killsqp) { siginfofree(p->p_killsqp); p->p_killsqp = NULL; } prfree(p); /* inform /proc */ /* * Don't free the init processes. * Other dying processes will access it. */ if (p == proc_init) return; /* * We wait until now to free the cred structure because a * zombie process's credentials may be examined by /proc. * No cred locking needed because there are no threads at this point. */ upcount_dec(crgetruid(p->p_cred), crgetzoneid(p->p_cred)); crfree(p->p_cred); if (p->p_corefile != NULL) { corectl_path_rele(p->p_corefile); p->p_corefile = NULL; } if (p->p_content != NULL) { corectl_content_rele(p->p_content); p->p_content = NULL; } if (p->p_nextofkin && !((p->p_nextofkin->p_flag & SNOWAIT) || (PTOU(p->p_nextofkin)->u_signal[SIGCLD - 1] == SIG_IGN))) { /* * This should still do the right thing since p_utime/stime * get set to the correct value on process exit, so it * should get properly updated */ p->p_nextofkin->p_cutime += p->p_utime; p->p_nextofkin->p_cstime += p->p_stime; p->p_nextofkin->p_cacct[LMS_USER] += p->p_acct[LMS_USER]; p->p_nextofkin->p_cacct[LMS_SYSTEM] += p->p_acct[LMS_SYSTEM]; p->p_nextofkin->p_cacct[LMS_TRAP] += p->p_acct[LMS_TRAP]; p->p_nextofkin->p_cacct[LMS_TFAULT] += p->p_acct[LMS_TFAULT]; p->p_nextofkin->p_cacct[LMS_DFAULT] += p->p_acct[LMS_DFAULT]; p->p_nextofkin->p_cacct[LMS_KFAULT] += p->p_acct[LMS_KFAULT]; p->p_nextofkin->p_cacct[LMS_USER_LOCK] += p->p_acct[LMS_USER_LOCK]; p->p_nextofkin->p_cacct[LMS_SLEEP] += p->p_acct[LMS_SLEEP]; p->p_nextofkin->p_cacct[LMS_WAIT_CPU] += p->p_acct[LMS_WAIT_CPU]; p->p_nextofkin->p_cacct[LMS_STOPPED] += p->p_acct[LMS_STOPPED]; p->p_nextofkin->p_cru.minflt += p->p_ru.minflt; p->p_nextofkin->p_cru.majflt += p->p_ru.majflt; p->p_nextofkin->p_cru.nswap += p->p_ru.nswap; p->p_nextofkin->p_cru.inblock += p->p_ru.inblock; p->p_nextofkin->p_cru.oublock += p->p_ru.oublock; p->p_nextofkin->p_cru.msgsnd += p->p_ru.msgsnd; p->p_nextofkin->p_cru.msgrcv += p->p_ru.msgrcv; p->p_nextofkin->p_cru.nsignals += p->p_ru.nsignals; p->p_nextofkin->p_cru.nvcsw += p->p_ru.nvcsw; p->p_nextofkin->p_cru.nivcsw += p->p_ru.nivcsw; p->p_nextofkin->p_cru.sysc += p->p_ru.sysc; p->p_nextofkin->p_cru.ioch += p->p_ru.ioch; } q = p->p_nextofkin; if (q && q->p_orphan == p) q->p_orphan = p->p_nextorph; else if (q) { for (q = q->p_orphan; q; q = q->p_nextorph) if (q->p_nextorph == p) break; ASSERT(q && q->p_nextorph == p); q->p_nextorph = p->p_nextorph; } /* * The process table slot is being freed, so it is now safe to give up * task and project membership. */ mutex_enter(&p->p_lock); tk = p->p_task; task_detach(p); mutex_exit(&p->p_lock); proc_detach(p); pid_exit(p, tk); /* frees pid and proc structure */ task_rele(tk); }