Change error namespace from MP_* to MPOOL_*
[eleutheria.git] / malloc / test.c
blob14ef4b7053741f91f1f62b83ac7b426d49e428b6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h> /* for memset() */
4 #include <time.h> /* for time() in srand() */
5 #include <sys/queue.h>
7 #include "mpool.h"
9 #define MAX_EPOCHS 20000 /* Maximum number of epochs of simulation */
10 #define MAX_LIFETIME 1000 /* Maximum lifetime of a reserved block */
11 #define MAX_LOGSIZE 5 /* Maximum logarithm of block's size */
12 #define TI 5 /* Every `TI' steps dump statistics */
14 typedef struct simnode {
15 void *ptr;
16 unsigned int lifetime;
17 LIST_ENTRY(simnode) next_node;
18 } simnode_t;
20 LIST_HEAD(simhead, simnode);
21 typedef struct simhead simhead_t;
23 /* Function prototypes */
24 void sim_add_to_list(simhead_t *simhead, simnode_t *simnode);
25 void sim_free_from_list(mpool_t *mpool, simhead_t *simhead, unsigned int t);
26 void sim_print_stats(const mpool_t *mpool, unsigned int t, FILE *fp);
28 int main(void)
30 mpool_t *mpool;
31 simhead_t simhead;
32 simnode_t simnode[MAX_EPOCHS];
33 unsigned int t, sz, lt, S;
35 /* Initialize random number generator */
36 srand(time(NULL));
38 /* Initialize memory pool */
39 if (mpool_init(&mpool, 25, 5) == MPOOL_ENOMEM) {
40 fprintf(stderr, "Not enough memory\n");
41 exit(EXIT_FAILURE);
45 p[0] = mpool_alloc(mpool, 50);
46 p[1] = mpool_alloc(mpool, 64-20);
47 mpool_free(mpool, p[1]);
48 mpool_free(mpool, p[0]);
49 exit(1);
52 char *p[1000];
53 for (t = 0; t < 1000; t++) {
54 p[t] = mpool_alloc(mpool, S = ((1 << (5 + rand() % 7)) - 20));
55 if (p[t] == NULL) {
56 fprintf(stderr, "No block available\n");
57 exit(EXIT_FAILURE);
59 memset(p[t], 0, S);
61 for (t = 0; t < 1000; t++)
62 mpool_free(mpool, p[t]);
64 sim_print_stats(mpool, 0, stdout);
65 mpool_destroy(mpool);
67 exit(EXIT_SUCCESS);
69 /* Initialize simlist */
70 LIST_INIT(&simhead);
72 /* Run simulation */
73 for (t = 0; t < MAX_EPOCHS; t++) {
74 /* Is it time to dump statistics ? */
75 if (t % TI == 0)
76 sim_print_stats(mpool, t, stdout);
78 /* */
79 sim_free_from_list(mpool, &simhead, t);
81 /* Calculate a random size `sz' and a random lifetime `lt' */
82 sz = 1 << rand() % (1 + MAX_LOGSIZE);
83 if (t < (MAX_EPOCHS - MAX_LIFETIME))
84 lt = 1 + rand() % MAX_LIFETIME;
85 else
86 lt = 1 + rand() % (MAX_EPOCHS - t);
87 /*printf("t = %u\tsz = %u\tlt = %u\n", t, sz, lt);*/
89 /* Allocate a block of size `sz' and make it last `lt' time intervals */
90 if ((simnode[t].ptr = mpool_alloc(mpool, sz)) == NULL) {
91 fprintf(stderr, "mpool: no available block\n");
92 mpool_destroy(mpool);
93 exit(EXIT_FAILURE);
95 simnode[t].lifetime = t + lt;
97 /* Add block to list, in the proper position */
98 sim_add_to_list(&simhead, &simnode[t]);
101 sim_print_stats(mpool, t, stdout);
103 /* Destroy memory pool and free all resources */
104 mpool_destroy(mpool);
106 return EXIT_SUCCESS;
109 void sim_add_to_list(simhead_t *simhead, simnode_t *simnode)
111 simnode_t *pnode;
113 /* LIST_FOREACH(pnode, simhead, next_node) {
114 printf("%u -> ", pnode->lifetime);
116 printf("\n");
119 LIST_FOREACH(pnode, simhead, next_node) {
120 if (simnode->lifetime < pnode->lifetime) {
121 LIST_INSERT_BEFORE(pnode, simnode, next_node);
122 return;
124 else if (LIST_NEXT(pnode, next_node) == NULL) {
125 LIST_INSERT_AFTER(pnode, simnode, next_node);
126 return;
130 /* 1st element goes here */
131 LIST_INSERT_HEAD(simhead, simnode, next_node);
134 void sim_free_from_list(mpool_t *mpool, simhead_t *simhead, unsigned int t)
136 simnode_t *pnode;
138 LIST_FOREACH(pnode, simhead, next_node) {
139 if (t == pnode->lifetime) {
140 /*printf("freeing %u\tptr = %p\n", t, pnode->ptr);*/
141 mpool_free(mpool, pnode->ptr);
142 LIST_REMOVE(pnode, next_node);
144 else
145 return;
149 void sim_print_stats(const mpool_t *mpool, unsigned int t, FILE *fp)
151 size_t an, un; /* nodes */
152 size_t ab, ub; /* blocks */
153 size_t me, sp; /* merges, splits */
154 size_t i;
156 mpool_stat_get_nodes(mpool, &an, &un);
157 mpool_stat_get_bytes(mpool, &ab, &ub);
158 me = mpool_stat_get_merges(mpool);
159 sp = mpool_stat_get_splits(mpool);
161 fprintf(fp, "%u\t%u\t%u\t%.2f\t%u\t%u\t%.2f\t%u\t%u\t%.2f\n",
162 t, an, un, 100.0 * an / (an + un), ab, ub, 100.0 * ab / (ab + ub), sp, me, 10.0*sp/(1+me));
164 /* Print length of every block
165 for (i = 0; i < mpool_stat_get_blocks(mpool); i++)
166 fprintf(fp, "%u\t", mpool_stat_get_block_length(mpool, i));
167 fprintf(fp, "\n");*/
170 fprintf(fp, "avail nodes = %u\tused nodes = %u\tfree(%%) = %f\n", an, un, 100.0 * an / (an + un));
171 fprintf(fp, "avail bytes = %u\tused bytes = %u\tfree(%%) = %f\n", ab, ub, 100.0 * ab / (ab + ub));
172 fprintf(fp, "splits = %u\tmerges = %u\n", sp, me);