3 #include <string.h> /* for memset() */
4 #include <time.h> /* for time() in srand() */
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
{
16 unsigned int lifetime
;
17 LIST_ENTRY(simnode
) next_node
;
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
);
32 simnode_t simnode
[MAX_EPOCHS
];
33 unsigned int t
, sz
, lt
, S
;
35 /* Initialize random number generator */
38 /* Initialize memory pool */
39 if (mpool_init(&mpool
, 25, 5) == MPOOL_ENOMEM
) {
40 fprintf(stderr
, "Not enough memory\n");
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]);
53 for (t
= 0; t
< 1000; t
++) {
54 p
[t
] = mpool_alloc(mpool
, S
= ((1 << (5 + rand() % 7)) - 20));
56 fprintf(stderr
, "No block available\n");
61 for (t
= 0; t
< 1000; t
++)
62 mpool_free(mpool
, p
[t
]);
64 sim_print_stats(mpool
, 0, stdout
);
69 /* Initialize simlist */
73 for (t
= 0; t
< MAX_EPOCHS
; t
++) {
74 /* Is it time to dump statistics ? */
76 sim_print_stats(mpool
, t
, stdout
);
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
;
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");
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
);
109 void sim_add_to_list(simhead_t
*simhead
, simnode_t
*simnode
)
113 /* LIST_FOREACH(pnode, simhead, next_node) {
114 printf("%u -> ", pnode->lifetime);
119 LIST_FOREACH(pnode
, simhead
, next_node
) {
120 if (simnode
->lifetime
< pnode
->lifetime
) {
121 LIST_INSERT_BEFORE(pnode
, simnode
, next_node
);
124 else if (LIST_NEXT(pnode
, next_node
) == NULL
) {
125 LIST_INSERT_AFTER(pnode
, simnode
, next_node
);
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
)
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
);
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 */
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));
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);