1 // Copyright (C) 2003, 2004, 2005, 2006, 2009 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 3, 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 COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
19 #include <testsuite_performance.h>
21 typedef int test_type
;
23 // The number of iterations to be performed.
24 int iterations
= 1000;
26 // TODO - restore Stefan's comment? i don't understand it. -- fwy
27 int insert_values
= 128;
32 Lock() {pthread_mutex_init(&mutex
, 0);}
33 ~Lock() {pthread_mutex_destroy(&mutex
);}
36 inline pthread_mutex_t
* operator&() {return &mutex
;}
39 inline void lock() {pthread_mutex_lock(&mutex
);}
40 inline void unlock() {pthread_mutex_unlock(&mutex
);}
44 Lock
& operator=(Lock
&);
47 pthread_mutex_t mutex
;
57 ~AutoLock() {lock
.unlock();}
61 AutoLock
& operator=(AutoLock
&);
67 template<typename Container
>
71 Queue() {pthread_cond_init(&condition
, 0);}
72 ~Queue() {pthread_cond_destroy(&condition
);}
75 void push_back(const typename
Container::value_type
& x
);
76 void swap(Container
& container
);
79 pthread_cond_t condition
;
84 template<typename Container
>
86 Queue
<Container
>::push_back(const typename
Container::value_type
& value
)
88 AutoLock
auto_lock(lock
);
89 const bool signal
= queue
.empty();
90 queue
.insert(queue
.end(), value
);
91 if (signal
) pthread_cond_signal(&condition
);
94 template<typename Container
>
96 Queue
<Container
>::swap(Container
& container
)
98 AutoLock
auto_lock(lock
);
99 while (queue
.empty()) pthread_cond_wait(&condition
, &lock
);
100 queue
.swap(container
);
105 // NB: Make this the last data member of an object defining operator()().
110 Attributes(int state
= PTHREAD_CREATE_JOINABLE
);
111 ~Attributes() {pthread_attr_destroy(&attributes
);}
114 inline pthread_attr_t
* operator&() {return &attributes
;}
117 pthread_attr_t attributes
;
121 Thread() {thread
= pthread_self();}
125 template <typename ThreadOwner
>
126 void create(ThreadOwner
* owner
);
132 Thread::Attributes::Attributes(int state
)
134 pthread_attr_init(&attributes
);
135 pthread_attr_setdetachstate(&attributes
, state
);
140 if (!pthread_equal(thread
, pthread_self()))
141 pthread_join(thread
, 0);
144 template<typename ThreadOwner
>
146 create_thread(void* _this
)
148 ThreadOwner
* owner
= static_cast<ThreadOwner
*>(_this
);
153 template<typename ThreadOwner
>
155 Thread::create(ThreadOwner
* owner
)
157 Thread::Attributes attributes
;
158 pthread_create(&thread
, &attributes
, create_thread
<ThreadOwner
>, owner
);
161 template<typename Container
>
165 Consumer(Queue
<Container
>& _queue
)
167 {thread
.create(this);}
173 Queue
<Container
>& queue
;
177 template<typename Container
>
179 Consumer
<Container
>::operator()()
181 for (int j
= insert_values
* iterations
; j
> 0;)
184 queue
.swap(container
);
185 j
-= container
.size();
189 template<typename TestType
>
190 struct Value
: public std::pair
<TestType
, TestType
>
193 : std::pair
<TestType
, TestType
>(0, 0)
196 inline Value
operator++() {return ++this->first
, *this;}
197 inline operator TestType() const {return this->first
;}
200 template<typename Container
>
201 class ProducerConsumer
: private Queue
<Container
>
204 ProducerConsumer() {thread
.create(this);}
213 template<typename Container
>
215 ProducerConsumer
<Container
>::operator()()
217 Consumer
<Container
> consumer(*this);
218 Value
<test_type
> test_value
;
219 for (int j
= insert_values
* iterations
; j
-- > 0;)
220 this->push_back(++test_value
);
223 template<typename Container
, int Iter
>
227 ProducerConsumer
<Container
> pc1
;
228 ProducerConsumer
<Container
> pc2
;
235 #define thread_type true
238 using __gnu_test::sequence_containers
;
239 typedef sequence_containers
<test_type
, thread_type
>::type container_types
;
241 typedef test_sequence
<thread_type
> test_type
;
242 test_type
test("producer_consumer_sequence");
243 __gnu_cxx::typelist::apply(test
, container_types());