rcuja: extend tests, more fixes
[userspace-rcu.git] / rcuja / testpop.c
CommitLineData
3d45251f
MD
1/*
2 * rcuja/testpop.c
3 *
4 * Userspace RCU library - RCU Judy Array population size test
5 *
6 * Copyright 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/*
c7b5bcc3
MD
24 * This program generates random populations, and shows the largest
25 * sub-class generated, as well as the distribution of sub-class size
26 * for the largest sub-class of each population.
3d45251f
MD
27 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdint.h>
32#include <time.h>
33#include <string.h>
34#include <limits.h>
35
36static int sel_pool_len = 50; /* default */
37static int nr_distrib = 2; /* default */
38//#define SEL_POOL_LEN 100
39//#define NR_POOLS 10000000ULL
40
41static uint8_t pool[256];
42static uint8_t nr_one[8];
43static uint8_t nr_2d_11[8][8];
44static uint8_t nr_2d_10[8][8];
c7b5bcc3 45static int global_max_minsubclass_len = 0;
3d45251f 46
c7b5bcc3 47static unsigned int subclass_len_distrib[256];
3d45251f
MD
48
49static
50uint8_t random_char(void)
51{
52 return (uint8_t) random();
53}
54
55static
56void print_pool(void)
57{
58 int i;
59
60 printf("pool: ");
61 for (i = 0; i < sel_pool_len; i++) {
62 printf("%d ", (int) pool[i]);
63 }
64 printf("\n");
65}
66
67static
68void gen_pool(void)
69{
70 uint8_t src_pool[256];
71 int i;
72 int nr_left = 256;
73
74 memset(pool, 0, sizeof(pool));
75 for (i = 0; i < 256; i++)
76 src_pool[i] = (uint8_t) i;
77 for (i = 0; i < sel_pool_len; i++) {
78 int sel;
79
80 sel = random_char() % nr_left;
81 pool[i] = src_pool[sel];
82 src_pool[sel] = src_pool[nr_left - 1];
83 nr_left--;
84 }
85}
86
87static
88void count_pool(void)
89{
90 int i;
91
92 memset(nr_one, 0, sizeof(nr_one));
93 memset(nr_2d_11, 0, sizeof(nr_2d_11));
94 memset(nr_2d_10, 0, sizeof(nr_2d_10));
95 for (i = 0; i < sel_pool_len; i++) {
96 if (nr_distrib == 2) {
97 int j;
98
99 for (j = 0; j < 8; j++) {
100 if (pool[i] & (1U << j))
101 nr_one[j]++;
102 }
103 }
104
105 if (nr_distrib == 4) {
106 int j, k;
107
108 for (j = 0; j < 8; j++) {
109 for (k = 0; k < j; k++) {
110 if ((pool[i] & (1U << j)) && (pool[i] & (1U << k))) {
111 nr_2d_11[j][k]++;
112 }
113 if ((pool[i] & (1U << j)) && !(pool[i] & (1U << k))) {
114 nr_2d_10[j][k]++;
115 }
116 }
117 }
118 }
119 }
120}
121
122static
123void print_count(void)
124{
125 int i;
126
127 printf("pool distribution:\n");
128
129 if (nr_distrib == 2) {
130 printf(" 0 1\n");
131 printf("----------\n");
132 for (i = 0; i < 8; i++) {
133 printf("%3d %3d\n",
134 sel_pool_len - nr_one[i], nr_one[i]);
135 }
136 }
137
138 if (nr_distrib == 4) {
139 /* TODO */
140 }
141 printf("\n");
142}
143
144static
145void stat_count(void)
146{
c7b5bcc3 147 int minsubclass_len = INT_MAX;
3d45251f
MD
148
149 if (nr_distrib == 2) {
150 int i;
151
152 for (i = 0; i < 8; i++) {
153 int diff;
154
155 diff = (int) nr_one[i] * 2 - sel_pool_len;
156 if (diff < 0)
157 diff = -diff;
c7b5bcc3
MD
158 if ((diff >> 1) < minsubclass_len) {
159 minsubclass_len = diff >> 1;
3d45251f
MD
160 }
161 }
162 }
163
164 if (nr_distrib == 4) {
165 int j, k;
166
167 for (j = 0; j < 8; j++) {
168 for (k = 0; k < j; k++) {
169 int diff[2];
170
171 diff[0] = (int) nr_2d_11[j][k] * 4 - sel_pool_len;
172 if (diff[0] < 0)
173 diff[0] = -diff[0];
174
175 diff[1] = (int) nr_2d_10[j][k] * 4 - sel_pool_len;
176 if (diff[1] < 0)
177 diff[1] = -diff[1];
178 /* Get max linear array size */
179 if (diff[1] > diff[0])
180 diff[0] = diff[1];
c7b5bcc3
MD
181 if ((diff[0] >> 2) < minsubclass_len) {
182 minsubclass_len = diff[0] >> 2;
3d45251f
MD
183 }
184 }
185 }
186 }
187
c7b5bcc3
MD
188 if (minsubclass_len > global_max_minsubclass_len) {
189 global_max_minsubclass_len = minsubclass_len;
3d45251f 190 }
c7b5bcc3 191 subclass_len_distrib[minsubclass_len]++;
3d45251f
MD
192}
193
194static
195void print_distrib(void)
196{
197 int i;
198 unsigned long long tot = 0;
199
200 for (i = 0; i < 256; i++) {
c7b5bcc3 201 tot += subclass_len_distrib[i];
3d45251f
MD
202 }
203 if (tot == 0)
204 return;
205 printf("Distribution:\n");
206 for (i = 0; i < 256; i++) {
207 printf("(%u, %u, %llu%%) ",
c7b5bcc3
MD
208 i, subclass_len_distrib[i],
209 100 * (unsigned long long) subclass_len_distrib[i] / tot);
3d45251f
MD
210 }
211 printf("\n");
212}
213
214static
215void print_stat(uint64_t i)
216{
c7b5bcc3
MD
217 printf("after %llu pools, global_max_minsubclass_len extra: %d\n",
218 (unsigned long long) i, global_max_minsubclass_len);
3d45251f
MD
219 print_distrib();
220}
221
222int main(int argc, char **argv)
223{
224 uint64_t i = 0;
225
226 srandom(time(NULL));
227
228 if (argc > 1) {
229 sel_pool_len = atoi(argv[1]);
230 if (sel_pool_len > 256 || sel_pool_len < 1) {
231 printf("Wrong pool len\n");
232 return -1;
233 }
234 }
235 printf("pool len: %d\n", sel_pool_len);
236
237 if (argc > 2) {
238 nr_distrib = atoi(argv[2]);
239 if (nr_distrib > 256 || nr_distrib < 1) {
240 printf("Wrong number of distributions\n");
241 return -1;
242 }
243 }
244 printf("pool distributions: %d\n", nr_distrib);
245
246 if (nr_distrib != 2 && nr_distrib != 4) {
247 printf("Wrong number of distributions. Only 2 and 4 supported.\n");
248 return -1;
249 }
250
251 //for (i = 0; i < NR_POOLS; i++) {
252 while (1) {
253 gen_pool();
254 count_pool();
255 //print_pool();
256 //print_count();
257 stat_count();
258 if (!(i % 100000ULL))
259 print_stat(i);
260 i++;
261 }
262 print_stat(i);
263 print_distrib();
264
265 return 0;
266}
This page took 0.032924 seconds and 4 git commands to generate.