Пример #1
0
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;
}
Пример #2
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;
}