Example #1
0
/*
 * Exit the current thread.
 * Calling this function initiates a context switch.
 */
void Exit(int exitCode)
{
    struct Kernel_Thread* current = g_currentThread;

    if (Interrupts_Enabled())
	Disable_Interrupts();

    /* Thread is dead */
    current->exitCode = exitCode;
    current->alive = false;

    /* Clean up any thread-local memory */
    Tlocal_Exit(g_currentThread);

    /* Notify the thread's owner, if any */
    Wake_Up(&current->joinQueue);

    /* Remove the thread's implicit reference to itself. */
    Detach_Thread(g_currentThread);

    /*
     * Schedule a new thread.
     * Since the old thread wasn't placed on any
     * thread queue, it won't get scheduled again.
     */
    Schedule();

    /* Shouldn't get here */
    KASSERT(false);
}
Example #2
0
/*
 * Wake up all threads waiting on the given condition.
 * The mutex guarding the condition should be held!
 */
void Cond_Broadcast(struct Condition* cond)
{
    KASSERT(Interrupts_Enabled());
    Disable_Interrupts();  /* prevent scheduling */
    Wake_Up(&cond->waitQueue);
    Enable_Interrupts();  /* resume scheduling */
}
Example #3
0
int Destroy_Semaphore(int sid)
{
    if (!validateSID(sid)) {
        return EINVALID;
    }

    bool atomic = Begin_Int_Atomic();
    KASSERT(0 < g_Semaphores[sid].references);
    g_Semaphores[sid].references--;
    Clear_Bit(g_currentThread->semaphores, sid);

    if (g_Semaphores[sid].references == 0) {
        g_Semaphores[sid].available = true; /* mark it available */
        Wake_Up(&g_Semaphores[sid].waitingThreads); /* wake all threads */
    }

    End_Int_Atomic(atomic);
    return 0;
}
Example #4
0
/*
 * Handler for keyboard interrupts.
 */
static void Keyboard_Interrupt_Handler(struct Interrupt_State* state)
{
    uchar_t status, scanCode;
    unsigned flag = 0;
    bool release = false, shift;
    Keycode keycode;

    Begin_IRQ(state);

    status = In_Byte(KB_CMD);
    IO_Delay();

    if ((status & KB_OUTPUT_FULL) != 0) {
	/* There is a byte available */
	scanCode = In_Byte(KB_DATA);
	IO_Delay();
/*
 *	Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : "");
 */

	if (scanCode & KB_KEY_RELEASE) {
	    release = true;
	    scanCode &= ~(KB_KEY_RELEASE);
	}

	if (scanCode >= SCAN_TABLE_SIZE) {
	    Print("Unknown scan code: %x\n", scanCode);
	    goto done;
	}

	/* Process the key */
	shift = ((s_shiftState & SHIFT_MASK) != 0);
	keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode];

	/* Update shift, control and alt state */
	switch (keycode) {
	case KEY_LSHIFT:
	    flag = LEFT_SHIFT;
	    break;
	case KEY_RSHIFT:
	    flag = RIGHT_SHIFT;
	    break;
	case KEY_LCTRL:
	    flag = LEFT_CTRL;
	    break;
	case KEY_RCTRL:
	    flag = RIGHT_CTRL;
	    break;
	case KEY_LALT:
	    flag = LEFT_ALT;
	    break;
	case KEY_RALT:
	    flag = RIGHT_ALT;
	    break;
	default:
	    goto noflagchange;
	}

	if (release)
	    s_shiftState &= ~(flag);
	else
	    s_shiftState |= flag;
			
	/*
	 * Shift, control and alt keys don't have to be
	 * queued, flags will be set!
	 */
	goto done;

noflagchange:
	/* Format the new keycode */
	if (shift)
	    keycode |= KEY_SHIFT_FLAG;
	if ((s_shiftState & CTRL_MASK) != 0)
	    keycode |= KEY_CTRL_FLAG;
	if ((s_shiftState & ALT_MASK) != 0)
	    keycode |= KEY_ALT_FLAG;
	if (release)
	    keycode |= KEY_RELEASE_FLAG;
		
	/* Put the keycode in the buffer */
	Enqueue_Keycode(keycode);

	/* Wake up event consumers */
	Wake_Up(&s_waitQueue);

	/*
	 * Pick a new thread upon return from interrupt
	 * (hopefully the one waiting for the keyboard event)
	 */
	g_needReschedule = true;
    }

done:
    End_IRQ(state);
}
Example #5
0
/*
 * Hand given thread to the reaper for destruction.
 * Must be called with interrupts disabled!
 */
static void Reap_Thread(struct Kernel_Thread* kthread)
{
    KASSERT(!Interrupts_Enabled());
    Enqueue_Thread(&s_graveyardQueue, kthread);
    Wake_Up(&s_reaperWaitQueue);
}
Example #6
0
/*
 * Wake up any threads in the floppy wait queue.
 */
static void Floppy_Interrupt_Handler(struct Interrupt_State* state)
{
    Begin_IRQ(state);
    Wake_Up(&s_floppyInterruptWaitQueue);
    End_IRQ(state);
}