Esempio n. 1
0
/*
 * Create a new raw thread object.
 * Returns a null pointer if there isn't enough memory.
 */
static struct Kernel_Thread* Create_Thread(int priority, bool detached)
{
    struct Kernel_Thread* kthread;
    void* stackPage = 0;

    /*
     * For now, just allocate one page each for the thread context
     * object and the thread's stack.
     */
    kthread = Alloc_Page();
    if (kthread != 0)
        stackPage = Alloc_Page();    

    /* Make sure that the memory allocations succeeded. */
    if (kthread == 0)
	return 0;
    if (stackPage == 0) {
	Free_Page(kthread);
	return 0;
    }

    /*Print("New thread @ %x, stack @ %x\n", kthread, stackPage); */

    /*
     * Initialize the stack pointer of the new thread
     * and accounting info
     */
    Init_Thread(kthread, stackPage, priority, detached);

    /* Add to the list of all threads in the system. */
    Add_To_Back_Of_All_Thread_List(&s_allThreadList, kthread);

    return kthread;
}
Esempio n. 2
0
l_Address sbrk(int size)
{
	l_Address sbrk_curbrk = Alloc_Page(0);
	if (size <= 0) return(Alloc_Page(0));
	
	long sbrk_size = 0;
	while (size > sbrk_size) {
	    if (Alloc_Page(1))
	    	sbrk_size += PageSize;
	    else
	    {
	    	errno = ENOMEM;
	    	return ((l_Address) -1);
	    }
	}
	errno = 0;
	return(sbrk_curbrk);
}
Esempio n. 3
0
/*
 * Initialize the floppy controller.
 */
void Init_Floppy(void)
{
    uchar_t floppyByte;
    bool ready = false;
    bool good;

    Print("Initializing floppy controller...\n");

    /* Allocate memory for DMA transfers */
    s_transferBuf = (uchar_t*) Alloc_Page();

    /* Use CMOS to get floppy configuration */
    Out_Byte(CMOS_OUT, CMOS_FLOPPY_INDEX);
    floppyByte = In_Byte(CMOS_IN);
    Setup_Drive_Parameters(0, (floppyByte >> 4) & 0xF);
    Setup_Drive_Parameters(1, floppyByte & 0xF);

    /* Install floppy interrupt handler */
    Install_IRQ(FDC_IRQ, &Floppy_Interrupt_Handler);
    Enable_IRQ(FDC_IRQ);

    /* Reset and calibrate the controller. */
    Disable_Interrupts();
    good = Reset_Controller();
    Enable_Interrupts();
    if (!good) {
	Print("  Failed to reset controller!\n");
	goto done;
    }

    /* Reserve DMA channel 2. */
    if (!Reserve_DMA(FDC_DMA)) {
	Print("  Failed to reserve DMA channel\n");
	goto done;
    }

    /*
     * Driver is now ready for requests.
     * Start the request processing thread.
     */
    ready = true;
    Start_Kernel_Thread(Floppy_Request_Thread, 0, PRIORITY_NORMAL, true);

done:
    if (!ready)
	Print("  Floppy controller initialization FAILED\n");
}
Esempio n. 4
0
/*
 * Get buffer for given block, and mark it in use.
 * Must be called with cache mutex held.
 */
static int Get_Buffer(struct FS_Buffer_Cache *cache, ulong_t fsBlockNum,
                      struct FS_Buffer **pBuf) {
    struct FS_Buffer *buf, *lru = 0;
    int rc;

    Debug("Request block %lu\n", fsBlockNum);

    KASSERT(IS_HELD(&cache->lock));

    /*
     * Look for existing buffer.
     * As a side-effect, finds the least recently used
     * buffer that is not in use (if any).
     */
    buf = Get_Front_Of_FS_Buffer_List(&cache->bufferList);
    while (buf != 0) {
        if (buf->fsBlockNum == fsBlockNum) {
            /* If buffer is in use, wait until it is available. */
            while (buf->flags & FS_BUFFER_INUSE) {
                Debug("Waiting for block %lu\n", fsBlockNum);
                Cond_Wait(&cache->cond, &cache->lock);
            }
            goto done;
        }

        /* If buffer isn't in use, it's a candidate for LRU. */
        if (!(buf->flags & FS_BUFFER_INUSE))
            lru = buf;

        buf = Get_Next_In_FS_Buffer_List(buf);
    }

    /*
     * If number of allocated buffers does not exceed the
     * limit, allocate a new one.
     */
    if (cache->numCached < FS_BUFFER_CACHE_MAX_BLOCKS) {
        buf = (struct FS_Buffer *)Malloc(sizeof(*buf));
        if (buf != 0) {
            buf->data = Alloc_Page();
            if (buf->data == 0)
                Free(buf);
            else {
                /* Successful creation */
                buf->fsBlockNum = fsBlockNum;
                buf->flags = 0;
                Add_To_Front_Of_FS_Buffer_List(&cache->bufferList, buf);
                ++cache->numCached;
                goto readAndAcquire;
            }
        }
    }

    /*
     * If there is no LRU buffer, then we have exceeded
     * the number of available buffers.
     */
    if (lru == 0)
        return ENOMEM;

    KASSERT(!noEvict);

    /* Make sure the LRU buffer is clean. */
    if ((rc = Sync_Buffer(cache, lru)) != 0)
        return rc;

    /* LRU buffer is clean, so we can steal it. */
    buf = lru;
    buf->flags = 0;
    buf->fsBlockNum = fsBlockNum;       /* bugfix by neil. */

    Move_To_Front(cache, buf);

  readAndAcquire:
    /*
     * The buffer selected should be clean (no uncommitted data),
     * and should have been moved to the front of the buffer list
     * (to show it has just been referenced).
     */
    KASSERT(!(buf->flags & FS_BUFFER_DIRTY));
    KASSERT(Get_Front_Of_FS_Buffer_List(&cache->bufferList) == buf);

    /* Read block data into buffer. */
    if ((rc = Do_Buffer_IO(cache, buf, Block_Read)) != 0)
        return rc;

  done:
    /* Buffer is now in use. */
    buf->flags |= FS_BUFFER_INUSE;

    /* Success! */
    Debug("Acquired block %lu\n", fsBlockNum);
    *pBuf = buf;
    return 0;
}