~ubuntu-branches/ubuntu/wily/aspectc++/wily

« back to all changes in this revision

Viewing changes to Puma/src/win32/ptmalloc/t-test1.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2005-12-23 10:49:40 UTC
  • Revision ID: james.westby@ubuntu.com-20051223104940-ig4klhoi991zs7km
Tags: upstream-0.99+1.0pre2
ImportĀ upstreamĀ versionĀ 0.99+1.0pre2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: t-test1.c,v 1.1.1.1 2003/07/02 16:32:09 matthias.urban Exp $
 
3
 * by Wolfram Gloger 1996-1999
 
4
 * A multi-thread test for malloc performance, maintaining one pool of
 
5
 * allocated bins per thread.
 
6
 */
 
7
 
 
8
#include "thread-m.h"
 
9
 
 
10
#if USE_PTHREADS /* Posix threads */
 
11
 
 
12
#include <pthread.h>
 
13
 
 
14
pthread_cond_t finish_cond = PTHREAD_COND_INITIALIZER;
 
15
pthread_mutex_t finish_mutex = PTHREAD_MUTEX_INITIALIZER;
 
16
 
 
17
#endif
 
18
 
 
19
#if (defined __STDC__ && __STDC__) || defined __cplusplus
 
20
# include <stdlib.h>
 
21
#endif
 
22
#include <stdio.h>
 
23
#include <unistd.h>
 
24
#include <sys/types.h>
 
25
#include <sys/time.h>
 
26
#include <sys/resource.h>
 
27
#include <sys/wait.h>
 
28
 
 
29
#if !USE_MALLOC
 
30
#include <malloc.h>
 
31
#else
 
32
#include "ptmalloc.h"
 
33
#endif
 
34
 
 
35
#include "lran2.h"
 
36
#include "t-test.h"
 
37
 
 
38
#define N_TOTAL         10
 
39
#ifndef N_THREADS
 
40
#define N_THREADS       2
 
41
#endif
 
42
#ifndef N_TOTAL_PRINT
 
43
#define N_TOTAL_PRINT 50
 
44
#endif
 
45
#define STACKSIZE       32768
 
46
#ifndef MEMORY
 
47
#define MEMORY          8000000l
 
48
#endif
 
49
#define SIZE            10000
 
50
#define I_MAX           10000
 
51
#define ACTIONS_MAX     30
 
52
 
 
53
#define RANDOM(d,s)     (lran2(d) % (s))
 
54
 
 
55
struct bin_info {
 
56
        struct bin *m;
 
57
        unsigned long size, bins;
 
58
};
 
59
 
 
60
#if TEST > 0
 
61
 
 
62
void
 
63
bin_test(struct bin_info *p)
 
64
{
 
65
        int b;
 
66
 
 
67
        for(b=0; b<p->bins; b++) {
 
68
                if(mem_check(p->m[b].ptr, p->m[b].size)) {
 
69
                        printf("memory corrupt!\n");
 
70
                        exit(1);
 
71
                }
 
72
        }
 
73
}
 
74
 
 
75
#endif
 
76
 
 
77
struct thread_st {
 
78
        int bins, max, flags;
 
79
        unsigned long size;
 
80
        thread_id id;
 
81
        char *sp;
 
82
        long seed;
 
83
};
 
84
 
 
85
#if USE_PTHREADS || USE_THR || defined NO_THREADS
 
86
void *
 
87
malloc_test(void *ptr)
 
88
#else
 
89
void
 
90
malloc_test(void *ptr, size_t stack_len)
 
91
#endif
 
