Esempio n. 1
0
	ModuleInstance* instantiateModule(const IR::Module& module,ImportBindings&& imports)
	{
		ModuleInstance* moduleInstance = new ModuleInstance(
			std::move(imports.functions),
			std::move(imports.tables),
			std::move(imports.memories),
			std::move(imports.globals)
			);
		
		// Get disassembly names for the module's objects.
		DisassemblyNames disassemblyNames;
		IR::getDisassemblyNames(module,disassemblyNames);

		// Check the type of the ModuleInstance's imports.
		errorUnless(moduleInstance->functions.size() == module.functions.imports.size());
		for(Uptr importIndex = 0;importIndex < module.functions.imports.size();++importIndex)
		{
			errorUnless(isA(moduleInstance->functions[importIndex],module.types[module.functions.imports[importIndex].type.index]));
		}
		errorUnless(moduleInstance->tables.size() == module.tables.imports.size());
		for(Uptr importIndex = 0;importIndex < module.tables.imports.size();++importIndex)
		{
			errorUnless(isA(moduleInstance->tables[importIndex],module.tables.imports[importIndex].type));
		}
		errorUnless(moduleInstance->memories.size() == module.memories.imports.size());
		for(Uptr importIndex = 0;importIndex < module.memories.imports.size();++importIndex)
		{
			errorUnless(isA(moduleInstance->memories[importIndex],module.memories.imports[importIndex].type));
		}
		errorUnless(moduleInstance->globals.size() == module.globals.imports.size());
		for(Uptr importIndex = 0;importIndex < module.globals.imports.size();++importIndex)
		{
			errorUnless(isA(moduleInstance->globals[importIndex],module.globals.imports[importIndex].type));
		}

		// Instantiate the module's memory and table definitions.
		for(const TableDef& tableDef : module.tables.defs)
		{
			auto table = createTable(tableDef.type);
			if(!table) { causeException(Exception::Cause::outOfMemory); }
			moduleInstance->tables.push_back(table);
		}
		for(const MemoryDef& memoryDef : module.memories.defs)
		{
			if(!MemoryInstance::theMemoryInstance) {
				MemoryInstance::theMemoryInstance = createMemory(memoryDef.type);
				if(!MemoryInstance::theMemoryInstance) { causeException(Exception::Cause::outOfMemory); }
			}
			moduleInstance->memories.push_back(MemoryInstance::theMemoryInstance);
		}

		// Find the default memory and table for the module.
		if(moduleInstance->memories.size() != 0)
		{
			assert(moduleInstance->memories.size() == 1);
			moduleInstance->defaultMemory = moduleInstance->memories[0];
		}
		if(moduleInstance->tables.size() != 0)
		{
			assert(moduleInstance->tables.size() == 1);
			moduleInstance->defaultTable = moduleInstance->tables[0];
		}

		// If any memory or table segment doesn't fit, throw an exception before mutating any memory/table.
		for(auto& tableSegment : module.tableSegments)
		{
			TableInstance* table = moduleInstance->tables[tableSegment.tableIndex];
			const Value baseOffsetValue = evaluateInitializer(moduleInstance,tableSegment.baseOffset);
			errorUnless(baseOffsetValue.type == ValueType::i32);
			const U32 baseOffset = baseOffsetValue.i32;
			if(baseOffset > table->elements.size()
			|| table->elements.size() - baseOffset < tableSegment.indices.size())
			{ causeException(Exception::Cause::invalidSegmentOffset); }
		}

		//Previously, the module instantiation would write in to the memoryInstance here. Don't do that
      //since the memoryInstance is shared across all moduleInstances and we could be compiling
      //a new instance while another instance is running
		
		// Instantiate the module's global definitions.
		for(const GlobalDef& globalDef : module.globals.defs)
		{
			const Value initialValue = evaluateInitializer(moduleInstance,globalDef.initializer);
			errorUnless(initialValue.type == globalDef.type.valueType);
			moduleInstance->globals.push_back(new GlobalInstance(globalDef.type,initialValue));
		}
		
		// Create the FunctionInstance objects for the module's function definitions.
		for(Uptr functionDefIndex = 0;functionDefIndex < module.functions.defs.size();++functionDefIndex)
		{
			const Uptr functionIndex = moduleInstance->functions.size();
			const DisassemblyNames::Function& functionNames = disassemblyNames.functions[functionIndex];
			std::string debugName = functionNames.name;
			if(!debugName.size()) { debugName = "<function #" + std::to_string(functionDefIndex) + ">"; }
			auto functionInstance = new FunctionInstance(moduleInstance,module.types[module.functions.defs[functionDefIndex].type.index],nullptr,debugName.c_str());
			moduleInstance->functionDefs.push_back(functionInstance);
			moduleInstance->functions.push_back(functionInstance);
		}

		// Generate machine code for the module.
		LLVMJIT::instantiateModule(module,moduleInstance);

		// Set up the instance's exports.
		for(const Export& exportIt : module.exports)
		{
			ObjectInstance* exportedObject = nullptr;
			switch(exportIt.kind)
			{
			case ObjectKind::function: exportedObject = moduleInstance->functions[exportIt.index]; break;
			case ObjectKind::table: exportedObject = moduleInstance->tables[exportIt.index]; break;
			case ObjectKind::memory: exportedObject = moduleInstance->memories[exportIt.index]; break;
			case ObjectKind::global: exportedObject = moduleInstance->globals[exportIt.index]; break;
			default: Errors::unreachable();
			}
			moduleInstance->exportMap[exportIt.name] = exportedObject;
		}
		
		// Copy the module's table segments into the module's default table.
		for(const TableSegment& tableSegment : module.tableSegments)
		{
			TableInstance* table = moduleInstance->tables[tableSegment.tableIndex];
			
			const Value baseOffsetValue = evaluateInitializer(moduleInstance,tableSegment.baseOffset);
			errorUnless(baseOffsetValue.type == ValueType::i32);
			const U32 baseOffset = baseOffsetValue.i32;
			assert(baseOffset + tableSegment.indices.size() <= table->elements.size());

			for(Uptr index = 0;index < tableSegment.indices.size();++index)
			{
				const Uptr functionIndex = tableSegment.indices[index];
				assert(functionIndex < moduleInstance->functions.size());
				setTableElement(table,baseOffset + index,moduleInstance->functions[functionIndex]);
			}
		}

		// Call the module's start function.
		if(module.startFunctionIndex != UINTPTR_MAX)
		{
			assert(moduleInstance->functions[module.startFunctionIndex]->type == IR::FunctionType::get());
			moduleInstance->startFunctionIndex = module.startFunctionIndex;
		}

		moduleInstances.push_back(moduleInstance);
		return moduleInstance;
	}
