Revision 4b1a848d
b/xseg/sys/kernel/Makefile | ||
---|---|---|
50 | 50 |
EXTRA_CFLAGS += -g -I$(BASE) -I$(BASE)/sys/kernel -DVAL_OVERLOAD |
51 | 51 |
LIBDIR=$(BASE)/lib/kernel |
52 | 52 |
|
53 |
xseg-objs := xsegmod.o xq.k.o xpool.k.o xhash.k.o xheap.k.o xobj.k.o xseg.k.o xworkq.k.o |
|
53 |
xseg-objs := xsegmod.o xq.k.o xpool.k.o xhash.k.o xheap.k.o xobj.k.o xseg.k.o xworkq.k.o xwaitq.k.o
|
|
54 | 54 |
obj-m += xseg.o segdev.o |
55 | 55 |
|
56 |
default: xq.k.c xpool.k.c xhash.k.c xheap.k.c xobj.k.c xworkq.k.c xseg.k.c |
|
56 |
default: xq.k.c xpool.k.c xhash.k.c xheap.k.c xobj.k.c xworkq.k.c xwaitq.k.c xseg.k.c
|
|
57 | 57 |
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) V=$(V) modules |
58 | 58 |
cp -vaf xseg.ko segdev.ko $(LIBDIR) |
59 | 59 |
|
... | ... | |
75 | 75 |
xworkq.k.c: $(BASE)/xtypes/xworkq.c $(BASE)/xtypes/xworkq.h |
76 | 76 |
ln -sf $< $@ |
77 | 77 |
|
78 |
xwaitq.k.c: $(BASE)/xtypes/xwaitq.c $(BASE)/xtypes/xwaitq.h |
|
79 |
ln -sf $< $@ |
|
80 |
|
|
78 | 81 |
xseg.k.c: $(BASE)/xseg/xseg.c $(BASE)/xseg/xseg.h |
79 | 82 |
ln -sf $< $@ |
80 | 83 |
|
... | ... | |
90 | 93 |
done |
91 | 94 |
|
92 | 95 |
clean: |
93 |
rm -f xq.k.c xpool.k.c xhash.k.c xheap.k.c xobj.k.c xworkq.k.c xseg.k.c |
|
96 |
rm -f xq.k.c xpool.k.c xhash.k.c xheap.k.c xobj.k.c xworkq.k.c xwaitq.k.c xseg.k.c
|
|
94 | 97 |
make -C /lib/modules/$(KVER)/build M=$(PWD) V=$(V) clean |
b/xseg/sys/user/Makefile | ||
---|---|---|
62 | 62 |
make -C xheap all |
63 | 63 |
make -C xobj all |
64 | 64 |
make -C xworkq all |
65 |
make -C xwaitq all |
|
65 | 66 |
|
66 | 67 |
COMMA=, |
67 | 68 |
_initialize.c: drivers |
... | ... | |
120 | 121 |
xworkq/xworkq.pic.o: |
121 | 122 |
make -C xworkq xworkq.pic.o |
122 | 123 |
|
124 |
xwaitq/xwaitq.o: |
|
125 |
make -C xwaitq xwaitq.o |
|
126 |
|
|
127 |
xwaitq/xwaitq.pic.o: |
|
128 |
make -C xwaitq xwaitq.pic.o |
|
129 |
|
|
123 | 130 |
xseg_user.o: xseg_user.c |
124 | 131 |
$(CC) $(CFLAGS) $(INC) -Wall -O2 -finline-functions -fPIC -c -o $@ $< |
125 | 132 |
|
126 | 133 |
libxseg.map: $(BASE)/xtypes/xq_exports.h $(BASE)/xseg/xseg_exports.h \ |
127 | 134 |
$(BASE)/xtypes/xpool_exports.h $(BASE)/xtypes/xhash_exports.h\ |
128 |
$(BASE)/xtypes/xobj_exports.h $(BASE)/xtypes/xworkq_exports.h |
|
135 |
$(BASE)/xtypes/xobj_exports.h $(BASE)/xtypes/xworkq_exports.h\ |
|
136 |
$(BASE)/xtypes/xwaitq_exports.h |
|
129 | 137 |
cat $(BASE)/xtypes/xq_exports.h $(BASE)/xseg/xseg_exports.h \ |
130 | 138 |
$(BASE)/xtypes/xpool_exports.h $(BASE)/xtypes/xhash_exports.h \ |
131 | 139 |
$(BASE)/xtypes/xobj_exports.h $(BASE)/xtypes/xworkq_exports.h \ |
132 |
| ./make_symbol_map.sh > $@ |
|
140 |
$(BASE)/xtypes/xwaitq_exports.h | ./make_symbol_map.sh > $@
|
|
133 | 141 |
|
134 | 142 |
libxseg.so.$(MAJOR).$(MINOR): xseg.pic.o xseg_user.o libxseg.map \ |
135 | 143 |
xq/xq.pic.o xpool/xpool.pic.o xhash/xhash.pic.o \ |
136 | 144 |
xheap/xheap.pic.o xobj/xobj.pic.o \ |
137 |
xworkq/xworkq.pic.o $(DRVOBJS) |
|
145 |
xworkq/xworkq.pic.o xwaitq/xwaitq.pic.o $(DRVOBJS)
|
|
138 | 146 |
$(CC) $(CFLAGS) -shared \ |
139 | 147 |
-Wl,-soname=libxseg.so.$(MAJOR) \ |
140 | 148 |
-o libxseg.so.$(MAJOR).$(MINOR) \ |
141 | 149 |
xseg.pic.o xseg_user.o xq/xq.pic.o \ |
142 | 150 |
xpool/xpool.pic.o xhash/xhash.pic.o\ |
143 | 151 |
xheap/xheap.pic.o xobj/xobj.pic.o \ |
144 |
xworkq/xworkq.pic.o \ |
|
152 |
xworkq/xworkq.pic.o xwaitq/xwaitq.pic.o \
|
|
145 | 153 |
_initialize.o $(DRVOBJS) \ |
146 | 154 |
-Wl,--version-script=libxseg.map \ |
147 | 155 |
-ldl -lrt -pthread |
... | ... | |
167 | 175 |
make -C xheap install-src |
168 | 176 |
make -C xobj install-src |
169 | 177 |
make -C xworkq install-src |
178 |
make -C xwaitq install-src |
|
170 | 179 |
make -C python install-src |
171 | 180 |
install -d $(DESTDIR)$(srcdir)$(SUBDIR) ; |
172 | 181 |
@for f in $(FILES) ; do \ |
... | ... | |
184 | 193 |
make -C xheap clean |
185 | 194 |
make -C xobj clean |
186 | 195 |
make -C xworkq clean |
196 |
make -C xwaitq clean |
|
187 | 197 |
make -C python clean |
188 | 198 |
rm -f _initialize.c _initialize.o |
189 | 199 |
rm -f xseg.o xseg.pic.o xseg_user.o |
b/xseg/sys/user/xwaitq/Makefile | ||
---|---|---|
1 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# 2. Redistributions in binary form must reproduce the above |
|
11 |
# copyright notice, this list of conditions and the following |
|
12 |
# disclaimer in the documentation and/or other materials |
|
13 |
# provided with the distribution. |
|
14 |
# |
|
15 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
16 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
17 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
18 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
19 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
20 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
21 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
22 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
23 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
24 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
25 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 |
# POSSIBILITY OF SUCH DAMAGE. |
|
27 |
# |
|
28 |
# The views and conclusions contained in the software and |
|
29 |
# documentation are those of the authors and should not be |
|
30 |
# interpreted as representing official policies, either expressed |
|
31 |
# or implied, of GRNET S.A. |
|
32 |
# |
|
33 |
|
|
34 |
.PHONY: default all clean install install-src |
|
35 |
|
|
36 |
include $(XSEG_HOME)/base.mk |
|
37 |
|
|
38 |
DEBUG=-g |
|
39 |
|
|
40 |
FILES="Makefile" |
|
41 |
#FILES+=$(shell ls *.h) |
|
42 |
#FILES+=$(shell ls *.c) |
|
43 |
|
|
44 |
SUBDIR:=$(subst $(XSEG_HOME),,$(CURDIR)) |
|
45 |
|
|
46 |
default: all |
|
47 |
|
|
48 |
all: xwaitq.o xwaitq.pic.o xwaitq_test |
|
49 |
|
|
50 |
$(BASE)/sys/user/xseg_user.o: |
|
51 |
make -C $(BASE)/sys/user xseg_user.o |
|
52 |
|
|
53 |
xwaitq_test: $(BASE)/xtypes/xwaitq_test.c xwaitq.o $(BASE)/sys/user/xq/xq.o $(BASE)/sys/user/xseg_user.o |
|
54 |
$(CC) $(CFLAGS) $(INC) -L$(LIB) -o $@ $< xwaitq.o \ |
|
55 |
$(BASE)/sys/user/xseg_user.o $(BASE)/sys/user/xq/xq.o \ |
|
56 |
-ldl -lpthread |
|
57 |
|
|
58 |
xwaitq.o: $(BASE)/xtypes/xwaitq.c $(BASE)/xtypes/xwaitq.h $(BASE)/xtypes/xwork.h $(BASE)/xtypes/xlock.h |
|
59 |
$(CC) $(CFLAGS) $(INC) -c -o $@ $< |
|
60 |
|
|
61 |
xwaitq.pic.o: $(BASE)/xtypes/xwaitq.c $(BASE)/xtypes/xwaitq.h $(BASE)/xtypes/xwork.h $(BASE)/xtypes/xlock.h |
|
62 |
$(CC) $(CFLAGS) $(INC) -fPIC -c -o $@ $< |
|
63 |
|
|
64 |
clean: |
|
65 |
rm -f xwaitq.o xwaitq.pic.o xwaitq_test |
|
66 |
|
|
67 |
install: |
|
68 |
|
|
69 |
install-src: |
|
70 |
install -d $(DESTDIR)$(srcdir)$(SUBDIR) ; |
|
71 |
@for f in $(FILES) ; do \ |
|
72 |
install -o 0 -g 0 -m 644 -t $(DESTDIR)$(srcdir)$(SUBDIR) $$f ; \ |
|
73 |
done |
b/xseg/xtypes/xwaitq.c | ||
---|---|---|
1 |
#include <xtypes/domain.h> |
|
2 |
#include <xtypes/xwaitq.h> |
|
3 |
|
|
4 |
static int __check_cond(struct xwaitq *wq) |
|
5 |
{ |
|
6 |
return wq->cond_fn(wq->cond_arg); |
|
7 |
} |
|
8 |
|
|
9 |
int xwaitq_init(struct xwaitq *wq, int (*cond_fn)(void *arg), void *arg, uint32_t flags) |
|
10 |
{ |
|
11 |
wq->cond_fn = cond_fn; |
|
12 |
wq->cond_arg = arg; |
|
13 |
wq->flags = flags; |
|
14 |
wq->q = xtypes_malloc(sizeof(struct xq)); |
|
15 |
if (!wq->q) |
|
16 |
return -1; |
|
17 |
xlock_release(&wq->lock); |
|
18 |
if (!xq_alloc_empty(wq->q, 8)){ |
|
19 |
xtypes_free(wq->q); |
|
20 |
return -1; |
|
21 |
} |
|
22 |
return 0; |
|
23 |
} |
|
24 |
|
|
25 |
void xwaitq_destroy(struct xwaitq *wq) |
|
26 |
{ |
|
27 |
xq_free(wq->q); |
|
28 |
xtypes_free(wq->q); |
|
29 |
} |
|
30 |
|
|
31 |
int __xwaitq_enqueue(struct xwaitq *wq, struct work *w) |
|
32 |
{ |
|
33 |
//enqueure and resize if necessary |
|
34 |
xqindex r; |
|
35 |
struct xq *newq; |
|
36 |
r = __xq_append_tail(wq->q, (xqindex)w); |
|
37 |
if (r == Noneidx){ |
|
38 |
newq = xtypes_malloc(sizeof(struct xq)); |
|
39 |
if (!newq){ |
|
40 |
return -1; |
|
41 |
} |
|
42 |
if (!xq_alloc_empty(newq, wq->q->size*2)){ |
|
43 |
xtypes_free(newq); |
|
44 |
return -1; |
|
45 |
} |
|
46 |
if (__xq_resize(wq->q, newq) == Noneidx){ |
|
47 |
xq_free(newq); |
|
48 |
xtypes_free(newq); |
|
49 |
return -1; |
|
50 |
} |
|
51 |
xtypes_free(wq->q); |
|
52 |
wq->q = newq; |
|
53 |
r = __xq_append_tail(wq->q, (xqindex)w); |
|
54 |
} |
|
55 |
|
|
56 |
return ((r == Noneidx)? -1 : 0); |
|
57 |
} |
|
58 |
|
|
59 |
int xwaitq_enqueue(struct xwaitq *wq, struct work *w) |
|
60 |
{ |
|
61 |
int r; |
|
62 |
xlock_acquire(&wq->lock, 1); |
|
63 |
if (__check_cond(wq)){ |
|
64 |
xlock_release(&wq->lock); |
|
65 |
w->job_fn(w->job); |
|
66 |
return 0; |
|
67 |
} |
|
68 |
r = __xwaitq_enqueue(wq, w); |
|
69 |
xlock_release(&wq->lock); |
|
70 |
return r; |
|
71 |
} |
|
72 |
|
|
73 |
void xwaitq_signal(struct xwaitq *wq) |
|
74 |
{ |
|
75 |
xqindex xqi; |
|
76 |
struct work *w; |
|
77 |
|
|
78 |
if (!xq_count(wq->q)) |
|
79 |
return; |
|
80 |
|
|
81 |
if (wq->flags & XWAIT_SIGNAL_ONE){ |
|
82 |
if (!xlock_try_lock(&wq->lock, 1)) |
|
83 |
return; |
|
84 |
} else { |
|
85 |
xlock_acquire(&wq->lock, 1); |
|
86 |
} |
|
87 |
while (xq_count(wq->q) && __check_cond(wq)){ |
|
88 |
xqi = __xq_pop_head(wq->q); |
|
89 |
xlock_release(&wq->lock); |
|
90 |
if (xqi == Noneidx){ |
|
91 |
break; |
|
92 |
} |
|
93 |
w = (struct work *)xqi; |
|
94 |
w->job_fn(w->job); |
|
95 |
if (wq->flags & XWAIT_SIGNAL_ONE){ |
|
96 |
if (!xlock_try_lock(&wq->lock, 1)) |
|
97 |
return; |
|
98 |
} else { |
|
99 |
xlock_acquire(&wq->lock, 1); |
|
100 |
} |
|
101 |
} |
|
102 |
xlock_release(&wq->lock); |
|
103 |
} |
b/xseg/xtypes/xwaitq.h | ||
---|---|---|
1 |
#ifndef __X_WAITQ_H |
|
2 |
#define __X_WAITQ_H |
|
3 |
|
|
4 |
#include <xtypes/xq.h> |
|
5 |
#include <xtypes/xwork.h> |
|
6 |
|
|
7 |
#define XWAIT_SIGNAL_ONE (1 << 0) |
|
8 |
|
|
9 |
struct xwaitq { |
|
10 |
int (*cond_fn)(void *arg); |
|
11 |
void *cond_arg; |
|
12 |
uint32_t flags; |
|
13 |
struct xq *q; |
|
14 |
struct xlock lock; |
|
15 |
}; |
|
16 |
|
|
17 |
int xwaitq_init(struct xwaitq *wq, int (*cond_fn)(void *arg), void *arg, uint32_t flags); |
|
18 |
int xwaitq_enqueue(struct xwaitq *wq, struct work *w); |
|
19 |
void xwaitq_signal(struct xwaitq *wq); |
|
20 |
void xwaitq_destroy(struct xwaitq *wq); |
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
#endif /* __X_WAITQ_H */ |
b/xseg/xtypes/xwaitq_exports.h | ||
---|---|---|
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 |
EXPORT_SYMBOL(xwaitq_init); |
|
36 |
EXPORT_SYMBOL(xwaitq_destroy); |
|
37 |
EXPORT_SYMBOL(xwaitq_enqueue); |
|
38 |
EXPORT_SYMBOL(xwaitq_signal); |
b/xseg/xtypes/xwaitq_test.c | ||
---|---|---|
1 |
#include "xwaitq.h" |
|
2 |
#include <stdio.h> |
|
3 |
#include <stdlib.h> |
|
4 |
#include <pthread.h> |
|
5 |
#include <xtypes/xlock.h> |
|
6 |
#include <sys/time.h> |
|
7 |
|
|
8 |
|
|
9 |
volatile int cond = 0; |
|
10 |
unsigned long sum = 0; |
|
11 |
struct xlock lock; |
|
12 |
|
|
13 |
int condfn(void *arg) |
|
14 |
{ |
|
15 |
return cond; |
|
16 |
} |
|
17 |
|
|
18 |
void jobfn(void *arg) |
|
19 |
{ |
|
20 |
unsigned long c = (unsigned long) arg; |
|
21 |
xlock_acquire(&lock, c); |
|
22 |
sum += c; |
|
23 |
xlock_release(&lock); |
|
24 |
} |
|
25 |
|
|
26 |
int test1(unsigned long n) |
|
27 |
{ |
|
28 |
struct xwaitq wq; |
|
29 |
unsigned long i; |
|
30 |
struct work *works = malloc(sizeof(struct work) * n); |
|
31 |
xwaitq_init(&wq, condfn, NULL, 0); |
|
32 |
cond = 0; |
|
33 |
sum = 0; |
|
34 |
xlock_release(&lock); |
|
35 |
|
|
36 |
for (i = 0; i < n; i++) { |
|
37 |
works[i].job_fn = jobfn; |
|
38 |
works[i].job = 1; |
|
39 |
} |
|
40 |
|
|
41 |
for (i = 0; i < n; i++) { |
|
42 |
xwaitq_enqueue(&wq, &works[i]); |
|
43 |
} |
|
44 |
cond = 1; |
|
45 |
xwaitq_signal(&wq); |
|
46 |
|
|
47 |
free(works); |
|
48 |
xwaitq_destroy(&wq); |
|
49 |
|
|
50 |
return ((sum == n)? 0 : -1); |
|
51 |
} |
|
52 |
|
|
53 |
struct thread_arg{ |
|
54 |
struct xwaitq *wq; |
|
55 |
unsigned long n; |
|
56 |
unsigned long num; |
|
57 |
}; |
|
58 |
|
|
59 |
void *thread_test(void *arg) |
|
60 |
{ |
|
61 |
struct thread_arg *targ = (struct thread_arg *)arg; |
|
62 |
unsigned long n = targ->n; |
|
63 |
unsigned long i; |
|
64 |
|
|
65 |
struct work *works = malloc(sizeof(struct work) * n); |
|
66 |
|
|
67 |
for (i = 0; i < n; i++) { |
|
68 |
works[i].job_fn = jobfn; |
|
69 |
works[i].job = targ->num; |
|
70 |
} |
|
71 |
|
|
72 |
for (i = 0; i < n; i++) { |
|
73 |
xwaitq_enqueue(targ->wq, &works[i]); |
|
74 |
} |
|
75 |
cond = 1; |
|
76 |
xwaitq_signal(targ->wq); |
|
77 |
|
|
78 |
// free(works); |
|
79 |
|
|
80 |
return NULL; |
|
81 |
} |
|
82 |
|
|
83 |
int test2(unsigned long n, unsigned long nr_threads) |
|
84 |
{ |
|
85 |
int i, r; |
|
86 |
struct xwaitq wq; |
|
87 |
xwaitq_init(&wq, condfn, NULL, 0); |
|
88 |
cond = 0; |
|
89 |
sum = 0; |
|
90 |
xlock_release(&lock); |
|
91 |
|
|
92 |
struct thread_arg *targs = malloc(sizeof(struct thread_arg)*nr_threads * n); |
|
93 |
pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads); |
|
94 |
|
|
95 |
for (i = 0; i < nr_threads; i++) { |
|
96 |
targs[i].num = i+1; |
|
97 |
targs[i].n = n; |
|
98 |
targs[i].wq = &wq; |
|
99 |
} |
|
100 |
for (i = 0; i < nr_threads; i++) { |
|
101 |
r = pthread_create(&threads[i], NULL, thread_test, &targs[i]); |
|
102 |
if (r) { |
|
103 |
fprintf(stderr, "error pthread_create\n"); |
|
104 |
return -1; |
|
105 |
} |
|
106 |
} |
|
107 |
|
|
108 |
for (i = 0; i < nr_threads; i++) { |
|
109 |
pthread_join(threads[i], NULL); |
|
110 |
} |
|
111 |
|
|
112 |
|
|
113 |
|
|
114 |
free(targs); |
|
115 |
free(threads); |
|
116 |
xwaitq_destroy(&wq); |
|
117 |
|
|
118 |
unsigned long expected_sum = 0; |
|
119 |
for (i = 0; i < nr_threads; i++) { |
|
120 |
expected_sum += n*(i+1); |
|
121 |
} |
|
122 |
return ((sum == expected_sum) ? 0 : -1); |
|
123 |
} |
|
124 |
|
|
125 |
int test3(unsigned long n, unsigned long nr_threads) |
|
126 |
{ |
|
127 |
int i, r; |
|
128 |
struct xwaitq wq; |
|
129 |
xwaitq_init(&wq, condfn, NULL, XWAIT_SIGNAL_ONE); |
|
130 |
cond = 0; |
|
131 |
sum = 0; |
|
132 |
xlock_release(&lock); |
|
133 |
|
|
134 |
struct thread_arg *targs = malloc(sizeof(struct thread_arg)*nr_threads * n); |
|
135 |
pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads); |
|
136 |
|
|
137 |
for (i = 0; i < nr_threads; i++) { |
|
138 |
targs[i].num = i+1; |
|
139 |
targs[i].n = n; |
|
140 |
targs[i].wq = &wq; |
|
141 |
} |
|
142 |
for (i = 0; i < nr_threads; i++) { |
|
143 |
r = pthread_create(&threads[i], NULL, thread_test, &targs[i]); |
|
144 |
if (r) { |
|
145 |
fprintf(stderr, "error pthread_create\n"); |
|
146 |
return -1; |
|
147 |
} |
|
148 |
} |
|
149 |
|
|
150 |
for (i = 0; i < nr_threads; i++) { |
|
151 |
pthread_join(threads[i], NULL); |
|
152 |
} |
|
153 |
|
|
154 |
|
|
155 |
|
|
156 |
free(targs); |
|
157 |
free(threads); |
|
158 |
xwaitq_destroy(&wq); |
|
159 |
|
|
160 |
unsigned long expected_sum = 0; |
|
161 |
for (i = 0; i < nr_threads; i++) { |
|
162 |
expected_sum += n*(i+1); |
|
163 |
} |
|
164 |
return ((sum == expected_sum) ? 0 : -1); |
|
165 |
} |
|
166 |
|
|
167 |
int main(int argc, const char *argv[]) |
|
168 |
{ |
|
169 |
struct timeval start, end, tv; |
|
170 |
int r; |
|
171 |
int n = atoi(argv[1]); |
|
172 |
int t = atoi(argv[2]); |
|
173 |
|
|
174 |
fprintf(stderr, "Running test1\n"); |
|
175 |
gettimeofday(&start, NULL); |
|
176 |
r = test1(n); |
|
177 |
if (r < 0){ |
|
178 |
fprintf(stderr, "Test1: FAILED\n"); |
|
179 |
return -1; |
|
180 |
} |
|
181 |
gettimeofday(&end, NULL); |
|
182 |
timersub(&end, &start, &tv); |
|
183 |
fprintf(stderr, "Test1: PASSED\n"); |
|
184 |
fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec); |
|
185 |
|
|
186 |
fprintf(stderr, "running test2\n"); |
|
187 |
gettimeofday(&start, NULL); |
|
188 |
r = test2(n, t); |
|
189 |
if (r < 0){ |
|
190 |
fprintf(stderr, "test2: failed\n"); |
|
191 |
return -1; |
|
192 |
} |
|
193 |
gettimeofday(&end, NULL); |
|
194 |
fprintf(stderr, "test2: passed\n"); |
|
195 |
timersub(&end, &start, &tv); |
|
196 |
fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec); |
|
197 |
|
|
198 |
fprintf(stderr, "running test3\n"); |
|
199 |
gettimeofday(&start, NULL); |
|
200 |
r = test3(n, t); |
|
201 |
if (r < 0){ |
|
202 |
fprintf(stderr, "test3: failed\n"); |
|
203 |
return -1; |
|
204 |
} |
|
205 |
gettimeofday(&end, NULL); |
|
206 |
fprintf(stderr, "test3: passed\n"); |
|
207 |
timersub(&end, &start, &tv); |
|
208 |
fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec); |
|
209 |
|
|
210 |
return 0; |
|
211 |
} |
Also available in: Unified diff