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

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [glue/] [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 2005 (C) Bahadir Balban
5
 *
6
 */
7
#include <macros.h>
8
#include <config.h>
9
#include INC_GLUE(memory.h)
10
 
11
#include <lib/printk.h>
12
#include <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
        memset(mem, 0, MAX_ALLOCATIONS * sizeof(void *));
105
        memset(full_state, 0, MAX_ALLOCATIONS * sizeof(int));
106
 
107
        print_test_state(TEST_STATE_BEGIN, print_allocator_state);
108
        stdout = state_init_file;
109
        print_test_state(TEST_STATE_BEGIN, print_allocator_state);
110
        stdout = default_stdout;
111
 
112
        /* Randomly either allocate/deallocate at a random
113
         * index, of random size */
114
        srand(time(0));
115
 
116
        /* Constraints */
117
        while (1) {
118
                if (alloc_so_far < (MAX_ALLOCATIONS / 2)) {
119
                        /* Give more chance to allocations at the beginning */
120
                        if ((rand() % 4) == 0)   /* 1/4 chance */
121
                                random_action = FREE;
122
                        else                    /* 3/4 chance */
123
                                random_action = ALLOCATE;
124
                } else {
125
                        if (!halfway_through) {
126
                                print_test_state(TEST_STATE_MIDDLE,
127
                                                 print_allocator_state);
128
                                halfway_through = 1;
129
                        }
130
                        /* Give more chane to freeing after halfway-through */
131
                        if ((rand() % 3) == 0)  /* 1/3 chance */
132
                                random_action = ALLOCATE;
133
                        else                    /* 2/3 chance */
134
                                random_action = FREE;
135
                }
136
                random_size = (rand() % (ALLOC_SIZE_MAX-1)) + 1;
137
 
138
                if (random_action == ALLOCATE) {
139
                        if (alloc_so_far < MAX_ALLOCATIONS) {
140
                                alloc_so_far++;
141
                                for (int i = 0; i < MAX_ALLOCATIONS; i++) {
142
                                        if (mem[i] == 0) {
143
                                                int allocation_error =
144
                                                        ((mem[i] = alloc(random_size)) <= 0);
145
                                                printf("%-12s%-8s%-12p%-8s%-10d\n",
146
                                                       "alloc:", "addr:", mem[i],
147
                                                       "size:", random_size);
148
                                                if (allocation_error) {
149
                                                        print_test_state(TEST_STATE_ERROR,
150
                                                                         print_allocator_state);
151
                                                        if (mem[i] < 0) {
152
                                                                printf("Error: alloc() returned negative value\n");
153
                                                                BUG();
154
                                                        } else if (mem[i] == 0) {
155
                                                                printf("Error: Allocator is out of memory.\n");
156
                                                                return 1;
157
                                                        }
158
                                                }
159
                                                full_state_last++;
160
                                                full_state[full_state_last] = i;
161
                                                break;
162
                                        }
163
                                }
164
                        } else
165
                                random_action = FREE;
166
                }
167
 
168
                if (random_action == FREE) {
169
                        /* all are free, can't free anymore */
170
                        if (full_state_last < 0)
171
                                continue;
172
                        else if (full_state_last > 0)
173
                                random_index = rand() % full_state_last;
174
                        else
175
                                random_index = 0; /* Last item */
176
 
177
                        if(mem[full_state[random_index]] == 0)
178
                                BUG();
179
 
180
                        free(mem[full_state[random_index]]);
181
                        printf("%-12s%-8s%-12p\n","free:",
182
                               "addr:",  mem[full_state[random_index]]);
183
                        mem[full_state[random_index]] = 0;
184
 
185
                        /* Fill in the empty gap with last element */
186
                        full_state[random_index] = full_state[full_state_last];
187
                        /* Last element now in the gap
188
                         * (somewhere inbetween first and last) */
189
                        full_state[full_state_last] = 0;
190
                        /* One less in the number of full items */
191
                        full_state_last--;
192
                }
193
 
194
                /* Check that all allocations and deallocations took place */
195
                if (alloc_so_far == MAX_ALLOCATIONS && full_state_last < 0)
196
                        break;
197
        }
198
 
199
        print_test_state(TEST_STATE_END, print_allocator_state);
200
        stdout = state_end_file;
201
        print_test_state(TEST_STATE_BEGIN, print_allocator_state);
202
        stdout = default_stdout;
203
        return 0;
204
}
205
 

powered by: WebSVN 2.1.0

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