1 // Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 2, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING. If not, write to the Free
16 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
28 #include <testsuite_common_types.h>
30 typedef int test_type
;
32 // The number of iterations to be performed.
33 int iterations
= 1000;
35 // TODO - restore Stefan's comment? i don't understand it. -- fwy
36 int insert_values
= 128;
41 Lock() {pthread_mutex_init(&mutex
, 0);}
42 ~Lock() {pthread_mutex_destroy(&mutex
);}
45 inline pthread_mutex_t
* operator&() {return &mutex
;}
48 inline void lock() {pthread_mutex_lock(&mutex
);}
49 inline void unlock() {pthread_mutex_unlock(&mutex
);}
53 Lock
& operator=(Lock
&);
56 pthread_mutex_t mutex
;
66 ~AutoLock() {lock
.unlock();}
70 AutoLock
& operator=(AutoLock
&);
76 template<typename Container
>
80 Queue() {pthread_cond_init(&condition
, 0);}
81 ~Queue() {pthread_cond_destroy(&condition
);}
84 void push_back(const typename
Container::value_type
& x
);
85 void swap(Container
& container
);
88 pthread_cond_t condition
;
93 template<typename Container
>
95 Queue
<Container
>::push_back(const typename
Container::value_type
& value
)
97 AutoLock
auto_lock(lock
);
98 const bool signal
= queue
.empty();
99 queue
.insert(queue
.end(), value
);
100 if (signal
) pthread_cond_signal(&condition
);
103 template<typename Container
>
105 Queue
<Container
>::swap(Container
& container
)
107 AutoLock
auto_lock(lock
);
108 while (queue
.empty()) pthread_cond_wait(&condition
, &lock
);
109 queue
.swap(container
);
114 // NB: Make this the last data member of an object defining operator()().
119 Attributes(int state
= PTHREAD_CREATE_JOINABLE
);
120 ~Attributes() {pthread_attr_destroy(&attributes
);}
123 inline pthread_attr_t
* operator&() {return &attributes
;}
126 pthread_attr_t attributes
;
130 Thread() {thread
= pthread_self();}
134 template <typename ThreadOwner
>
135 void create(ThreadOwner
* owner
);
141 Thread::Attributes::Attributes(int state
)
143 pthread_attr_init(&attributes
);
144 pthread_attr_setdetachstate(&attributes
, state
);
149 if (!pthread_equal(thread
, pthread_self()))
150 pthread_join(thread
, 0);
153 template<typename ThreadOwner
>
155 create_thread(void* _this
)
157 ThreadOwner
* owner
= static_cast<ThreadOwner
*>(_this
);
162 template<typename ThreadOwner
>
164 Thread::create(ThreadOwner
* owner
)
166 Thread::Attributes attributes
;
167 pthread_create(&thread
, &attributes
, create_thread
<ThreadOwner
>, owner
);
170 template<typename Container
>
174 Consumer(Queue
<Container
>& _queue
)
176 {thread
.create(this);}
182 Queue
<Container
>& queue
;
186 template<typename Container
>
188 Consumer
<Container
>::operator()()
190 for (int j
= insert_values
* iterations
; j
> 0;)
193 queue
.swap(container
);
194 j
-= container
.size();
198 template<typename TestType
>
199 struct Value
: public std::pair
<TestType
, TestType
>
202 : std::pair
<TestType
, TestType
>(0, 0)
205 inline Value
operator++() {return ++this->first
, *this;}
206 inline operator TestType() const {return this->first
;}
209 template<typename Container
>
210 class ProducerConsumer
: private Queue
<Container
>
213 ProducerConsumer() {thread
.create(this);}
222 template<typename Container
>
224 ProducerConsumer
<Container
>::operator()()
226 Consumer
<Container
> consumer(*this);
227 Value
<test_type
> test_value
;
228 for (int j
= insert_values
* iterations
; j
-- > 0;)
229 this->push_back(++test_value
);
232 template<typename Container
, int Iter
>
236 ProducerConsumer
<Container
> pc1
;
237 ProducerConsumer
<Container
> pc2
;
244 #define thread_type true
247 using __gnu_test::sequence_containers
;
248 typedef sequence_containers
<test_type
, thread_type
>::type container_types
;
250 typedef test_sequence
<thread_type
> test_type
;
251 test_type
test("producer_consumer_sequence");
252 __gnu_cxx::apply
<test_type
, container_types
> applier
;