Bump version to 0.3.5next
[archipelago] / xseg / xtypes / xworkq_test.c
1 /*
2  * Copyright 2013 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #include "xworkq.h"
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <pthread.h>
39 #include <xtypes/xlock.h>
40 #include <sys/time.h>
41
42
43 unsigned long sum = 0;
44 struct xlock lock;
45
46 void jobfn(void *q, void *arg)
47 {
48         unsigned long c = (unsigned long) arg;
49         sum += c;
50 }
51
52 int test1(unsigned long n)
53 {
54         struct xworkq wq;
55         unsigned long i;
56         xworkq_init(&wq, &lock, 0);
57         sum = 0;
58         xlock_release(&lock);
59
60         for (i = 0; i < n; i++) {
61                 xworkq_enqueue(&wq, jobfn, (void *)1);
62         }
63
64         xworkq_destroy(&wq);
65
66         return ((sum == n)? 0 : -1);
67 }
68
69 struct thread_arg{
70         struct xworkq *wq;
71         unsigned long n;
72         unsigned long num;
73 };
74
75 void *thread_test(void *arg)
76 {
77         struct thread_arg *targ = (struct thread_arg *)arg;
78         unsigned long n = targ->n;
79         unsigned long i;
80
81         for (i = 0; i < n; i++) {
82                 xworkq_enqueue(targ->wq, jobfn, (void *)targ->num);
83         }
84
85
86         return NULL;
87 }
88
89 int test2(unsigned long n, unsigned long nr_threads)
90 {
91         int i, r;
92         struct xworkq wq;
93         xworkq_init(&wq, &lock, 0);
94         sum = 0;
95         xlock_release(&lock);
96
97         struct thread_arg *targs = malloc(sizeof(struct thread_arg)*nr_threads * n);
98         pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads);
99
100         for (i = 0; i < nr_threads; i++) {
101                 targs[i].num = i+1;
102                 targs[i].n = n;
103                 targs[i].wq = &wq;
104         }
105         for (i = 0; i < nr_threads; i++) {
106                 r = pthread_create(&threads[i], NULL, thread_test, &targs[i]);
107                 if (r) {
108                         fprintf(stderr, "error pthread_create\n");
109                         return -1;
110                 }
111         }
112
113         for (i = 0; i < nr_threads; i++) {
114                 pthread_join(threads[i], NULL);
115         }
116
117
118
119         free(targs);
120         free(threads);
121         xworkq_destroy(&wq);
122
123         unsigned long expected_sum = 0;
124         for (i = 0; i < nr_threads; i++) {
125                 expected_sum += n*(i+1);
126         }
127         return ((sum == expected_sum) ? 0 : -1);
128 }
129
130 int test3(unsigned long n, unsigned long nr_threads)
131 {
132         int i, r;
133         struct xworkq wq;
134         xworkq_init(&wq, &lock, 0);
135         sum = 0;
136         xlock_release(&lock);
137
138         struct thread_arg *targs = malloc(sizeof(struct thread_arg)*nr_threads * n);
139         pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads);
140
141         for (i = 0; i < nr_threads; i++) {
142                 targs[i].num = i+1;
143                 targs[i].n = n;
144                 targs[i].wq = &wq;
145         }
146         for (i = 0; i < nr_threads; i++) {
147                 r = pthread_create(&threads[i], NULL, thread_test, &targs[i]);
148                 if (r) {
149                         fprintf(stderr, "error pthread_create\n");
150                         return -1;
151                 }
152         }
153
154         for (i = 0; i < nr_threads; i++) {
155                 pthread_join(threads[i], NULL);
156         }
157
158
159
160         free(targs);
161         free(threads);
162         xworkq_destroy(&wq);
163
164         unsigned long expected_sum = 0;
165         for (i = 0; i < nr_threads; i++) {
166                 expected_sum += n*(i+1);
167         }
168         return ((sum == expected_sum) ? 0 : -1);
169 }
170
171 int main(int argc, const char *argv[])
172 {
173         struct timeval start, end, tv;
174         int r;
175         int n = atoi(argv[1]);
176         int t = atoi(argv[2]);
177
178         fprintf(stderr, "Running test1\n");
179         gettimeofday(&start, NULL);
180         r = test1(n);
181         if (r < 0){
182                 fprintf(stderr, "Test1: FAILED\n");
183                 return -1;
184         }
185         gettimeofday(&end, NULL);
186         timersub(&end, &start, &tv);
187         fprintf(stderr, "Test1: PASSED\n");
188         fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec);
189
190         fprintf(stderr, "running test2\n");
191         gettimeofday(&start, NULL);
192         r = test2(n, t);
193         if (r < 0){
194                 fprintf(stderr, "test2: failed\n");
195                 return -1;
196         }
197         gettimeofday(&end, NULL);
198         fprintf(stderr, "test2: passed\n");
199         timersub(&end, &start, &tv);
200         fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec);
201
202         fprintf(stderr, "running test3\n");
203         gettimeofday(&start, NULL);
204         r = test3(n, t);
205         if (r < 0){
206                 fprintf(stderr, "test3: failed\n");
207                 return -1;
208         }
209         gettimeofday(&end, NULL);
210         fprintf(stderr, "test3: passed\n");
211         timersub(&end, &start, &tv);
212         fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec);
213
214         return 0;
215 }