bench: pass N as argument, update readme
[libc-test] / src / malloc / bench.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <pthread.h>
5 #include "test.h"
6
7 void bench_malloc_sparse(int N) {
8         void *p[N];
9         size_t i;
10         for (i=0; i<sizeof p/sizeof *p; i++) {
11                 p[i] = malloc(4000);
12                 memset(p[i], 0, 4000);
13         }
14         for (i=0; i<sizeof p/sizeof *p; i++)
15                 if (i%150) free(p[i]);
16 }
17
18 void bench_malloc_bubble(int N) {
19         void *p[N];
20         size_t i;
21         for (i=0; i<sizeof p/sizeof *p; i++) {
22                 p[i] = malloc(4000);
23                 memset(p[i], 0, 4000);
24         }
25         for (i=0; i<sizeof p/sizeof *p-1; i++)
26                 free(p[i]);
27 }
28
29 void bench_malloc_tiny1(int N) {
30         void **p = malloc(N * sizeof *p);
31         size_t i;
32         for (i=0; i<N; i++) {
33                 p[i] = malloc((i%4+1)*16);
34         }
35         for (i=0; i<N; i++) {
36                 free(p[i]);
37         }
38         free(p);
39 }
40
41 void bench_malloc_tiny2(int N) {
42         void **p = malloc(N * sizeof *p);
43         size_t i;
44         for (i=0; i<N; i++) {
45                 p[i] = malloc((i%4+1)*16);
46         }
47         if (N>1) for (i=1; i; i = (i+1999)%N)
48                 free(p[i]);
49         free(p[0]);
50         free(p);
51 }
52
53 void bench_malloc_big1(int N) {
54         void *p[N];
55         size_t i;
56         for (i=0; i<sizeof p/sizeof *p; i++) {
57                 p[i] = malloc((i%4+1)*16384);
58         }
59         for (i=0; i<sizeof p/sizeof *p; i++) {
60                 free(p[i]);
61         }
62 }
63
64 void bench_malloc_big2(int N) {
65         void *p[N];
66         size_t i;
67         for (i=0; i<sizeof p/sizeof *p; i++) {
68                 p[i] = malloc((i%4+1)*16384);
69         }
70         if (N>1) for (i=1; i; i = (i+1999)%(sizeof p/sizeof *p))
71                 free(p[i]);
72         free(p[0]);
73 }
74
75
76 #define SH_COUNT 300
77 #define PV_COUNT 300
78 #define MAX_SZ 500
79 #define DEF_SZ 40
80
81 struct foo {
82         void *mem;
83         pthread_mutex_t lock;
84 };
85
86 static unsigned rng(unsigned *r)
87 {
88         return *r = *r * 1103515245 + 12345;
89 }
90
91 static int N;
92
93 static void *stress(void *arg)
94 {
95         struct foo *foo = arg;
96         unsigned r = (unsigned)pthread_self();
97         int i, j;
98         size_t sz;
99         void *p;
100
101         for (i=0; i<N; i++) {
102                 j = rng(&r) % SH_COUNT;
103                 sz = rng(&r) % MAX_SZ;
104                 pthread_mutex_lock(&foo[j].lock);
105                 p = foo[j].mem;
106                 foo[j].mem = 0;
107                 pthread_mutex_unlock(&foo[j].lock);
108                 free(p);
109                 if (!p) {
110                         p = malloc(sz);
111                         pthread_mutex_lock(&foo[j].lock);
112                         if (!foo[j].mem) foo[j].mem = p, p = 0;
113                         pthread_mutex_unlock(&foo[j].lock);
114                         free(p);
115                 }
116         }
117         return 0;
118 }
119
120 void bench_malloc_thread_stress(int n) {
121         struct foo foo[SH_COUNT] = {{0}};
122         pthread_t td1, td2;
123         void *res;
124
125         N = n;
126         pthread_create(&td1, 0, stress, foo);
127         pthread_create(&td2, 0, stress, foo);
128         pthread_join(td1, &res);
129         pthread_join(td2, &res);
130 }
131
132 void bench_malloc_thread_local(int n) {
133         struct foo foo1[SH_COUNT] = {{0}};
134         struct foo foo2[SH_COUNT] = {{0}};
135         pthread_t td1, td2;
136         void *res;
137
138         N = n;
139         pthread_create(&td1, 0, stress, foo1);
140         pthread_create(&td2, 0, stress, foo2);
141         pthread_join(td1, &res);
142         pthread_join(td2, &res);
143 }