2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
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
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // Worker thread class
33 // Used by some of the multi-threaded demos.
35 #ifndef NATIVE_CLIENT_TESTS_COMMON_WORKER_H_
36 #define NATIVE_CLIENT_TESTS_COMMON_WORKER_H_
38 // typdef helper for pthread_create
39 typedef void* (*Entry
)(void *data
);
41 // WorkerThreadManager is a class to manage N worker threads
42 // It includes a mutex protected counter so each thread
43 // can derive work from a uid. It also includes two semaphores
44 // used to synchronize the workers and the main thread.
46 class WorkerThreadManager
{
47 #if defined(HAVE_THREADS)
49 void SetCounter(int v
);
51 void PostWork() { sem_post(&work_
); }
53 { for (int i
= 0; i
< num_threads_
; ++i
) sem_post(&work_
); }
54 void WaitWork() { sem_wait(&work_
); }
55 void PostDone() { sem_post(&done_
); }
56 void WaitDone() { sem_wait(&done_
); }
57 bool CreateThreadPool(int num
, void *(*entry
)(void *data
), void *data
);
59 WorkerThreadManager();
60 ~WorkerThreadManager() { ; }
62 // pthread_attr_t attr_;
64 pthread_mutex_t mutex_
;
71 void SetCounter(int v
) { ; }
72 int DecCounter() { ; }
74 void PostWorkAll() { ; }
78 bool CreateThreadPool(int num
, void *(*entry
)(void *data
), void *data
) { ; }
80 WorkerThreadManager() { ; }
81 ~WorkerThreadManager() { ; }
82 #endif // HAVE_THREADS
86 #if defined(HAVE_THREADS)
88 // Sets the mutex protected counter to specified value.
89 inline void WorkerThreadManager::SetCounter(int v
) {
90 pthread_mutex_lock(&mutex_
);
92 pthread_mutex_unlock(&mutex_
);
96 // Decrements and get the value of the mutex protected counter
97 inline int WorkerThreadManager::DecCounter() {
99 pthread_mutex_lock(&mutex_
);
101 pthread_mutex_unlock(&mutex_
);
106 // Initializes mutex & semaphores used by worker manager.
107 // The thread poll will be created later.
108 inline WorkerThreadManager::WorkerThreadManager()
109 : threads_(NULL
), counter_(0), num_threads_(0) {
111 status
= pthread_mutex_init(&mutex_
, NULL
);
113 fprintf(stderr
, "Failed to initialize mutex!\n");
116 status
= sem_init(&work_
, 0, 0);
118 fprintf(stderr
, "Failed to initialize semaphore!\n");
121 status
= sem_init(&done_
, 0, 0);
123 fprintf(stderr
, "Failed to initialize semaphore!\n");
129 // Creates a pool of detached worker threads.
130 inline bool WorkerThreadManager::CreateThreadPool(int num
,
131 Entry entry
, void *data
) {
132 if (NULL
!= threads_
) {
133 // shouldn't happen, but we should at least tell user
134 fprintf(stderr
, "WARNING: A thread pool has already been created!\n");
137 // create worker threads
138 threads_
= new pthread_t
[num
];
140 printf("Starting up %d worker threads.\n", num
);
141 for (int i
= 0; i
< num
; ++i
) {
142 int status
= pthread_create(&threads_
[i
], NULL
, entry
, data
);
144 fprintf(stderr
, "Failed to allocate thread %d!\n", i
);
152 // join up all the threads in the pool
153 inline void WorkerThreadManager::JoinAll() {
155 for (int i
= 0; i
< num_threads_
; ++i
) {
156 pthread_join(threads_
[i
], &retval
);
160 #endif // HAVE_THREADS
161 #endif // NATIVE_CLIENT_TESTS_COMMON_WORKER_H_