tdb2: test: fix run-57-die-during-transaction.c to be more efficient.
[ccan] / ccan / lbalance / test / run.c
1 #include "config.h"
2 #include <sys/time.h>
3 #include <sys/resource.h>
4 #include <unistd.h>
5 #include <errno.h>
6
7 static int fake_gettimeofday(struct timeval *tv, struct timezone *tz);
8 static int fake_getrusage(int who, struct rusage *usage);
9 #define gettimeofday fake_gettimeofday
10 #define getrusage fake_getrusage
11
12 #include <ccan/lbalance/lbalance.c>
13 #include <ccan/tap/tap.h>
14
15 static unsigned faketime_ms = 0;
16 static struct rusage total_usage;
17
18 static int fake_gettimeofday(struct timeval *tv, struct timezone *tz)
19 {
20         assert(tz == NULL);
21         tv->tv_usec = (faketime_ms % 1000) * 1000;
22         tv->tv_sec = faketime_ms / 1000;
23         return 0;
24 }
25
26 static int fake_getrusage(int who, struct rusage *usage)
27 {
28         assert(who == RUSAGE_CHILDREN);
29         *usage = total_usage;
30         return 0;
31 }
32
33 static void test_optimum(struct lbalance *lb, unsigned int optimum)
34 {
35         unsigned int j, i, num_tasks = 0, usec, num_counted = 0;
36         float average;
37         struct lbalance_task *tasks[1000];
38
39         for (j = 0; j < 1000; j++) {
40                 diag("lbalance_target is %u\n", lbalance_target(lb));
41                 /* We measure average once we try optimum once. */
42                 if (lbalance_target(lb) == optimum && num_counted == 0) {
43                         average = lbalance_target(lb);
44                         num_counted = 1;
45                 } else if (num_counted) {
46                         average += lbalance_target(lb);
47                         num_counted++;
48                 }
49
50                 /* Create tasks until we reach target. */
51                 for (i = 0; i < lbalance_target(lb); i++) {
52                         tasks[i] = lbalance_task_new(lb);
53                 }
54                 num_tasks = i;
55
56                 faketime_ms += 100;
57                 /* If we're under optimum, set utilization to 100% */
58                 if (num_tasks <= optimum) {
59                         usec = 100000;
60                 } else {
61                         usec = 100000 * optimum / num_tasks;
62                 }
63
64                 for (i = 0; i < num_tasks; i++) {
65                         total_usage.ru_utime.tv_usec += usec / 2;
66                         if (total_usage.ru_utime.tv_usec > 1000000) {
67                                 total_usage.ru_utime.tv_usec -= 1000000;
68                                 total_usage.ru_utime.tv_sec++;
69                         }
70                         total_usage.ru_stime.tv_usec += usec / 2;
71                         if (total_usage.ru_stime.tv_usec > 1000000) {
72                                 total_usage.ru_stime.tv_usec -= 1000000;
73                                 total_usage.ru_stime.tv_sec++;
74                         }
75                         lbalance_task_free(tasks[i], NULL);
76                 }
77         }
78
79         /* We should have stayed close to optimum. */
80         ok1(num_counted && (int)(average / num_counted + 0.5) == optimum);
81 }
82
83 int main(void)
84 {
85         struct lbalance *lb;
86
87         plan_tests(4);
88         lb = lbalance_new();
89
90         test_optimum(lb, 1);
91         test_optimum(lb, 2);
92         test_optimum(lb, 4);
93         test_optimum(lb, 64);
94         lbalance_free(lb);
95
96         return exit_status();
97 }