92
{
 
93
        struct thread_st *st = ptr;
 
94
        int b, i, j, actions, pid = 1;
 
95
        struct bin_info p;
 
96
        struct lran2_st ld; /* data for random number generator */
 
97
 
 
98
        lran2_init(&ld, st->seed);
 
99
#ifdef TEST_FORK
 
100
        if(RANDOM(&ld, TEST_FORK) == 0) {
 
101
                int status;
 
102
 
 
103
                printf("forking\n");
 
104
                pid = fork();
 
105
                if(pid > 0) {
 
106
                        printf("waiting for %d...\n", pid);
 
107
                        waitpid(pid, &status, 0);
 
108
                        if(!WIFEXITED(status)) {
 
109
                                printf("child term with signal %d\n", WTERMSIG(status));
 
110
                        }
 
111
                        goto end;
 
112
                }
 
113
        }
 
114
#endif
 
115
        p.m = (struct bin *)malloc(st->bins*sizeof(*p.m));
 
116
        p.bins = st->bins;
 
117
        p.size = st->size;
 
118
        for(b=0; b<p.bins; b++) {
 
119
                p.m[b].size = 0;
 
120
                p.m[b].ptr = NULL;
 
121
                if(RANDOM(&ld, 2) == 0)
 
122
                        bin_alloc(&p.m[b], RANDOM(&ld, p.size) + 1, lran2(&ld));
 
123
        }
 
124
        for(i=0; i<=st->max;) {
 
125
#if TEST > 1
 
126
                bin_test(&p);
 
127
#endif
 
128
                actions = RANDOM(&ld, ACTIONS_MAX);
 
129
#if USE_MALLOC && MALLOC_DEBUG
 
130
                if(actions < 2) { mallinfo(); }
 
131
#endif
 
132
                for(j=0; j<actions; j++) {
 
133
                        b = RANDOM(&ld, p.bins);
 
134
                        bin_free(&p.m[b]);
 
135
                }
 
136
                i += actions;
 
137
                actions = RANDOM(&ld, ACTIONS_MAX);
 
138
                for(j=0; j<actions; j++) {
 
139
                        b = RANDOM(&ld, p.bins);
 
140
                        bin_alloc(&p.m[b], RANDOM(&ld, p.size) + 1, lran2(&ld));
 
141
#if TEST > 2
 
142
                        bin_test(&p);
 
143
#endif
 
144
                }
 
145
#if 0 /* Test illegal free()s while setting MALLOC_CHECK_ */
 
146
                for(j=0; j<8; j++) {
 
147
                        b = RANDOM(&ld, p.bins);
 
148
                        if(p.m[b].ptr) {
 
149
                          int offset = (RANDOM(&ld, 11) - 5)*8;
 
150
                          char *rogue = (char*)(p.m[b].ptr) + offset;
 
151
                          /*printf("p=%p rogue=%p\n", p.m[b].ptr, rogue);*/
 
152
                          free(rogue);
 
153
                        }
 
154
                }
 
155
#endif
 
156
                i += actions;
 
157
        }
 
158
        for(b=0; b<p.bins; b++) bin_free(&p.m[b]);
 
159
        free(p.m);
 
160
#ifdef TEST_FORK
 
161
end:
 
162
#endif
 
163
#if USE_PTHREADS
 
164
        if(pid > 0) {
 
165
                pthread_mutex_lock(&finish_mutex);
 
166
                st->flags = 1;
 
167
                pthread_mutex_unlock(&finish_mutex);
 
168
                pthread_cond_signal(&finish_cond);
 
169
        }
 
170
        return NULL;
 
171
#elif USE_SPROC
 
172
        return;
 
173
#else
 
174
        return NULL;
 
175
#endif
 
176
}
 
177
 
 
178
int
 
179
my_start_thread(struct thread_st *st)
 
180
{
 
181
#if USE_PTHREADS
 
182
        pthread_create(&st->id, NULL, malloc_test, st);
 
183
#elif USE_THR
 
184
        if(!st->sp)
 
185
                st->sp = malloc(STACKSIZE);
 
186
        if(!st->sp) return -1;
 
187
        thr_create(st->sp, STACKSIZE, malloc_test, st, THR_NEW_LWP, &st->id);
 
188
#elif USE_SPROC
 
189
        if(!st->sp)
 
190
                st->sp = malloc(STACKSIZE);
 
191
        if(!st->sp) return -1;
 
192
        st->id = sprocsp(malloc_test, PR_SALL, st, st->sp+STACKSIZE, STACKSIZE);
 
193
        if(st->id < 0) {
 
194
                return -1;
 
195
        }
 
196
#else /* NO_THREADS */
 
197
        st->id = 1;
 
198
        malloc_test(st);
 
199
#endif
 
200
        return 0;
 
201
}
 
202
 
 
203
int n_total=0, n_total_max=N_TOTAL, n_running;
 
204
 
 
205
int
 
206
my_end_thread(struct thread_st *st)
 
207
{
 
208
        /* Thread st has finished.  Start a new one. */
 
209
#if 0
 
210
        printf("Thread %lx terminated.\n", (long)st->id);
 
211
#endif
 
212
        if(n_total >= n_total_max) {
 
213
                n_running--;
 
214
        } else if(st->seed++, my_start_thread(st)) {
 
215
                printf("Creating thread #%d failed.\n", n_total);
 
216
        } else {
 
217
                n_total++;
 
218
                if(n_total%N_TOTAL_PRINT == 0)
 
219
                        printf("n_total = %d\n", n_total);
 
220
        }
 
221
        return 0;
 
222
}
 
223
 
 
224
int
 
225
main(int argc, char *argv[])
 
