/********************************************************************************************************* ** Function name: mqueue_abort ** Descriptions: 终止等待消息队列 ** input parameters: mqueue 消息队列 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int mqueue_abort(mqueue_t *mqueue) { struct mqueue *q; task_t *task; reg_t reg; reg = interrupt_disable(); if (mqueue) { q = *mqueue; if (q && q->type == IPC_TYPE_MQUEUE && q->valid) { while ((task = q->w_wait_list) != NULL) { resume_task(task, q->w_wait_list, TASK_RESUME_INTERRUPT); } while ((task = q->r_wait_list) != NULL) { resume_task(task, q->r_wait_list, TASK_RESUME_INTERRUPT); } interrupt_resume(reg); return 0; } } interrupt_resume(reg); return -1; }
void apply(future<void> f) const { if (f.ready()) return; task_context* ctx = current_task_context::get(); if (!ctx) { f.wait(); return; } auto&& resume_task = [=]() { ctx->resume(); }; auto s = f.get_state(detail::use_private_interface); s->continue_with([&]() { s->await_queue()->push_front([=]() { resume_task(); }); }); ctx->yield(); }
/********************************************************************************************************* ** Function name: mqueue_flush ** Descriptions: 清空消息队列 ** input parameters: mqueue 消息队列 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int mqueue_flush(mqueue_t *mqueue) { struct mqueue *q; task_t *task; reg_t reg; int i; reg = interrupt_disable(); if (mqueue) { q = *mqueue; if (q && q->type == IPC_TYPE_MQUEUE && q->valid) { q->nr = 0; q->in = 0; q->out = 0; for (i = 0; ((task = q->w_wait_list) != NULL) && i < q->size; i++) { resume_task(task, q->w_wait_list, TASK_RESUME_MSG_OUT); } interrupt_resume(reg); return 0; } } interrupt_resume(reg); return -1; }
/********************************************************************************************************* ** Function name: mqueue_tryfetch ** Descriptions: 尝试从消息队列里取出消息 ** input parameters: mqueue 消息队列 ** output parameters: msg 消息 ** Returned value: 0 OR -1 *********************************************************************************************************/ int mqueue_tryfetch(mqueue_t *mqueue, void **msg) { struct mqueue *q; task_t *task; reg_t reg; reg = interrupt_disable(); if (mqueue) { q = *mqueue; if (q && q->type == IPC_TYPE_MQUEUE && q->valid) { if (q->nr) { *msg = q->msg[q->out]; q->out++; q->out %= q->size; q->nr--; task = q->w_wait_list; if (task) { resume_task(task, q->w_wait_list, TASK_RESUME_MSG_OUT); } interrupt_resume(reg); return 0; } } } interrupt_resume(reg); return -1; }
/********************************************************************************************************* ** Function name: mqueue_trypost ** Descriptions: 尝试投递消息到消息队列 ** input parameters: mqueue 消息队列 ** msg 消息 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int mqueue_trypost(mqueue_t *mqueue, void *msg) { struct mqueue *q; task_t *task; reg_t reg; reg = interrupt_disable(); if (mqueue) { q = *mqueue; if (q && q->type == IPC_TYPE_MQUEUE && q->valid) { if (q->nr < q->size) { q->msg[q->in] = msg; q->in++; q->in %= q->size; q->nr++; task = q->r_wait_list; if (task) { resume_task(task, q->r_wait_list, TASK_RESUME_MSG_COME); } interrupt_resume(reg); return 0; } } } interrupt_resume(reg); return -1; }
/********************************************************************************************************* ** Function name: mutex_unlock ** Descriptions: 对互斥量进行解锁 ** input parameters: mutex 互斥量 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int mutex_unlock(mutex_t *mutex) { struct mutex *m; task_t *task; reg_t reg; if (in_interrupt()) { return -1; } reg = interrupt_disable(); if (mutex) { m = *mutex; if (m && m->type == IPC_TYPE_MUTEX && m->valid) { if (m->lock) { if (m->owner == current) { m->lock--; if (!m->lock) { m->owner = NULL; task = m->wait_list; if (task) { printk(KERN_DEBUG"%s: %s unlock mutex, %s get it\n", __func__, current->name, task->name); resume_task(task, m->wait_list, TASK_RESUME_MUTEX_COME); } } interrupt_resume(reg); return 0; } } } } interrupt_resume(reg); return -1; }
/********************************************************************************************************* ** Function name: mqueue_fetch ** Descriptions: 从消息队列里取出消息 ** input parameters: mqueue 消息队列 ** timeout 超时 TICK 数 ** output parameters: msg 消息 ** Returned value: 0 OR -1 *********************************************************************************************************/ int mqueue_fetch(mqueue_t *mqueue, void **msg, tick_t timeout) { struct mqueue *q; task_t *task; reg_t reg; uint8_t resume_type; tick_t tick; if (in_interrupt()) { return mqueue_tryfetch(mqueue, msg); } reg = interrupt_disable(); if (mqueue) { again: q = *mqueue; if (q && q->type == IPC_TYPE_MQUEUE && q->valid) { if (q->nr) { *msg = q->msg[q->out]; q->out++; q->out %= q->size; q->nr--; task = q->w_wait_list; if (task) { resume_task(task, q->w_wait_list, TASK_RESUME_MSG_OUT); } interrupt_resume(reg); return 0; } else { if (timeout != 0) { wait_event_timeout(q->r_wait_list, resume_type, timeout, tick); } else { wait_event_forever(q->r_wait_list, resume_type); } if (resume_type == TASK_RESUME_INTERRUPT || resume_type == TASK_RESUME_TIMEOUT || resume_type == TASK_RESUME_UNKNOW) { goto error; } else { if (timeout != 0) { if (timeout <= tick) { goto error; } timeout -= tick; } goto again; } } } } error: interrupt_resume(reg); return -1; }
void schedule_exit() { curr_task->state = TSK_Exited; curr_task->time_slice = 0; task_context_t* stack = (task_context_t*)(curr_task->esp); int retval = stack->eax; terminal_writestring("Task exited "); terminal_writeuint32(retval); terminal_writestring("\n"); schedule(); curr_task = next_task; resume_task(); }
void schedule_kill() { curr_task->state = TSK_Terminated; terminal_writestring("Killed task: \n"); task_print(curr_task); schd_task_del(curr_task); schedule(); curr_task = next_task; terminal_writestring("Resuming\n"); bochs_break(); resume_task(); }
/********************************************************************************************************* ** Function name: sem_abort ** Descriptions: 终止等待信号量 ** input parameters: sem 信号量 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int sem_abort(sem_t *sem) { struct sem *s; task_t *task; reg_t reg; reg = interrupt_disable(); if (sem) { s = *sem; if (s && s->type == IPC_TYPE_SEM && s->valid) { while ((task = s->wait_list) != NULL) { resume_task(task, s->wait_list, TASK_RESUME_INTERRUPT); } interrupt_resume(reg); return 0; } } interrupt_resume(reg); return -1; }
/********************************************************************************************************* ** Function name: mutex_abort ** Descriptions: 终止等待互斥量 ** input parameters: mutex 互斥量 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int mutex_abort(mutex_t *mutex) { struct mutex *m; task_t *task; reg_t reg; reg = interrupt_disable(); if (mutex) { m = *mutex; if (m && m->type == IPC_TYPE_MUTEX && m->valid) { while ((task = m->wait_list) != NULL) { resume_task(task, m->wait_list, TASK_RESUME_INTERRUPT); } interrupt_resume(reg); return 0; } } interrupt_resume(reg); return -1; }
/********************************************************************************************************* ** Function name: sem_sync ** Descriptions: 如果有任务在等待, 则发送一个信号量 ** input parameters: sem 信号量 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int sem_sync(sem_t *sem) { struct sem *s; task_t *task; reg_t reg; reg = interrupt_disable(); if (sem) { s = *sem; if (s && s->type == IPC_TYPE_SEM && s->valid) { task = s->wait_list; if (task) { s->count++; resume_task(task, s->wait_list, TASK_RESUME_SEM_COME); } interrupt_resume(reg); return 0; } } interrupt_resume(reg); return -1; }
static void stdin_readable(int fd, void *data) { char buffer[1000]; int n; Var v; stdin_waiter *w; if (data != &waiters) panic("STDIN_READABLE: Bad data!"); if (!waiters) { errlog("STDIN_READABLE: Nobody cares!\n"); return; } n = read(0, buffer, sizeof(buffer)); buffer[n] = '\0'; while (n) if (buffer[--n] == '\n') buffer[n] = 'X'; if (buffer[0] == 'a') { v.type = TYPE_ERR; v.v.err = E_NACC; } else { v.type = TYPE_STR; v.v.str = str_dup(buffer); } resume_task(waiters->the_vm, v); w = waiters->next; myfree(waiters, M_TASK); waiters = w; if (!waiters) network_unregister_fd(0); }