Example #1
0
TVMStatus VMMemoryPoolAllocate(TVMMemoryPoolID memory, TVMMemorySize size, void **pointer){
	TMachineSignalState sigState;	
	MachineSuspendSignals(&sigState);
	ThreadStore* tStore = ThreadStore::getInstance();

	if((size == 0) || (pointer == NULL)){
		printf("VMMemoryPoolAllocate(): size was zero or pointer was null.\n");
		MachineResumeSignals(&sigState);
		return VM_STATUS_ERROR_INVALID_PARAMETER;
	}

//	printf("VMMemoryPoolAllocate(): looking for pool: %d\n", memory);
	MemoryPool *pool = tStore->findMemoryPoolByID(memory);

	if(pool == NULL){
		printf("VMMemoryPoolAllocate(): pool was null.\n");
		MachineResumeSignals(&sigState);
		return VM_STATUS_ERROR_INVALID_PARAMETER;
	}
	
	uint8_t* newMemory = pool->allocateMemory(size);
//	printf("VMMemoryPoolAllocate(): allocated chunk %d\n", newMemory);

	if(newMemory == NULL){
		printf("VMMemoryPoolAllocate(): new memory allocated was null.\n");
		return VM_STATUS_ERROR_INSUFFICIENT_RESOURCES;
	}

//	printf("VMMemoryPoolAllocate(): Memory allocated successfully!\n");
	*pointer = newMemory;										//if execution gets here, everything is valid and
	MachineResumeSignals(&sigState);				//the memory should be allocated
	return VM_STATUS_SUCCESS;
}
Example #2
0
TVMStatus VMFileWrite(int fileDescriptor, void* data, int *length){
	TMachineSignalState sigState;			
	MachineSuspendSignals(&sigState);	//suspend signals so we cannot be pre-empted while scheduling a new thread
	ThreadStore* tStore = ThreadStore::getInstance();
	MemoryPool* sharedMemory = tStore->findMemoryPoolByID((TVMMemoryPoolID)1);
	TCB* currentThread = tStore->getCurrentThread();
	uint8_t* sharedLocation;
	TVMMemorySize allocSize = *length;

	//Step 0 - validate data
	if((data == NULL) || (length == NULL)){
		MachineResumeSignals (&sigState);
		return VM_STATUS_ERROR_INVALID_PARAMETER;
	}
	
	//Step 1 - initialize shared memory location, and wait if memory is not available from share pool
	if(allocSize > 512){	//make sure thread never asks for > 512 bytes
		allocSize = 512;
	}
	if(allocSize > sharedMemory->getSize()){
		allocSize = sharedMemory->getSize();
	}

	sharedLocation = sharedMemory->allocateMemory(allocSize);		//allocate a space in the shared memory pool
	
	if(sharedLocation == NULL){
//		printf("VMFileWrite(): shared location was null\n");
		sharedLocation = tStore->waitCurrentThreadOnMemory(allocSize, 1);
	}

	//Step 2 - IO loop. If the data to transfer is > 512 bytes, loop. If it isn't, loop only runs once.
	int bytesLeft = *length;
	int chunkSize = bytesLeft;
	void *dataLocation = data;
	int bytesTransferred = 0;

	if(bytesLeft > allocSize)
		chunkSize = allocSize;

	for(bytesLeft; bytesLeft > 0; bytesLeft -= chunkSize){

		if(bytesLeft < chunkSize)
			chunkSize = bytesLeft;
		
		//printf("tid %d outputting\n", tStore->getCurrentThread()->getThreadID());

		//copy chunkSize bytes of data from *data into the shared memory location, starting at dataLocation
		memcpy((void*)sharedLocation, dataLocation, chunkSize*sizeof(uint8_t));
	
		//step 3 - call MachineFileWrite with the pointer to the shared memory location
		MachineFileWrite(fileDescriptor, sharedLocation, chunkSize, &machineFileIOCallback, (void*)currentThread);
		tStore->waitCurrentThreadOnIO();	//switch to a new thread while waiting on IO

		//update bytesLeft and dataLocation for the next iteration
		bytesTransferred = bytesTransferred + currentThread->getFileIOResult();
		dataLocation = ((uint8_t*)dataLocation + chunkSize);
	}

	//step 4 - Deallocate the shared memory location, do last error check, and return
	sharedMemory->deallocate(sharedLocation);
	
	if(bytesTransferred < 0){
		MachineResumeSignals (&sigState);
		return VM_STATUS_FAILURE;
	}
	
	MachineResumeSignals (&sigState);
	return VM_STATUS_SUCCESS;
}
Example #3
0
TVMStatus VMFileRead(int filedescriptor, void *data, int *length){
	TMachineSignalState sigState;			
	MachineSuspendSignals(&sigState);	//suspend signals so we cannot be pre-empted while scheduling a new thread
	ThreadStore* tStore = ThreadStore::getInstance();
	MemoryPool* sharedMemory = tStore->findMemoryPoolByID((TVMMemoryPoolID)1);
	TCB* currentThread = tStore->getCurrentThread();
	uint8_t* sharedLocation;
	TVMMemorySize allocSize = *length;

	//Step 0 - validation
	if ((data == NULL) || (length == NULL)){
		MachineResumeSignals (&sigState);
  	return VM_STATUS_ERROR_INVALID_PARAMETER;
	}

	//Step 1 - initialize shared memory location, and wait if memory is not available from share pool
	if(allocSize > 512){	//make sure thread never asks for > 512 bytes
		allocSize = 512;
	}

	if(allocSize > sharedMemory->getSize()){
		allocSize = sharedMemory->getSize();
	}

	sharedLocation = sharedMemory->allocateMemory(allocSize);		//allocate a space in the shared memory pool
	
	if(sharedLocation == NULL){
		//if there isn't enough room in shared memory to do the IO, the current thread must wait until a chunk
		//of size allocSize becomes avaliable. waitCurrentThread puts the thread to sleep until that happens,
		//then returns the amount of shared memory requested.
		sharedLocation = tStore->waitCurrentThreadOnMemory(allocSize, 1);
	}
	
	//Step 2 - Set up loop 
	int bytesLeft = *length;
	int chunkSize = bytesLeft;
	void *dataLocation = data;
	int bytesTransferred = 0;
	
	if(bytesLeft > allocSize)
		chunkSize = allocSize;

	for(bytesLeft; bytesLeft > 0; bytesLeft -= chunkSize){

		if(bytesLeft < chunkSize)
			chunkSize = bytesLeft;

		//read the amount of data specified by chunkSize into the location specified by sharedLocation
		MachineFileRead(filedescriptor, (void*)sharedLocation, chunkSize, &machineFileIOCallback, (void*)currentThread);
		tStore->waitCurrentThreadOnIO();															//resume execution here after IO completes
		//copy chunkSize bytes of data from sharedLocation into dataLocation, starting at sharedLocation
		memcpy(dataLocation, (void*)sharedLocation, chunkSize*sizeof(uint8_t));
		
		//update bytesLeft and dataLocation for the next iteration
		bytesTransferred = bytesTransferred + currentThread->getFileIOResult();
		dataLocation = ((uint8_t*)dataLocation + chunkSize);
	}

	if(currentThread->getFileIOResult() < 0){			//if call to open() failed
		MachineResumeSignals (&sigState);
		return VM_STATUS_FAILURE;											//return failure state
	}
	
	*length = bytesTransferred;
	MachineResumeSignals(&sigState);
	return VM_STATUS_SUCCESS;
}