YAPC::EU 2018 Glasgow Update!
This commit is contained in:
parent
22f33d4004
commit
4e2d22a71d
1170 changed files with 15042 additions and 3047 deletions
142
Task/Arena-storage-pool/C/arena-storage-pool-7.c
Normal file
142
Task/Arena-storage-pool/C/arena-storage-pool-7.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// VERY rudimentary C memory management independent of C library's malloc.
|
||||
|
||||
// Linked list (yes, this is inefficient)
|
||||
struct __ALLOCC_ENTRY__
|
||||
{
|
||||
void * allocatedAddr;
|
||||
size_t size;
|
||||
struct __ALLOCC_ENTRY__ * next;
|
||||
};
|
||||
typedef struct __ALLOCC_ENTRY__ __ALLOCC_ENTRY__;
|
||||
|
||||
// Keeps track of allocated memory and metadata
|
||||
__ALLOCC_ENTRY__ * __ALLOCC_ROOT__ = NULL;
|
||||
__ALLOCC_ENTRY__ * __ALLOCC_TAIL__ = NULL;
|
||||
|
||||
// Add new metadata to the table
|
||||
void _add_mem_entry(void * location, size_t size)
|
||||
{
|
||||
|
||||
__ALLOCC_ENTRY__ * newEntry = (__ALLOCC_ENTRY__ *) mmap(NULL, sizeof(__ALLOCC_ENTRY__), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
if (__ALLOCC_TAIL__ != NULL)
|
||||
{
|
||||
__ALLOCC_TAIL__ -> next = newEntry;
|
||||
__ALLOCC_TAIL__ = __ALLOCC_TAIL__ -> next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create new table
|
||||
__ALLOCC_ROOT__ = newEntry;
|
||||
__ALLOCC_TAIL__ = newEntry;
|
||||
}
|
||||
|
||||
__ALLOCC_ENTRY__ * tail = __ALLOCC_TAIL__;
|
||||
tail -> allocatedAddr = location;
|
||||
tail -> size = size;
|
||||
tail -> next = NULL;
|
||||
__ALLOCC_TAIL__ = tail;
|
||||
}
|
||||
|
||||
// Remove metadata from the table given pointer
|
||||
size_t _remove_mem_entry(void * location)
|
||||
{
|
||||
__ALLOCC_ENTRY__ * curNode = __ALLOCC_ROOT__;
|
||||
|
||||
// Nothing to do
|
||||
if (curNode == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// First entry matches
|
||||
if (curNode -> allocatedAddr == location)
|
||||
{
|
||||
__ALLOCC_ROOT__ = curNode -> next;
|
||||
size_t chunkSize = curNode -> size;
|
||||
|
||||
// No nodes left
|
||||
if (__ALLOCC_ROOT__ == NULL)
|
||||
{
|
||||
__ALLOCC_TAIL__ = NULL;
|
||||
}
|
||||
munmap(curNode, sizeof(__ALLOCC_ENTRY__));
|
||||
|
||||
return chunkSize;
|
||||
}
|
||||
|
||||
// If next node is null, remove it
|
||||
while (curNode -> next != NULL)
|
||||
{
|
||||
__ALLOCC_ENTRY__ * nextNode = curNode -> next;
|
||||
|
||||
if (nextNode -> allocatedAddr == location)
|
||||
{
|
||||
size_t chunkSize = nextNode -> size;
|
||||
|
||||
if(curNode -> next == __ALLOCC_TAIL__)
|
||||
{
|
||||
__ALLOCC_TAIL__ = curNode;
|
||||
}
|
||||
curNode -> next = nextNode -> next;
|
||||
munmap(nextNode, sizeof(__ALLOCC_ENTRY__));
|
||||
|
||||
return chunkSize;
|
||||
}
|
||||
|
||||
curNode = nextNode;
|
||||
}
|
||||
|
||||
// Nothing was found
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate a block of memory with size
|
||||
// When customMalloc an already mapped location, causes undefined behavior
|
||||
void * customMalloc(size_t size)
|
||||
{
|
||||
// Now we can use 0 as our error state
|
||||
if (size == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * mapped = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
// Store metadata
|
||||
_add_mem_entry(mapped, size);
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
// Free a block of memory that has been customMalloc'ed
|
||||
void customFree(void * addr)
|
||||
{
|
||||
size_t size = _remove_mem_entry(addr);
|
||||
|
||||
munmap(addr, size);
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int *p1 = customMalloc(4*sizeof(int)); // allocates enough for an array of 4 int
|
||||
int *p2 = customMalloc(sizeof(int[4])); // same, naming the type directly
|
||||
int *p3 = customMalloc(4*sizeof *p3); // same, without repeating the type name
|
||||
|
||||
if(p1) {
|
||||
for(int n=0; n<4; ++n) // populate the array
|
||||
p1[n] = n*n;
|
||||
for(int n=0; n<4; ++n) // print it back out
|
||||
printf("p1[%d] == %d\n", n, p1[n]);
|
||||
}
|
||||
|
||||
customFree(p1);
|
||||
customFree(p2);
|
||||
customFree(p3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue