static bool validateSID(int sid) { KASSERT(g_currentThread->semaphores != NULL); return (0 <= sid && sid < MAX_NUM_SEMAPHORES && !g_Semaphores[sid].available && Is_Bit_Set(g_currentThread->semaphores, sid)); }
/* * This is slow!! */ int Find_First_N_Free(void *bitSet, uint_t runLength, ulong_t totalBits) { uint_t i, j; for (i = 0; i < totalBits - runLength; i++) { if (!Is_Bit_Set(bitSet, i)) { for (j = 1; j < runLength; j++) { if (Is_Bit_Set(bitSet, i + j)) { break; } } if (j == runLength) { return i; } } } return -1; }
/* * Read function for PFAT files. */ static int PFAT_Read(struct File *file, void *buf, ulong_t numBytes) { struct PFAT_File *pfatFile = (struct PFAT_File*) file->fsData; struct PFAT_Instance *instance = (struct PFAT_Instance*) file->mountPoint->fsData; ulong_t start = file->filePos; ulong_t end = file->filePos + numBytes; ulong_t startBlock, endBlock, curBlock; ulong_t i; /* Special case: can't handle reads longer than INT_MAX */ if (numBytes > INT_MAX) return EINVALID; /* Make sure request represents a valid range within the file */ if (start >= file->endPos || end > file->endPos || end < start) { Debug("Invalid read position: filePos=%lu, numBytes=%lu, endPos=%lu\n", file->filePos, numBytes, file->endPos); return EINVALID; } /* * Now the complicated part; ensure that all blocks containing the * data we need are in the file data cache. */ startBlock = (start % SECTOR_SIZE) / SECTOR_SIZE; endBlock = Round_Up_To_Block(end) / SECTOR_SIZE; /* * Traverse the FAT finding the blocks of the file. * As we encounter requested blocks that aren't in the * file data cache, we issue requests to read them. */ curBlock = pfatFile->entry->firstBlock; for (i = 0; i < endBlock; ++i) { /* Are we at a valid block? */ if (curBlock == FAT_ENTRY_FREE || curBlock == FAT_ENTRY_EOF) { Print("Unexpected end of file in FAT at file block %lu\n", i); return EIO; /* probable filesystem corruption */ } /* Do we need to read this block? */ if (i >= startBlock) { int rc = 0; /* Only allow one thread at a time to read this block. */ Mutex_Lock(&pfatFile->lock); if (!Is_Bit_Set(pfatFile->validBlockSet, i)) { /* Read block into the file data cache */ Debug("Reading file block %lu (device block %lu)\n", i, curBlock); rc = Block_Read(file->mountPoint->dev, curBlock, pfatFile->fileDataCache + i*SECTOR_SIZE); if (rc == 0) /* Mark as having read this block */ Set_Bit(pfatFile->validBlockSet, i); } /* Done attempting to fetch the block */ Mutex_Unlock(&pfatFile->lock); if (rc != 0) return rc; } /* Continue to next block */ ulong_t nextBlock = instance->fat[curBlock]; curBlock = nextBlock; } /* * All cached data we need is up to date, * so just copy it into the caller's buffer. */ memcpy(buf, pfatFile->fileDataCache + start, numBytes); Debug("Read satisfied!\n"); return numBytes; }