Esempio n. 2
0
 handle<cl_mem> createMemory(cl_mem_flags flags, const VectorType<SCALARTYPE, A> & _buffer)
 {
   return createMemory(flags, static_cast<unsigned int>(sizeof(SCALARTYPE) * _buffer.size()), (void*)&_buffer[0]);
 }
Esempio n. 3
0
int main(int argc, char *argv[])
{
	int i, j, m, n, k, pid, total = 0, errorCheck = FALSE;
	/* 2D integer arrays to point to shared memory block. */
	int *matrixA_ptr = NULL, *matrixB_ptr = NULL, *matrixC_ptr = NULL;
	/* Names of the shared memory objects. */
	char *matrixA = "matrixA", *matrixB = "matrixB", *matrixC = "matrixC", 
		*subtotal = "subtotal";
	Shared *ptr;

	/* Error check the number of command line arguements. */
	if (argc != 6)
	{
		printf("Incorrect number of command line arguements!\n");
		errorCheck = TRUE;
	}

	/* If there was the correct number of command line arguments
	   then continue with the program. */
	if (errorCheck != TRUE)
	{
		/* Convert command-line args from string to int. */
		m = atoi(argv[3]);
		n = atoi(argv[4]);
		k = atoi(argv[5]);

		if (m < 0 || n < 0 || k < 0)
		{
			printf("One or more matrix dimensions are invalid!\n");
			return 0;
		}

		/* Create shared memory objects. */
		matrixA_ptr = (int*)createMemory(matrixA, sizeof(int)*m*n);
		matrixB_ptr = (int*)createMemory(matrixB, sizeof(int)*n*k);
		matrixC_ptr = (int*)createMemory(matrixC, sizeof(int)*m*k);
		ptr = (Shared*)createMemory(subtotal, sizeof(Shared));

		/* Read matrix files. */
		readMatrix(argv[1], m, n, matrixA_ptr);
		readMatrix(argv[2], n, k, matrixB_ptr);

		/* Initialise semaphores. */
		sem_init(&ptr->mutex, 1, 1);
		sem_init(&ptr->empty, 1, 1);
		sem_init(&ptr->full, 1, 0);

		/* Kills zombie processes. */
		signal(SIGCHLD, SIG_IGN);

		/* Create m child processes. */
		for (i = 0; i < m; i++)
		{
			pid = fork();
			/*Fork error*/
			if (pid < 0)
			{
				perror("Fork Failed");
				return 0;
			}
			/*Do child processing*/
			else if (pid == 0)
			{
				childProcess(matrixA_ptr, matrixB_ptr, matrixC_ptr, ptr, i, n, k);
				exit(0);
			}
		}
		/*Parent Process*/
		for (j = 0; j < m; j++)
		{
			sem_wait(&ptr->full);
			sem_wait(&ptr->mutex);
			/*Consume buffer*/
			printf("Subtotal produced by process with ID %d: %d\n",ptr->process, ptr->subtotal);
			total += ptr->subtotal;
	      	sem_post(&ptr->mutex);
	      	sem_post(&ptr->empty);
		}
		printf("Total: %d\n", total);	
	}

	return 0;
}
Esempio n. 4
0
/**
 * Load ROM from file.
 * \param [in]  filename ROM filename.
 * \param [out] memmap   Memory map.
 * \return 1 upon success, 0 if an error occured.
 */
