示例#1
0
/*
 * Create a new small heap in main memory.
 */
void *SH_create_small_heap(void) {
	// Small heap has not been allocated to the thread yet
	void * heap = mmap(NULL, heapSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); // Use mmap to allocate space for the new small heap.
	if (heap == MAP_FAILED)
		PRINTFMC("MMAP failed");
	return heap;
}
示例#2
0
/*
 * Initialise the small heap.
 * Parameters that are allocated inside of this functions are described in the header file.
 */
struct shMapType *SH_init(void *ptr, pthread_t thread) {
	struct shMapType * shMapElement = malloc(sizeof(struct shMapType));
	shMapElement->memArea = (unsigned int *) ptr;
	shMapElement->memAreaSize = heapSize / sizeof(unsigned int);
	shMapElement->memArea[0] = heapSize / sizeof(unsigned int) - 1;
	shMapElement->memArea[shMapElement->memAreaSize - 1] = heapSize / sizeof(unsigned int);
	shMapElement->thread_id = thread;
	shMapElement->available = 0;
	my_mutex_init(&shMapElement->mutex);
	PRINTFMC("Component created. Heap location: %p\n", shMapElement->memArea);
	return shMapElement;
}
示例#3
0
/*
 * Allocator of memory, allocates into the specified small heap
 */
void *SH_alloc_in_specific_heap(unsigned size, struct shMapType * shMapEntry){
	if (size == 0) {  //return NULL pointer after attempt to allocate 0-length memory
		return NULL ;
	}
	if (shMapEntry == NULL ) {
		if ( pthread_self() == mainThread ) {
			// If it is the main thread - malloc space
			void * result = (void *) malloc(size + sizeof(MemHeaderStruct));
			listAdd(mallocList, result);
			log_into_file("malloc     at", result, size + sizeof(MemHeaderStruct));  // Log into a file, if required.
			return result;
		}
		PRINTFMC("\nSize of SHList %d. Pthread_self %u. NULL returned from the list.", SHList->count, (unsigned) pthread_self());
		// If nothing can be done - return NULL
		return NULL ;
	} else {
		return SH_alloc_at_base(size, shMapEntry);
	}
}
示例#4
0
/*
 * Initialise an Insense component and start a POSIX thread running the behaviour function from the component.
 */
void *component_create(behaviour_ft behaviour, int struct_size, int stack_size, int argc, void *argv[], int core) {
	// Define thread
	struct IComponent_data *this_ptr;
	// Allocate space for the struct
#if HEAPS == HEAP_PRIVATE // Private heaps
	struct shMapType *heapElement = new_PrivateHeap(); 		// Create a new private heap (to be put to the heap map)
	this_ptr = DAL_alloc_in_specific_heap(struct_size, true, heapElement); 			// Allocate space for this_ptr in the newly created private heap
	if (this_ptr == NULL ) {
		return NULL ;
	} else {
		memset(this_ptr, 0, struct_size);
	}
#else // Shared heap
	if ((this_ptr = ((struct IComponent_data *) DAL_alloc(struct_size, true))) == NULL ) {
		return NULL;
	} else {
		memset(this_ptr, 0, struct_size);
	}
#endif
	// Initialize this->comp_create_sem
	my_sem_init(&(this_ptr->component_create_sem), 0);
	// Setup the stopped condition
	if (struct_size) {
		struct IComponent_data *t = (struct IComponent_data*) this_ptr;
		t->stopped = 0;
	}

	// Define new structure for arguments for the wrapper function
	// Whenever dealing with garbage collection, first define as NULL
	struct argStructType * argStruct = malloc(sizeof(struct argStructType));
	argStruct->behaviour = behaviour;
	argStruct->argc = argc;
	argStruct->argv = argv;
	argStruct->this_ptr = this_ptr;

	// Create thread
#if HEAPS == HEAP_PRIVATE // Private heaps
	pthread_mutex_lock(&thread_lock); // Lock mutex to make component thread wait until its heap has been put inserted into the heap map
#endif

	pthread_create(&this_ptr->behav_thread, NULL, startRoutine, argStruct); // Create a POSIX thread, use wrapper function startRoutine to pass three arguments to the function running inside of the thread

	//Set affinity
#if AFFINITY_ALGO != AFFINITY_DYNAMIC
	if (core != -1) { // Manually passed Core ID
		setAffinityToCore(this_ptr->behav_thread, core);// Use passed ID of a core
	} else { // Core ID was not passed to the component_create function
		setAffinity(this_ptr->behav_thread);// Use an algorithm defined in GlobalVars.h
	}
	getAffinityThread(this_ptr->behav_thread); // Check if setting affinity worked. Data outputted only in PRINTMC is defined.
#endif

	// If small heaps are used, add a new entry to the map with a pointer to a newly created pthread.
#if HEAPS == HEAP_PRIVATE // Private heaps
	heapElement->thread_id = this_ptr->behav_thread; // Put a thread id to the element to be to the map
	PRINTFMC("Component created. Thread ID: %x\n", heapElement->thread_id);
	listAdd(SHList, heapElement);
	pthread_mutex_unlock(&thread_lock); // Unlock mutex to permit component to continue now that its heap has been put inserted into the heap map
#endif
	// Insert thread into the list of threads
	listAdd(threadList, this_ptr->behav_thread);
	my_sem_wait(&this_ptr->component_create_sem); // Wait for creation of the component
	return this_ptr;
}
/*
 * Entry point of Multi-core Insense runtime.
 */
