xref: /openbsd-src/regress/lib/libpthread/malloc_duel/malloc_duel.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /* $OpenBSD: malloc_duel.c,v 1.2 2003/07/31 21:48:04 deraadt Exp $ */
2 /* PUBLIC DOMAIN Nov 2002 <marc@snafu.org> */
3 
4 /*
5  * Dueling malloc in different threads
6  */
7 
8 #include <signal.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 
12 #include "test.h"
13 
14 volatile sig_atomic_t	done;
15 
16 #define MALLOC_COUNT	1024
17 
18 /*
19  * sigalrm handler.  Initiate end-of-test
20  */
21 static void
22 alarm_handler(int sig)
23 {
24 	done = 1;
25 }
26 
27 /*
28  * A function that does lots of mallocs, called by all threads.
29  */
30 static void
31 malloc_loop(void)
32 {
33 	int	i;
34 	int	**a;
35 
36 	a = calloc(MALLOC_COUNT, sizeof(int*));
37 	ASSERT(a != NULL);
38 	while (!done) {
39 		for (i = 0; i < MALLOC_COUNT; i++) {
40 			a[i] = malloc(sizeof(int));
41 			ASSERT(a[i] != NULL);
42 		}
43 		for (i = 0; i < MALLOC_COUNT; i++) {
44 			free(a[i]);
45 		}
46 	}
47 }
48 
49 /*
50  * A thread that does a lot of mallocs
51  */
52 static void *
53 thread(void *arg)
54 {
55 	malloc_loop();
56 	return NULL;
57 }
58 
59 int
60 main(int argc, char **argv)
61 {
62 	pthread_t	child;
63 
64 	CHECKr(pthread_create(&child, NULL, thread, NULL));
65 	ASSERT(signal(SIGALRM, alarm_handler) != SIG_ERR);
66 	CHECKe(alarm(20));
67 	malloc_loop();
68 	CHECKr(pthread_join(child, NULL));
69 	SUCCEED;
70 }
71