int loadROM(const char* filename, MemoryMap* memmap)
{
    FILE   *in;
    size_t size;
    size_t count, nRead;
    
    /* Open file */
    in = fopen(filename, "rb");
    if(NULL == in)
    {
        ERROR_MSG("Unable to open %s : %s", filename, strerror(errno));
        return 0;
    }

    /* Compute file size. */
    fseek(in, 0, SEEK_END);
    size  = ftell(in);
    fseek(in, 0, SEEK_SET);
    size -= ftell(in);

    /* Check size */
    if(0 == size)
    {
        ERROR_MSG("Empty file: %s", filename);
        goto err_0;
    }

    /* Check for possible header */
    if(size & 0x200)
    {
        /* Jump header */
        size &= ~0x200;
        if(fseek(in, 0x200, SEEK_SET))
        {
            ERROR_MSG("Failed to jump rom header in %s: %s", filename, strerror(errno));
            goto err_0;
        }
    }

    /* Allocate rom storage */
    if(0 == createMemory(&memmap->rom, (size + 0x1fff) & ~0x1fff))
    {
        ERROR_MSG("Failed to allocate ROM storage : %s", strerror(errno));
        goto err_0;
    }
    /* Fill rom with 0xff */
    memset(memmap->rom.data, 0xff, memmap->rom.len);
    
    /* Read ROM data */
    count = (size < memmap->rom.len) ? size : memmap->rom.len;
    nRead = fread(memmap->rom.data, 1, count, in);
    if(nRead != count)
    {
        ERROR_MSG("Failed to read ROM data from %s : %s", filename, strerror(errno));
        goto err_1;
    }
    fclose(in);

    /* Initialize ROM pages (from mednafen source code). */
    /* Note : the decrement by (i*8192) is a trick to avoid doing a 
     *        bitwise with the address when reading a byte from that
     *        page. */
    if(0x60000 == memmap->rom.len)
    {
        int i;
        for(i=0; i<64; i++)
        {
            memmap->page[i] = &memmap->rom.data[(i & 0x1f) * 8192] - (i*8192);
        }
        for(i=64; i<128; i++)
        {
            memmap->page[i] = &memmap->rom.data[((i & 0x0f) + 32) * 8192] - (i*8192);
        }
    }
    else if(0x80000 == memmap->rom.len)
    {
        int i;
        for(i=0; i<64; i++)
        {
            memmap->page[i] = &memmap->rom.data[(i & 0x3f) * 8192] - (i*8192);
        }
        for(i=64; i<128; i++)
        {
            memmap->page[i] = &memmap->rom.data[((i & 0x1f) + 32) * 8192] - (i*8192);
        }
    }
    else
    {
        int i;
        for(i=0; i<128; i++)
        {
            uint8_t bank = i % (memmap->rom.len / 8192);
            memmap->page[i] = &memmap->rom.data[bank * 8192] - (i*8192);
        }
    }

    return 1;

err_1:
    destroyMemory(&memmap->rom);
err_0:
    fclose(in);
    return 0;
}