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; }
/** * Reserve given DMA channel. * @param chan the channel to reserve * @return true if successful, false if not */ bool Reserve_DMA(int chan) { bool iflag = Begin_Int_Atomic(); bool result = false; KASSERT(VALID_CHANNEL(chan)); if (!IS_RESERVED(chan)) { /* Channel is available; unmask it. */ Out_Byte(DMA_MASK_ONE_REG(chan), chan & 3); /* Mask channel as allocated */ s_allocated |= (1 << chan); result = true; } End_Int_Atomic(iflag); return result; }
/* * Wait for a keycode to arrive. * Uses the keyboard wait queue to sleep until * a keycode arrives. */ Keycode Wait_For_Key(void) { bool gotKey, iflag; Keycode keycode = KEY_UNKNOWN; iflag = Begin_Int_Atomic(); do { gotKey = !Is_Queue_Empty(); if (gotKey) keycode = Dequeue_Keycode(); else Wait(&s_waitQueue); } while (!gotKey); End_Int_Atomic(iflag); return keycode; }
int Create_Semaphore(char *name, int nameLength, int initCount) { int sid = 0; int ret = -1; /* Syscall contract */ KASSERT(name != NULL); KASSERT(0 < nameLength && nameLength <= MAX_SEMAPHORE_NAME); KASSERT(0 <= initCount); KASSERT(strnlen(name, MAX_SEMAPHORE_NAME) == nameLength); bool atomic = Begin_Int_Atomic(); sid = isSemaphoreCreated(name, nameLength); KASSERT(sid < 0 || sid < MAX_NUM_SEMAPHORES); KASSERT(g_currentThread->semaphores != NULL); /* Negative sid for non existing, otherwise sid is Semaphore ID */ if (0 <= sid) { /* Already created semaphore */ g_Semaphores[sid].references++; Set_Bit(g_currentThread->semaphores, sid); ret = sid; } else { /* Semaphore not created. Create. */ sid = getFreeSemaphore(); if (sid < 0) { /* No semaphores available */ ret = EUNSPECIFIED; } else { strncpy(g_Semaphores[sid].name, name, MAX_SEMAPHORE_NAME); g_Semaphores[sid].resources = initCount; g_Semaphores[sid].available = false; g_Semaphores[sid].references = 1; Clear_Thread_Queue(&g_Semaphores[sid].waitingThreads); Set_Bit(g_currentThread->semaphores, sid); ret = sid; } } End_Int_Atomic(atomic); return ret; }
/* * Print list of all threads in system. * For debugging. */ void Dump_All_Thread_List(void) { struct Kernel_Thread *kthread; int count = 0; bool iflag = Begin_Int_Atomic(); kthread = Get_Front_Of_All_Thread_List(&s_allThreadList); Print("["); while (kthread != 0) { ++count; Print("<%lx,%lx,%lx>", (ulong_t) Get_Prev_In_All_Thread_List(kthread), (ulong_t) kthread, (ulong_t) Get_Next_In_All_Thread_List(kthread)); KASSERT(kthread != Get_Next_In_All_Thread_List(kthread)); kthread = Get_Next_In_All_Thread_List(kthread); } Print("]\n"); Print("%d threads are running\n", count); End_Int_Atomic(iflag); }
/* * Write a single character to the screen at current position * using current attribute, handling scrolling, special characters, etc. */ void Put_Char(int c) { bool iflag = Begin_Int_Atomic(); Put_Char_Imp(c); Update_Cursor(); End_Int_Atomic(iflag); }
/* * Set the current character attribute. */ void Set_Current_Attr(uchar_t attrib) { bool iflag = Begin_Int_Atomic(); s_cons.currentAttr = attrib; End_Int_Atomic(iflag); }
/* * Get current cursor position. */ void Get_Cursor(int *row, int *col) { bool iflag = Begin_Int_Atomic(); *row = s_cons.row; *col = s_cons.col; End_Int_Atomic(iflag); }
/* * Write a block at the logical block number indicated. */ static int IDE_Write(int driveNum, int blockNum, char *buffer) { int i; int head; int sector; int cylinder; short *bufferW; int reEnable = 0; if(driveNum < 0 || driveNum > (numDrives - 1)) { return IDE_ERROR_BAD_DRIVE; } if(blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) { return IDE_ERROR_INVALID_BLOCK; } /* now compute the head, cylinder, and sector */ sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1; cylinder = blockNum / (drives[driveNum].num_Heads * drives[driveNum].num_SectorsPerTrack); head = (blockNum / drives[driveNum].num_SectorsPerTrack) % drives[driveNum].num_Heads; if(ideDebug) { Print("request to write block %d\n", blockNum); Print(" head %d\n", head); Print(" cylinder %d\n", cylinder); Print(" sector %d\n", sector); } #ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK reEnable = Begin_Int_Atomic(); #endif Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1); Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector); Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder)); Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder)); Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(driveNum) | head); Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_WRITE_SECTORS); /* wait for the drive */ while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ; bufferW = (short *)buffer; for(i = 0; i < 256; i++) { Out_Word(IDE_DATA_REGISTER, bufferW[i]); } if(ideDebug) Print("About to wait for Write \n"); /* wait for the drive */ while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ; if(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) { Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER)); #ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK End_Int_Atomic(reEnable); #endif return IDE_ERROR_DRIVE_ERROR; } if(ideDebug) Print("write completed \n"); #ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK End_Int_Atomic(reEnable); #endif return IDE_ERROR_NO_ERROR; }