int main() { void *bitset = Create_Bit_Set(100); assert(Find_First_Free_Bit(bitset,100) == 0); Set_Bit(bitset, 0); assert(Find_First_Free_Bit(bitset,100) == 1); Set_Bit(bitset, 1); assert(Find_First_Free_Bit(bitset,100) == 2); Set_Bit(bitset, 3); assert(Find_First_Free_Bit(bitset,100) == 2); Set_Bit(bitset, 4); Set_Bit(bitset, 5); Set_Bit(bitset, 6); Set_Bit(bitset, 7); assert(Find_First_Free_Bit(bitset,100) == 2); Set_Bit(bitset, 2); assert(Find_First_Free_Bit(bitset,100) == 8); Clear_Bit(bitset, 2); assert(Find_First_Free_Bit(bitset,100) == 2); }
/* * Get a PFAT_File object representing the file whose directory entry * is given. */ static struct PFAT_File *Get_PFAT_File(struct PFAT_Instance *instance, directoryEntry *entry) { ulong_t numBlocks; struct PFAT_File *pfatFile = 0; char *fileDataCache = 0; struct Bit_Set *validBlockSet = 0; KASSERT(entry != 0); KASSERT(instance != 0); Mutex_Lock(&instance->lock); /* * See if this file has already been opened. * If so, use the existing PFAT_File object. */ for (pfatFile = Get_Front_Of_PFAT_File_List(&instance->fileList); pfatFile != 0; pfatFile = Get_Next_In_PFAT_File_List(pfatFile)) { if (pfatFile->entry == entry) break; } if (pfatFile == 0) { /* Determine size of data block cache for file. */ numBlocks = Round_Up_To_Block(entry->fileSize) / SECTOR_SIZE; /* * Allocate File object, PFAT_File object, file block data cache, * and valid cache block bitset */ if ((pfatFile = (struct PFAT_File *) Malloc(sizeof(*pfatFile))) == 0 || (fileDataCache = Malloc(numBlocks * SECTOR_SIZE)) == 0 || (validBlockSet = Create_Bit_Set(numBlocks)) == 0) { goto memfail; } /* Populate PFAT_File */ pfatFile->entry = entry; pfatFile->numBlocks = numBlocks; pfatFile->fileDataCache = fileDataCache; pfatFile->validBlockSet = validBlockSet; Mutex_Init(&pfatFile->lock); /* Add to instance's list of PFAT_File objects. */ Add_To_Back_Of_PFAT_File_List(&instance->fileList, pfatFile); KASSERT(pfatFile->nextPFAT_File_List == 0); } /* Success! */ goto done; memfail: if (pfatFile != 0) Free(pfatFile); if (fileDataCache != 0) Free(fileDataCache); if (validBlockSet != 0) Free(validBlockSet); done: Mutex_Unlock(&instance->lock); return pfatFile; }