forked from Bananymous/banan-os
				
			LibC: Fix my ugly and hacked posix_memalign
This commit is contained in:
		
							parent
							
								
									ff289b25b6
								
							
						
					
					
						commit
						87f348b48e
					
				|  | @ -96,12 +96,6 @@ static bool allocate_pool(size_t pool_index) | ||||||
| 	node->prev_free = nullptr; | 	node->prev_free = nullptr; | ||||||
| 	node->next_free = nullptr; | 	node->next_free = nullptr; | ||||||
| 
 | 
 | ||||||
| #pragma GCC diagnostic push |  | ||||||
| #pragma GCC diagnostic ignored "-Warray-bounds" |  | ||||||
| #pragma GCC diagnostic ignored "-Wstringop-overflow" |  | ||||||
| 	node->data[-1] = 0; |  | ||||||
| #pragma GCC diagnostic pop |  | ||||||
| 
 |  | ||||||
| 	pool.free_list = node; | 	pool.free_list = node; | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
|  | @ -150,12 +144,6 @@ static void shrink_node_if_needed(malloc_pool_t& pool, malloc_node_t* node, size | ||||||
| 	next->size = node_end - (uint8_t*)next; | 	next->size = node_end - (uint8_t*)next; | ||||||
| 	next->last = node->last; | 	next->last = node->last; | ||||||
| 
 | 
 | ||||||
| #pragma GCC diagnostic push |  | ||||||
| #pragma GCC diagnostic ignored "-Warray-bounds" |  | ||||||
| #pragma GCC diagnostic ignored "-Wstringop-overflow" |  | ||||||
| 	next->data[-1] = 0; |  | ||||||
| #pragma GCC diagnostic pop |  | ||||||
| 
 |  | ||||||
| 	node->last = false; | 	node->last = false; | ||||||
| 
 | 
 | ||||||
| 	// insert excess node to free list
 | 	// insert excess node to free list
 | ||||||
|  | @ -196,29 +184,6 @@ static void* allocate_from_pool(size_t pool_index, size_t size) | ||||||
| 
 | 
 | ||||||
| static malloc_node_t* node_from_data_pointer(void* data_pointer) | static malloc_node_t* node_from_data_pointer(void* data_pointer) | ||||||
| { | { | ||||||
| 	if (((uint8_t*)data_pointer)[-1]) |  | ||||||
| 	{ |  | ||||||
| 		malloc_pool_t* pool = nullptr; |  | ||||||
| 		for (size_t i = 0; i < s_malloc_pool_count; i++) |  | ||||||
| 		{ |  | ||||||
| 			if (!s_malloc_pools[i].start) |  | ||||||
| 				continue; |  | ||||||
| 			if (data_pointer < s_malloc_pools[i].start) |  | ||||||
| 				continue; |  | ||||||
| 			if (data_pointer > s_malloc_pools[i].end()) |  | ||||||
| 				continue; |  | ||||||
| 			pool = &s_malloc_pools[i]; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		assert(pool); |  | ||||||
| 
 |  | ||||||
| 		auto* node = (malloc_node_t*)pool->start; |  | ||||||
| 		for (; (uint8_t*)node < pool->end(); node = node->next()) |  | ||||||
| 			if (node->data < data_pointer && data_pointer < node->next()) |  | ||||||
| 				return node; |  | ||||||
| 		assert(false); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return (malloc_node_t*)((uint8_t*)data_pointer - sizeof(malloc_node_t)); | 	return (malloc_node_t*)((uint8_t*)data_pointer - sizeof(malloc_node_t)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -379,16 +344,52 @@ int posix_memalign(void** memptr, size_t alignment, size_t size) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	uint8_t* unaligned = (uint8_t*)malloc(size + alignment); | 	if (alignment < s_malloc_default_align) | ||||||
|  | 		alignment = s_malloc_default_align; | ||||||
|  | 
 | ||||||
|  | 	void* unaligned = malloc(size + alignment + sizeof(malloc_node_t)); | ||||||
| 	if (unaligned == nullptr) | 	if (unaligned == nullptr) | ||||||
| 		return -1; | 		return -1; | ||||||
| 
 | 
 | ||||||
| 	if (auto rem = (uintptr_t)unaligned % alignment) | 	pthread_mutex_lock(&s_malloc_mutex); | ||||||
| 	{ |  | ||||||
| 		unaligned += alignment - rem; |  | ||||||
| 		unaligned[-1] = 1; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	*memptr = unaligned; | 	auto* node = node_from_data_pointer(unaligned); | ||||||
|  | 	auto& pool = pool_from_node(node); | ||||||
|  | 
 | ||||||
|  | // NOTE: gcc does not like accessing the node from pointer returned by malloc
 | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Warray-bounds" | ||||||
|  | 	if (reinterpret_cast<uintptr_t>(unaligned) % alignment) | ||||||
|  | 	{ | ||||||
|  | 		uintptr_t curr_data_address = reinterpret_cast<uintptr_t>(unaligned); | ||||||
|  | 
 | ||||||
|  | 		uintptr_t next_data_address = curr_data_address + sizeof(malloc_node_t); | ||||||
|  | 		if (auto rem = next_data_address % alignment) | ||||||
|  | 			next_data_address += alignment - rem; | ||||||
|  | 
 | ||||||
|  | 		auto* next = node_from_data_pointer(reinterpret_cast<void*>(next_data_address)); | ||||||
|  | 		next->size = reinterpret_cast<uintptr_t>(node->next()) - reinterpret_cast<uintptr_t>(next); | ||||||
|  | 		next->allocated = true; | ||||||
|  | 		assert(next->data_size() >= size); | ||||||
|  | 
 | ||||||
|  | 		node->size = reinterpret_cast<uintptr_t>(next) - reinterpret_cast<uintptr_t>(node); | ||||||
|  | 		node->allocated = false; | ||||||
|  | 
 | ||||||
|  | 		// add node to free list
 | ||||||
|  | 		if (pool.free_list) | ||||||
|  | 			pool.free_list->prev_free = node; | ||||||
|  | 		node->prev_free = nullptr; | ||||||
|  | 		node->next_free = pool.free_list; | ||||||
|  | 		pool.free_list = node; | ||||||
|  | 
 | ||||||
|  | 		node = next; | ||||||
|  | 	} | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  | 
 | ||||||
|  | 	shrink_node_if_needed(pool, node, size); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_unlock(&s_malloc_mutex); | ||||||
|  | 
 | ||||||
|  | 	*memptr = node->data; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue