/* * 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; }
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); }
/* * 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"); }
/* * 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; }