3 #include <string.h> /* for memset() */
4 #include <time.h> /* for time() in srand() */
10 #define MAX_EPOCHS 20000 /* Maximum number of epochs of simulation */
11 #define MAX_LIFETIME 1000 /* Maximum lifetime of a reserved block */
12 #define MAX_LOGSIZE 5 /* Maximum logarithm of block's size */
13 #define TI 5 /* Every `TI' steps dump statistics */
15 typedef struct simnode
{
17 unsigned int lifetime
;
18 LIST_ENTRY(simnode
) next_node
;
21 LIST_HEAD(simhead
, simnode
);
22 typedef struct simhead simhead_t
;
24 /* Function prototypes */
25 void sim_add_to_list(simhead_t
*simhead
, simnode_t
*simnode
);
26 void sim_free_from_list(mpool_t
*mpool
, simhead_t
*simhead
, unsigned int t
);
27 void sim_print_stats(const mpool_t
*mpool
, unsigned int t
, FILE *fp
);
33 simnode_t simnode
[MAX_EPOCHS
];
34 unsigned int t
, sz
, lt
, S
;
36 /* Initialize memory pool */
37 if (mpool_init(&mpool
, 25, 5) == MPOOL_ENOMEM
) {
38 fprintf(stderr
, "mpool: not enough memory\n");
42 /* Initialize random number generator */
45 /* Initialize simlist */
49 for (t
= 0; t
< MAX_EPOCHS
; t
++) {
50 /* Is it time to dump statistics ? */
52 sim_print_stats(mpool
, t
, stdout
);
55 sim_free_from_list(mpool
, &simhead
, t
);
57 /* Calculate a random size `sz' and a random lifetime `lt' */
58 sz
= 1 << rand() % (1 + MAX_LOGSIZE
);
59 if (t
< (MAX_EPOCHS
- MAX_LIFETIME
))
60 lt
= 1 + rand() % MAX_LIFETIME
;
62 lt
= 1 + rand() % (MAX_EPOCHS
- t
);
63 /*printf("t = %u\tsz = %u\tlt = %u\n", t, sz, lt);*/
65 /* Allocate a block of size `sz' and make it last `lt' time intervals */
66 if ((simnode
[t
].ptr
= mpool_alloc(mpool
, sz
)) == NULL
) {
67 fprintf(stderr
, "mpool: no available block\n");
71 simnode
[t
].lifetime
= t
+ lt
;
73 /* Add block to list, in the proper position */
74 sim_add_to_list(&simhead
, &simnode
[t
]);
77 sim_print_stats(mpool
, t
, stdout
);
79 /* Destroy memory pool and free all resources */
85 void sim_add_to_list(simhead_t
*simhead
, simnode_t
*simnode
)
89 /* LIST_FOREACH(pnode, simhead, next_node) {
90 printf("%u -> ", pnode->lifetime);
95 LIST_FOREACH(pnode
, simhead
, next_node
) {
96 if (simnode
->lifetime
< pnode
->lifetime
) {
97 LIST_INSERT_BEFORE(pnode
, simnode
, next_node
);
100 else if (LIST_NEXT(pnode
, next_node
) == NULL
) {
101 LIST_INSERT_AFTER(pnode
, simnode
, next_node
);
106 /* 1st element goes here */
107 LIST_INSERT_HEAD(simhead
, simnode
, next_node
);
110 void sim_free_from_list(mpool_t
*mpool
, simhead_t
*simhead
, unsigned int t
)
114 LIST_FOREACH(pnode
, simhead
, next_node
) {
115 if (t
== pnode
->lifetime
) {
116 /*printf("freeing %u\tptr = %p\n", t, pnode->ptr);*/
117 mpool_free(mpool
, pnode
->ptr
);
118 LIST_REMOVE(pnode
, next_node
);
125 void sim_print_stats(const mpool_t
*mpool
, unsigned int t
, FILE *fp
)
127 size_t an
, un
; /* nodes */
128 size_t ab
, ub
; /* blocks */
129 size_t me
, sp
; /* merges, splits */
132 mpool_stat_get_nodes(mpool
, &an
, &un
);
133 mpool_stat_get_bytes(mpool
, &ab
, &ub
);
134 me
= mpool_stat_get_merges(mpool
);
135 sp
= mpool_stat_get_splits(mpool
);
137 fprintf(fp
, "%u\t%u\t%u\t%.2f\t%u\t%u\t%.2f\t%u\t%u\t%.2f\n",
138 t
, an
, un
, 100.0 * an
/ (an
+ un
), ab
, ub
, 100.0 * ab
/ (ab
+ ub
), sp
, me
, 10.0*sp
/(1+me
));
140 /* Print length of every block
141 for (i = 0; i < mpool_stat_get_blocks(mpool); i++)
142 fprintf(fp, "%u\t", mpool_stat_get_block_length(mpool, i));
146 fprintf(fp, "avail nodes = %u\tused nodes = %u\tfree(%%) = %f\n", an, un, 100.0 * an / (an + un));
147 fprintf(fp, "avail bytes = %u\tused bytes = %u\tfree(%%) = %f\n", ab, ub, 100.0 * ab / (ab + ub));
148 fprintf(fp, "splits = %u\tmerges = %u\n", sp, me);