예제 #1
0
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));
}
예제 #2
0
/*
 * 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;
}
예제 #3
0
파일: pfat.c 프로젝트: Dreamgoing/myGeekos
/*
 * 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;
}