int Thread::abort() { /* * This function can get a thread from anywhere in the system, rip it * out from its current state and runs it. The idea is that the thread * knows what to do when it wakes up. */ int unblocked = 0; //kinfo("Unblocking thread %d %d st=%d\n", get_pid(), get_id(), state); while (!unblocked) { switch (m_state) { case THR_ST_READY: case THR_ST_RUNNING: unblocked = 1; break; case THR_ST_SENDING: case THR_ST_RECEIVING: kinfo("Queued on %p\n", proc_queue); // if (proc_queue) // { // rwlock_wrlock(&proc_queue->msg_queue_lock); // if (state == THR_ST_SENDING) // { // proc_queue->smsg_queue.rem_item(this); // } // else if (state == THR_ST_RECEIVING) // { // proc_queue->rmsg_queue.rem_item(this); // } // proc_queue = NULL; // unref(); // rwlock_unlock(&proc_queue->msg_queue_lock); // } sys.m_sched.add(this, 1); break; case THR_ST_NANOSLEEP: if (timerqueue_remove(thread_timer)) { sys.m_sched.add(this, 1); } break; case THR_ST_STOPPED: sys.m_sched.add(this, 1); break; case THR_ST_WAITING: get_proc()->wait_list.rem_item(this); break; case THR_ST_ZOMBIE: //die(); unblocked = 1; break; case THR_ST_DEAD: case THR_ST_FUTEX: case THR_ST_JOINING: default: kinfo("UNHANDLED STATE %d\n", m_state); break; } } return 0; }
int Syscall::kcall_clocknanosleep(CoreData& core_data, Thread *currt) { /* * Sleep on a clock * * KPARM1 : clock id * KPARM2 : flags * KPARM3 : ticks * KPARM4 : ptr to remaining ticks * * return : 0 or -ERRNO */ Timer *t; uint64_t expire_time; int absolute; /* * Posix tells us to treat absolute and relative timers differently when * a clock's time is changed. This means generally that the timer code that * queues/deletes/expires/handles timers needs to know whether they are * absolute or not. * * So we'll just pass the requested time and the TIMER_ABSTIME flag * through to the timer_queue funtions. */ absolute = KPARM2 & TIMER_ABSTIME ? 1 : 0; /* Work out when the timer should expire */ switch (KPARM1) { case CLOCK_REALTIME: if (absolute) { expire_time = KPARM3; } else { /* Use the mono clock so that time changes don't affect us */ expire_time = sys.clock_getmono() + KPARM3; } break; case CLOCK_MONOTONIC: if (absolute) { expire_time = KPARM3; } else { expire_time = sys.clock_getmono() + KPARM3; } break; default: /* We don't support others yet */ return -EINVAL; } /* * Now find the timer, we don't need locking 'cos no-one else will * be touching our timer */ if (currt->thread_timer == NULL) { currt->thread_timer = (Timer *)kmalloc(sizeof(Timer)); memset(currt->thread_timer, 0, sizeof(Timer)); } if ((t = currt->thread_timer) == NULL) { return -EAGAIN; } sys.m_sched.block(THR_ST_NANOSLEEP); timerqueue_remove(t); t->expire_time = expire_time; t->interval = 0; t->callback = unblock_func; t->arg = currt; timerqueue_insert(t); return 0; }