Last active
December 25, 2015 19:49
-
-
Save semahawk/7030646 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* alloc.c | |
* | |
* Created at: Thu 17 Oct 2013 17:23:59 CEST 17:23:59 | |
* | |
* Author: Szymon Urbaś <[email protected]> | |
* | |
* License: the MIT license | |
* | |
* Description: In this program I'm trying to implement the 'one big malloc' (as | |
* opposed to 'many small mallocs'). | |
* | |
* One malloc/free instead of POOLSZ many, now that's what's called | |
* optimization. | |
* | |
* Nemo will use that knowledge aqquired here. | |
* Because, suprisingly, this is actually working. | |
* | |
* Update: Now there are two different 'object' types (of different sizes) that | |
* are supported. Aaand it still works, which is nice. | |
* | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#define POOL_SIZE 20 | |
/* the base of the two different 'objects' */ | |
struct base { | |
char id; /* 1 byte */ | |
}; | |
struct integer { | |
struct base base; /* 1 byte */ | |
short i; /* 2 bytes */ | |
}; /* total: 3 bytes */ | |
struct floating { | |
struct base base; /* 1 byte */ | |
double f; /* 8 bytes */ | |
}; /* total: 9 bytes */ | |
/* pointer to the malloced block of memory */ | |
static void *pool; | |
/* pointer to the current element in the pool */ | |
static void *curr; | |
/* the current 'id', pretty much not essential to the program */ | |
static int id; | |
/* | |
* Short and simple. This two functions pretend to be the new 'malloc'. | |
* There's two separate functions for each 'object' kind. | |
* | |
* Some optimizations may follow, but for now I'm KISSing it. | |
*/ | |
struct integer *new_integer(short i) | |
{ | |
void *save = curr; | |
((struct integer *)curr)->base.id = id + 97; | |
((struct integer *)curr)->i = i; | |
curr += sizeof(struct integer); | |
id++; | |
return (struct integer *)save; | |
} | |
struct floating *new_floating(double f) | |
{ | |
void *save = curr; | |
((struct floating *)curr)->base.id = id + 97; | |
((struct floating *)curr)->f = f; | |
curr += sizeof(struct floating); | |
id++; | |
return (struct floating *)save; | |
} | |
int main(void) | |
{ | |
/* a few dummy 'objects' */ | |
struct integer *five, *seven; | |
struct floating *pi, *e; | |
/* initialize the pool */ | |
pool = malloc(sizeof(void *) * POOL_SIZE); | |
if (!pool){ | |
fprintf(stderr, "malloc failed\n"); | |
return 1; | |
} | |
/* set 'curr' to the first 'object' in the pool */ | |
curr = pool; | |
/* 'malloc' the first 'object' */ | |
five = new_integer(5); | |
/* same for the second */ | |
pi = new_floating(3.14); | |
/* and for the third one */ | |
e = new_floating(2.71); | |
/* aaaaand the last one */ | |
seven = new_integer(7); | |
/* make sure it actually works, and that the struct members are accessible */ | |
assert(five->i == 5); | |
assert(pi->f == 3.14); | |
assert(e->f == 2.71); | |
assert(seven->i == 7); | |
/* some debugging info */ | |
printf("pool's place in the memory: %p\n", (void *)pool); | |
printf("sizeof(struct integer): %lu, sizeof(struct floating): %lu\n\n", sizeof(struct integer), sizeof(struct floating)); | |
printf("%p id %c: five: %d\n", (void *)five, five->base.id, five->i); | |
printf("%p id %c: pi: %g\n", (void *)pi, pi->base.id, pi->f); | |
printf("%p id %c: e: %g\n", (void *)e, e->base.id, e->f); | |
printf("%p id %c: seven: %d\n", (void *)seven, seven->base.id, seven->i); | |
printf("\ncurr ended up pointing to %p\n", (void *)curr); | |
/* release the <s>kraken</s> memory */ | |
free(pool); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment