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