Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b520b5d8c5e650255746f95efdf33ad7abac1e54
[simgrid.git] / teshsuite / xbt / parmap_test / parmap_test.c
1 /* parmap_test -- test parmap                                               */
2
3 /* Copyright (c) 2007-2017. The SimGrid Team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "simgrid/msg.h"
9 #include "src/internal_config.h"
10 #include "xbt.h"
11 #include "xbt/ex.h"
12 #include "xbt/xbt_os_time.h"
13
14 XBT_LOG_NEW_DEFAULT_CATEGORY(parmap_test, "Test for parmap");
15
16 static void fun_double(void *arg)
17 {
18   unsigned *u = arg;
19   *u = 2 * *u + 1;
20 }
21
22 static int test_parmap_basic(e_xbt_parmap_mode_t mode)
23 {
24   int ret = 0;
25   unsigned num_workers;
26   for (num_workers = 1 ; num_workers <= 16 ; num_workers *= 2) {
27     const unsigned len = 1033;
28     const unsigned num = 5;
29     unsigned *a;
30     xbt_dynar_t data;
31     xbt_parmap_t parmap;
32     unsigned i;
33
34     parmap = xbt_parmap_new(num_workers, mode);
35
36     a = xbt_malloc(len * sizeof *a);
37     data = xbt_dynar_new(sizeof a, NULL);
38     for (i = 0; i < len; i++) {
39       a[i] = i;
40       xbt_dynar_push_as(data, void *, &a[i]);
41     }
42
43     for (i = 0; i < num; i++)
44       xbt_parmap_apply(parmap, fun_double, data);
45
46     for (i = 0; i < len; i++) {
47       unsigned expected = (1U << num) * (i + 1) - 1;
48       if (a[i] != expected) {
49         XBT_CRITICAL("with %u threads, a[%u]: expected %u, got %u", num_workers, i, expected, a[i]);
50         ret = 1;
51         break;
52       }
53     }
54
55     xbt_dynar_free(&data);
56     xbt_free(a);
57     xbt_parmap_destroy(parmap);
58   }
59   return ret;
60 }
61
62 static void fun_get_id(void *arg)
63 {
64   *(uintptr_t *)arg = (uintptr_t)xbt_os_thread_self();
65   xbt_os_sleep(0.05);
66 }
67
68 static int fun_compare(const void *pa, const void *pb)
69 {
70   uintptr_t a = *(uintptr_t *)pa;
71   uintptr_t b = *(uintptr_t *)pb;
72   return a < b ? -1 : a > b ? 1 : 0;
73 }
74
75 static int test_parmap_extended(e_xbt_parmap_mode_t mode)
76 {
77   int ret = 0;
78   unsigned num_workers;
79
80   for (num_workers = 1 ; num_workers <= 16 ; num_workers *= 2) {
81     const unsigned len = 2 * num_workers;
82     uintptr_t *a;
83     xbt_parmap_t parmap;
84     xbt_dynar_t data;
85     unsigned i;
86     unsigned count;
87
88     parmap = xbt_parmap_new(num_workers, mode);
89
90     a = xbt_malloc(len * sizeof *a);
91     data = xbt_dynar_new(sizeof a, NULL);
92     for (i = 0; i < len; i++)
93       xbt_dynar_push_as(data, void *, &a[i]);
94
95     xbt_parmap_apply(parmap, fun_get_id, data);
96
97     qsort(a, len, sizeof a[0], fun_compare);
98     count = 1;
99     for (i = 1; i < len; i++)
100       if (a[i] != a[i - 1])
101         count++;
102     if (count != num_workers) {
103       XBT_CRITICAL("only %u/%u threads did some work", count, num_workers);
104       ret = 1;
105     }
106
107     xbt_dynar_free(&data);
108     xbt_free(a);
109     xbt_parmap_destroy(parmap);
110   }
111   return ret;
112 }
113
114 int main(int argc, char** argv)
115 {
116   int status = 0;
117   MSG_init(&argc, argv);
118
119   XBT_INFO("Basic testing posix");
120   status += test_parmap_basic(XBT_PARMAP_POSIX);
121   XBT_INFO("Basic testing futex");
122 #if HAVE_FUTEX_H
123   status += test_parmap_basic(XBT_PARMAP_FUTEX);
124 #endif
125   XBT_INFO("Basic testing busy wait");
126   status += test_parmap_basic(XBT_PARMAP_BUSY_WAIT);
127
128   XBT_INFO("Extended testing posix");
129   status += test_parmap_extended(XBT_PARMAP_POSIX);
130   XBT_INFO("Extended testing futex");
131 #if HAVE_FUTEX_H
132   status += test_parmap_extended(XBT_PARMAP_FUTEX);
133 #endif
134   XBT_INFO("Extended testing busy wait");
135   status += test_parmap_extended(XBT_PARMAP_BUSY_WAIT);
136
137   return status == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
138 }