226
{
 
227
        int i, bins;
 
228
        int n_thr=N_THREADS;
 
229
        int i_max=I_MAX;
 
230
        unsigned long size=SIZE;
 
231
        struct thread_st *st;
 
232
 
 
233
#if USE_MALLOC && !defined(MALLOC_HOOKS) && !defined(__GLIBC__)
 
234
        ptmalloc_init();
 
235
#endif
 
236
        if(argc > 1) n_total_max = atoi(argv[1]);
 
237
        if(n_total_max < 1) n_thr = 1;
 
238
        if(argc > 2) n_thr = atoi(argv[2]);
 
239
        if(n_thr < 1) n_thr = 1;
 
240
        if(n_thr > 100) n_thr = 100;
 
241
        if(argc > 3) i_max = atoi(argv[3]);
 
242
 
 
243
        if(argc > 4) size = atol(argv[4]);
 
244
        if(size < 2) size = 2;
 
245
 
 
246
        bins = MEMORY/(size*n_thr);
 
247
        if(argc > 5) bins = atoi(argv[5]);
 
248
        if(bins < 4) bins = 4;
 
249
 
 
250
#if USE_PTHREADS
 
251
        printf("Using posix threads.\n");
 
252
        pthread_cond_init(&finish_cond, NULL);
 
253
        pthread_mutex_init(&finish_mutex, NULL);
 
254
#elif USE_THR
 
255
        printf("Using Solaris threads.\n");
 
256
#elif USE_SPROC
 
257
        printf("Using sproc() threads.\n");
 
258
#else
 
259
        printf("No threads.\n");
 
260
#endif
 
261
        printf("total=%d threads=%d i_max=%d size=%ld bins=%d\n",
 
262
                   n_total_max, n_thr, i_max, size, bins);
 
263
 
 
264
        st = (struct thread_st *)malloc(n_thr*sizeof(*st));
 
265
        if(!st) exit(-1);
 
266
 
 
267
#if !defined NO_THREADS && defined __sun__
 
268
        /* I know of no other way to achieve proper concurrency with Solaris. */
 
269
        thr_setconcurrency(n_thr);
 
270
#endif
 
271
 
 
272
        /* Start all n_thr threads. */
 
273
        for(i=0; i<n_thr; i++) {
 
274
                st[i].bins = bins;
 
275
                st[i].max = i_max;
 
276
                st[i].size = size;
 
277
                st[i].flags = 0;
 
278
                st[i].sp = 0;
 
279
                st[i].seed = ((long)i_max*size + i) ^ bins;
 
280
                if(my_start_thread(&st[i])) {
 
281
                        printf("Creating thread #%d failed.\n", i);
 
282
                        n_thr = i;
 
283
                        break;
 
284
                }
 
285
                printf("Created thread %lx.\n", (long)st[i].id);
 
286
        }
 
287
 
 
288
        for(n_running=n_total=n_thr; n_running>0;) {
 
289
#if USE_SPROC || USE_THR
 
290
                thread_id id;
 
291
#endif
 
292
 
 
293
                /* Wait for subthreads to finish. */
 
294
#if USE_PTHREADS
 
295
                pthread_mutex_lock(&finish_mutex);
 
296
                pthread_cond_wait(&finish_cond, &finish_mutex);
 
297
                for(i=0; i<n_thr; i++) if(st[i].flags) {
 
298
                        pthread_join(st[i].id, NULL);
 
299
                        st[i].flags = 0;
 
300
                        my_end_thread(&st[i]);
 
301
                }
 
302
                pthread_mutex_unlock(&finish_mutex);
 
303
#elif USE_THR
 
304
                thr_join(0, &id, NULL);
 
305
                for(i=0; i<n_thr; i++)
 
306
                        if(id == st[i].id) {
 
307
                                my_end_thread(&st[i]);
 
308
                                break;
 
309
                        }
 
310
#elif USE_SPROC
 
311
                {
 
312
                        int status = 0;
 
313
                        id = wait(&status);
 
314
                        if(status != 0) {
 
315
                                if(WIFSIGNALED(status))
 
316
                                        printf("thread %id terminated by signal %d\n",
 
317
                                                   id, WTERMSIG(status));
 
318
                                else
 
319
                                        printf("thread %id exited with status %d\n",
 
320
                                                   id, WEXITSTATUS(status));
 
321
                        }
 
322
                        for(i=0; i<n_thr; i++)
 
323
                                if(id == st[i].id) {
 
324
                                        my_end_thread(&st[i]);
 
325
                                        break;
 
326
                                }
 
327
                }
 
328
#else /* NO_THREADS */
 
329
                for(i=0; i<n_thr; i++)
 
330
                        my_end_thread(&st[i]);
 
331
                break;
 
332
#endif
 
333
        }
 
334
        for(i=0; i<n_thr; i++) {
 
335
                if(st[i].sp)
 
336
                        free(st[i].sp);
 
337
        }
 
338
        free(st);
 
339
#if USE_MALLOC
 
340
        malloc_stats();
 
341
#endif
 
342
        printf("Done.\n");
 
343
        return 0;
 
344
}
 
345
 
 
346
/*
 
347
 * Local variables:
 
348
 * tab-width: 4
 
349
 * End:
 
350
 */