1 /* $OpenBSD: malloc_duel.c,v 1.4 2021/12/24 15:09:10 bluhm 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
alarm_handler(int sig)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
malloc_loop(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 *
thread(void * arg)53 thread(void *arg)
54 {
55 	malloc_loop();
56 	return NULL;
57 }
58 
59 #define NCHILDS	10
60 int
main(int argc,char ** argv)61 main(int argc, char **argv)
62 {
63 	pthread_t	child[NCHILDS];
64 	int i;
65 
66 	for (i = 0; i < NCHILDS; i++)
67 		CHECKr(pthread_create(&child[i], NULL, thread, NULL));
68 	ASSERT(signal(SIGALRM, alarm_handler) != SIG_ERR);
69 	CHECKe(alarm(60));
70 	malloc_loop();
71 	for (i = 0; i < NCHILDS; i++)
72 		CHECKr(pthread_join(child[i], NULL));
73 	SUCCEED;
74 }
75