OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [libmem/] [tests/] [test_alloc_generic.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Generic random allocation/deallocation test
3
 *
4
 * Copyright 2007 (C) Bahadir Balban
5
 *
6
 */
7
#include <l4/macros.h>
8
#include <l4/config.h>
9
#include <l4/types.h>
10
#include INC_GLUE(memory.h)
11
 
12
#include <l4/lib/list.h>
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <time.h>
16
#include <string.h>
17
#include "test_alloc_generic.h"
18
#include "debug.h"
19
 
20
void print_test_state(unsigned int title,
21
                      print_alloc_state_t print_allocator_state)
22
{
23
        switch (title) {
24
                case TEST_STATE_BEGIN:
25
                        printf("=================\n"
26
                                "===== BEGIN =====\n"
27
                                "=================\n\n");
28
                        break;
29
                case TEST_STATE_MIDDLE:
30
                        printf("==================\n"
31
                                "===== MIDDLE =====\n"
32
                                "==================\n\n");
33
                        break;
34
                case TEST_STATE_END:
35
                        printf("===========\n"
36
                                "=== END ===\n"
37
                                "===========\n\n");
38
                        break;
39
                case TEST_STATE_ERROR:
40
                        printf("=================\n"
41
                                "===== ERROR =====\n"
42
                                "=================\n\n");
43
                        break;
44
                default:
45
                        printf("Title error.\n");
46
        }
47
        print_allocator_state();
48
}
49
 
50
void get_output_filepaths(FILE **out1, FILE **out2,
51
                          char *alloc_func_name)
52
{
53
        char pathbuf[150];
54
        char *rootpath = "/tmp/";
55
        char *initstate_prefix = "test_initstate_";
56
        char *endstate_prefix = "test_endstate_";
57
        char *extention = ".out";
58
 
59
        /* File path manipulations */
60
        sprintf(pathbuf, "%s%s%s%s", rootpath, initstate_prefix, alloc_func_name, extention);
61
        *out1 = fopen(pathbuf,"w+");
62
        sprintf(pathbuf, "%s%s%s%s", rootpath, endstate_prefix, alloc_func_name, extention);
63
        *out2 = fopen(pathbuf, "w+");
64
        return;
65
}
66
 
67
/* This function is at the heart of generic random allocation testing.
68
 * It is made as simple as possible, and can be used for testing all
69
 * allocators. It randomly allocates/deallocates data and prints out
70
 * the outcome of the action. Here are a few things it does and doesn't
71
 * do:
72
 * - It does not test false input on the allocators, e.g. attempting
73
 *   to free an address that hasn't been allocated, or attempting to
74
 *   free address 0.
75
 * - It does capture and compare initial and final states of the
76
 *   allocators' internal structures after all allocations are freed.
77
 *   This is done by comparing two files filled with allocator state
78
 *   by functions supplied by the allocators themselves.
79
 * - It expects the allocator NOT to run out of memory.
80
 */
81
int
82
test_alloc_free_random_order(const int MAX_ALLOCATIONS,
83
                             const int ALLOC_SIZE_MAX,
84
                             alloc_func_t alloc,
85
                             free_func_t free,
86
                             print_alloc_state_t print_allocator_state,
87
                             FILE *state_init_file, FILE *state_end_file)
88
{
89
        /* The last element in full_state that tells about any full index.
90
         * This is the limit the random deallocation would use to find a full
91
         * index */
92
        int random_size;
93
        int random_action;
94
        int random_index;
95
        int alloc_so_far = 0;
96
        int full_state_last = -1;
97
        int halfway_through = 0;
98
        FILE * const default_stdout = stdout;
99
        /* Memory pointers */
100
        void *mem[MAX_ALLOCATIONS];
101
        /* Each element keeps track of one currently full index number */
102
        int full_state[MAX_ALLOCATIONS];
103
 
104
        /* Check arguments first */
105
        if (!MAX_ALLOCATIONS || !ALLOC_SIZE_MAX || !alloc || !free
106
            || !print_allocator_state || !state_init_file || !state_end_file) {
107
                printf("Invalid arguments to %s()\n", __FUNCTION__);
108
                return 1;
109
        }
110
        memset(mem, 0, MAX_ALLOCATIONS * sizeof(void *));
111
        memset(full_state, 0, MAX_ALLOCATIONS * sizeof(int));
112
 
113
        //print_test_state(TEST_STATE_BEGIN, print_allocator_state);
114
        stdout = state_init_file;
115
        print_test_state(TEST_STATE_BEGIN, print_allocator_state);
116
        stdout = default_stdout;
117
 
118
        /* Randomly either allocate/deallocate at a random
119
         * index, of random size */
120
        srand(time(0));
121
 
122
        while (1) {
123
                if (alloc_so_far < (MAX_ALLOCATIONS / 2)) {
124
                        /* Give more chance to allocations at the beginning */
125
                        if ((rand() % 4) == 0)   /* 1/4 chance */
126
                                random_action = FREE;
127
                        else                    /* 3/4 chance */
128
                                random_action = ALLOCATE;
129
                } else {
130
                        if (!halfway_through) {
131
#if defined (DEBUG)
132
                                        print_test_state(TEST_STATE_MIDDLE,
133
                                                         print_allocator_state);
134
#endif
135
                                halfway_through = 1;
136
                        }
137
                        /* Give more chane to freeing after halfway-through */
138
                        if ((rand() % 3) == 0)  /* 1/3 chance */
139
                                random_action = ALLOCATE;
140
                        else                    /* 2/3 chance */
141
                                random_action = FREE;
142
                }
143
                random_size = (rand() % (ALLOC_SIZE_MAX-1)) + 1;
144
 
145
                if (random_action == ALLOCATE) {
146
                        if (alloc_so_far < MAX_ALLOCATIONS) {
147
                                alloc_so_far++;
148
                                for (int i = 0; i < MAX_ALLOCATIONS; i++) {
149
                                        if (mem[i] == 0) {                       // Find the first empty slot.
150
                                                int allocation_error =
151
                                                        ((mem[i] = alloc(random_size)) <= 0);
152
                                                dprintf("%-12s%-8s%-12p%-8s%-10d\n",
153
                                                       "alloc:", "addr:", mem[i],
154
                                                       "size:", random_size);
155
                                                if (allocation_error) {
156
                                                        print_test_state(TEST_STATE_ERROR,
157
                                                                         print_allocator_state);
158
                                                        if (mem[i] < 0) {
159
                                                                printf("Error: alloc() returned negative value\n");
160
                                                                BUG();
161
                                                        } else if (mem[i] == 0) {
162
                                                                printf("Error: Allocator is out of memory.\n");
163
                                                                return 1;
164
                                                        }
165
                                                }
166
                                                full_state_last++;
167
                                                full_state[full_state_last] = i;
168
                                                break;
169
                                        }
170
                                }
171
                        } else
172
                                random_action = FREE;
173
                }
174
 
175
                if (random_action == FREE) {
176
                        /* all are free, can't free anymore */
177
                        if (full_state_last < 0)
178
                                continue;
179
                        else if (full_state_last > 0)
180
                                random_index = rand() % full_state_last;
181
                        else
182
                                random_index = 0; /* Last item */
183
 
184
                        if(mem[full_state[random_index]] == 0)
185
                                BUG();
186
 
187
                        if (free(mem[full_state[random_index]]) < 0)
188
                                BUG();
189
                        dprintf("%-12s%-8s%-12p\n","free:",
190
                               "addr:",  mem[full_state[random_index]]);
191
                        mem[full_state[random_index]] = 0;
192
 
193
                        /* Fill in the empty gap with last element */
194
                        full_state[random_index] = full_state[full_state_last];
195
                        /* Last element now in the gap
196
                         * (somewhere inbetween first and last) */
197
                        full_state[full_state_last] = 0;
198
                        /* One less in the number of full items */
199
                        full_state_last--;
200
                }
201
 
202
                /* Check that all allocations and deallocations took place */
203
                if (alloc_so_far == MAX_ALLOCATIONS && full_state_last < 0) {
204
                        for (int i = 0; i < MAX_ALLOCATIONS; i++)
205
                                BUG_ON(full_state[i] != 0);              // A final sanity check.
206
                        break;
207
                }
208
        }
209
 
210
        //print_test_state(TEST_STATE_END, print_allocator_state);
211
        stdout = state_end_file;
212
        print_test_state(TEST_STATE_BEGIN, print_allocator_state);
213
        stdout = default_stdout;
214
        return 0;
215
}
216
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.