コード例 #1
0
ファイル: sthread.c プロジェクト: arcticmatt/CS24
/*
 * The scheduler is called with the context of the current thread,
 * or NULL when the scheduler is first started.
 *
 * The general operation of this function is:
 *   1.  Save the context argument into the current thread.
 *   2.  Either queue up or deallocate the current thread,
 *       based on its state.
 *   3.  Select a new "ready" thread to run, and set the "current"
 *       variable to that thread.
 *        - If no "ready" thread is available, examine the system
 *          state to handle this situation properly.
 *   4.  Return the context of the thread to run, so that a context-
 *       switch will be performed to start running the next thread.
 *
 * This function is global because it needs to be called from the assembly.
 */
ThreadContext *__sthread_scheduler(ThreadContext *context) {
    // Check if we actually have a context to work with
    if (context != NULL) {
        // 1. Save the context argument into the current thread
        current->context = context;
        // 2. Either queue up or deallocate the current thread, based on its state
        switch (current->state) {
            case ThreadFinished:
                // Delete the thread
                __sthread_delete(current);
                break;
            case ThreadRunning:
                // Change state of thread, and queue it
                current->state = ThreadReady;
                queue_add(current);
                break;
            case ThreadBlocked:
                // Queue thread
                queue_add(current);
                break;
            case ThreadReady:
                // Should not be switching from a ready thread
                printf("ERROR: Switching from a ready thread\n");
                assert(0);
                break;
        }
    }

    // 3. Select a new "ready" thread to run, and set the "current" variable
    // to that thread. If there are no ready threads and there are no blocked
    // threads, all threads in the program have successfully completed. However,
    // if there are one more more blocked threads in the blocked queue, the
    // program has become deadblocked.
    current = queue_take(&ready_queue);
    if (current == NULL && queue_empty(&blocked_queue)) {
        printf("All threads in the program have successfully completed, exiting\n");
        exit(0);
    } else if (current == NULL && !queue_empty(&blocked_queue)) {
        printf("Program has become deadlocked, exiting\n");
        exit(1);
    }
    current->state = ThreadRunning;

    // 4. Return the next thread to resume executing.
    return current->context;
}
コード例 #2
0
ファイル: sthread.c プロジェクト: mishraritvik/personal
/*
 * The scheduler is called with the context of the current thread,
 * or NULL when the scheduler is first started.
 *
 * The general operation of this function is:
 *   1.  Save the context argument into the current thread.
 *   2.  Either queue up or deallocate the current thread,
 *       based on its state.
 *   3.  Select a new "ready" thread to run, and set the "current"
 *       variable to that thread.
 *        - If no "ready" thread is available, examine the system
 *          state to handle this situation properly.
 *   4.  Return the context of the thread to run, so that a context-
 *       switch will be performed to start running the next thread.
 *
 * This function is global because it needs to be called from the assembly.
 */
ThreadContext *__sthread_scheduler(ThreadContext *context) {
    if (context != NULL) {
        /* Save the context argument into the current thread. */
        current->context = context;
        /* Either queue up or deallocate current thread, based on its state. */
        if (current->state == ThreadFinished) {
            /* Deallocatate because finished. */
            __sthread_delete(current);
        }
        else if (current->state == ThreadBlocked) {
            /* Queue up because blocked. */
            queue_add(current);
        }
        else if (current->state == ThreadRunning) {
            /* Queue up because yielding and make it ready. */
            current->state = ThreadReady;
            queue_add(current);
        }
    }

    if (queue_empty(&ready_queue)) {
        if (queue_empty(&blocked_queue)) {
            /* Nothing ready and nothing blocked, so done! */
            printf("Done.\n");
            exit(0);
        }
        else {
            /* Nothing ready but still blocked threads, so deadlock. */
            printf("Deadlock.\n");
            /* Exit with error. */
            exit(1);
        }
    }
    else {
        /* Select a new "ready" thread to run, and set the "current" variable to
         * that thread. */
        current = queue_take(&ready_queue);
        current->state = ThreadRunning;
    }

    return current->context;
}
コード例 #3
0
ファイル: sthread.c プロジェクト: ayraei/CS24
/*
 * The scheduler is called with the context of the current thread,
 * or NULL when the scheduler is first started.
 *
 * The general operation of this function is:
 *   1.  Save the context argument into the current thread.
 *   2.  Either queue up or deallocate the current thread,
 *       based on its state.
 *   3.  Select a new "ready" thread to run, and set the "current"
 *       variable to that thread.
 *        - If no "ready" thread is available, examine the system
 *          state to handle this situation properly.
 *   4.  Return the context of the thread to run, so that a context-
 *       switch will be performed to start running the next thread.
 *
 * This function is global because it needs to be called from the assembly.
 */
ThreadContext *__sthread_scheduler(ThreadContext *context) {

    /* Add the current thread to the ready queue */
    if (context != NULL) {
        assert(current != NULL);

        if (current->state == ThreadRunning)
            current->state = ThreadReady;

        if (current->state != ThreadFinished) {
            current->context = context;
            queue_add(current);
        }
        else {
            __sthread_delete(current);
        }
    }

    /*
     * Choose a new process from the ready queue.
     * Abort if the queue is empty.
     */
    current = queue_take(&ready_queue);
    if (current == NULL) {
        if (queue_empty(&blocked_queue)) {
            fprintf(stderr, "All threads completed, exiting.\n");
            exit(0);
        }
        else {
            fprintf(stderr, "The system is deadlocked!\n");
            exit(1);
        }
    }

    current->state = ThreadRunning;

    /* Return the next thread to resume executing. */
    return current->context;
}
コード例 #4
0
ファイル: sthread.c プロジェクト: ayraei/CS24
/*
 * The scheduler is called with the context of the current thread,
 * or NULL when the scheduler is first started.
 *
 * The general operation of this function is:
 *   1.  Save the context argument into the current thread.
 *   2.  Either queue up or deallocate the current thread,
 *       based on its state.
 *   3.  Select a new "ready" thread to run, and set the "current"
 *       variable to that thread.
 *        - If no "ready" thread is available, examine the system
 *          state to handle this situation properly.
 *   4.  Return the context of the thread to run, so that a context-
 *       switch will be performed to start running the next thread.
 *
 * This function is global because it needs to be called from the assembly.
 */
ThreadContext *__sthread_scheduler(ThreadContext *context) {
    /* If this is not the first call to scheduler (= no current thread),
     * 1. Save the context argument into the current thread.
     */
    if (context != NULL) {
        current->context = context;

        /* 2. Queue up or deallocate the current thread. */
        if (current->state == ThreadRunning) {
            current->state = ThreadReady;
            queue_add(current);
        }
        else if (current->state == ThreadBlocked) {
            queue_add(current);
        }
        else if (current->state == ThreadFinished) {
            __sthread_delete(current);
        }
    }
    
    /* 3. Select a new 'ready' thread to run. */
    current = queue_take(&ready_queue);
    
    /* No Ready threads. */
    if (current == NULL && queue_take(&blocked_queue) == NULL) {
        fprintf(stderr, "All threads finished successfully.\n");
        exit(0);
    }
    else if (current == NULL) {
        fprintf(stderr, "Program deadlocked!\n");
        exit(1);
    }
    
    current->state = ThreadRunning;

    /* 4. Return the next thread to resume executing. */
    return current->context;
}