2
* Copyright (c) 2001-2004 Jakub Jermar
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
#include <proc/thread.h>
35
#include <synch/waitq.h>
36
#include <synch/semaphore.h>
42
static semaphore_t sem;
44
static waitq_t can_start;
45
static atomic_t items_produced;
46
static atomic_t items_consumed;
48
static void producer(void *arg)
50
thread_detach(THREAD);
52
waitq_sleep(&can_start);
55
atomic_inc(&items_produced);
60
static void consumer(void *arg)
62
thread_detach(THREAD);
64
waitq_sleep(&can_start);
67
atomic_inc(&items_consumed);
72
char *test_semaphore1(void)
75
int consumers, producers;
77
waitq_initialize(&can_start);
78
semaphore_initialize(&sem, AT_ONCE);
80
for (i = 1; i <= 3; i++) {
83
atomic_set(&items_produced, 0);
84
atomic_set(&items_consumed, 0);
86
consumers = i * CONSUMERS;
87
producers = (4 - i) * PRODUCERS;
89
TPRINTF("Creating %d consumers and %d producers...", consumers, producers);
91
for (j = 0; j < (CONSUMERS + PRODUCERS) / 2; j++) {
92
for (k = 0; k < i; k++) {
93
thrd = thread_create(consumer, NULL, TASK, 0, "consumer", false);
97
TPRINTF("could not create consumer %d\n", i);
99
for (k = 0; k < (4 - i); k++) {
100
thrd = thread_create(producer, NULL, TASK, 0, "producer", false);
104
TPRINTF("could not create producer %d\n", i);
111
waitq_wakeup(&can_start, WAKEUP_ALL);
113
while ((items_consumed.count != consumers) || (items_produced.count != producers)) {
114
TPRINTF("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);