int main() {
	PRINTFMC("Cache line size: %dB\n", cache_line_size());PRINTFMC("Main thread: %u\n", (unsigned) pthread_self());

#if HEAPS // Small heaps
	// Initialize mutex
	if (pthread_mutex_init(&thread_lock, NULL ) != 0) {
		PRINTF("Mutex initialization failed.\n");
		return NULL;
	}
#else // Big heap
	// Initialize mutex
	if (pthread_mutex_init(&alloc_lock, NULL ) != 0) {
		PRINTF("Mutex initialization failed.\n");
		return NULL ;
	}
#endif

	mainThread = pthread_self(); // Note the ID of the main thread.

	// Create a list for storing references to p-threads
	threadList = listCreate();

	// Create map used to store memory locations of small heaps (using Thread safe list)
	SHList = listCreate();

	// Create map used to store memory locations what is allocated using malloc
	mallocList = listCreate();

// Start recording execution time
#if TIMING
	// CPU time
	struct timespec start, finish;
	double elapsed;
	//clock_gettime(CLOCK_MONOTONIC, &start);
	// User time
	time_t start_t, end_t;
	double diff_t;
	time(&start_t);
#endif

	// Call primordial_main.
	primordial_main(NULL );

	// Join all p-threads
	if (threadList != NULL ) {
		listJoinThreads(threadList);
	}

// Stop recording execution time
#if TIMING
	// CPU time
	//clock_gettime(CLOCK_MONOTONIC, &finish);
	elapsed = (finish.tv_sec - start.tv_sec);
	elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
	printf("CPU:  %f seconds elapsed\n", elapsed);
#endif

	// Destroy lists and free memory
	listDestroy(threadList);
	listDestroy(SHList);
	listDestroy(mallocList);
	pthread_mutex_destroy(&thread_lock); 	// Destroy mutex lock used with pthreads
	pthread_mutex_destroy(&alloc_lock); 	// Destroy mutex lock used with alloc and free in the big heap scheme

	return 1;
}
示例#6
0
/*
 * Entry point of Multi-core Insense runtime.
 */
int main(int argc, char* argv[]) {
	PRINTFMC("Cache line size: %dB\n", cache_line_size());
	PRINTFMC("Main thread: %u\n", (unsigned) pthread_self());

	errval_t err;
	coreid_t mycore = disp_get_core_id();

	if (argc == 2) {
		num_to_span = atoi(argv[1]);
		if(num_to_span==0)
			all_spanned = true;		

		debug_printf("Spanning onto %d cores\n", num_to_span);
		for (int i = 1; i < num_to_span; i++) {
			err = domain_new_dispatcher(mycore + i, span_cb, NULL);
		    
			if (err_is_fail(err)) {
				DEBUG_ERR(err, "failed span %d", i);
			} 
		}
	} else {
		debug_printf("ERROR: Must specify number of cores to span\n");
		return EXIT_FAILURE;
	}

	posixcompat_pthread_set_placement_fn(rrPlacement);

	while (!all_spanned) {
		thread_yield();
	}

	my_mutex_init(&shared_heap_mutex);
#if HEAPS == HEAP_PRIVATE // Private heaps
	// Initialize mutex
	if (pthread_mutex_init(&thread_lock, NULL ) != 0) {
		PRINTF("Mutex initialization failed.\n");
		return -1;
	}
#endif

	mainThread = pthread_self(); // Note the ID of the main thread.

	// Create a list for storing references to p-threads
	threadList = listCreate();

	// Create map used to store memory locations of small heaps (using Thread safe list)
	SHList = listCreate();

	// Create map used to store memory locations what is allocated using malloc
	mallocList = listCreate();

// Start recording execution time
#if TIMING
	// CPU time
	uint64_t start, end;
	uint64_t tsc_per_ms = 0;
	sys_debug_get_tsc_per_ms(&tsc_per_ms);
	start = rdtsc();
#endif

	// Call primordial_main.
	primordial_main(NULL );

	// Join all p-threads
	if (threadList != NULL ) {
		listJoinThreads(threadList);
	}

// Stop recording execution time
#if TIMING
	end = rdtsc();
	
	uint64_t diff = (end - start) / tsc_per_ms;
	float elapsed = (diff / 1000) + ((diff % 1000) / 1000.0);

	printf("CPU:  %f seconds elapsed\n", elapsed);
#endif

	// Destroy lists and free memory
	listDestroy(threadList);
	listDestroy(SHList);
	listDestroy(mallocList);
#if HEAPS == HEAP_PRIVATE
	pthread_mutex_destroy(&thread_lock); 	// Destroy mutex lock used with pthreads
#endif
	return 0;
}