sel_ldr: Remove support for rodata segment at start of executable
[nativeclient.git] / common / worker.h
blob3ef6dd7ea8e7e3c7c16b0ca492f50eca2c9feedc
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
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
14 * distribution.
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)
48 public:
49 void SetCounter(int v);
50 int DecCounter();
51 void PostWork() { sem_post(&work_); }
52 void PostWorkAll()
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);
58 void JoinAll();
59 WorkerThreadManager();
60 ~WorkerThreadManager() { ; }
61 private:
62 // pthread_attr_t attr_;
63 pthread_t *threads_;
64 pthread_mutex_t mutex_;
65 int counter_;
66 int num_threads_;
67 sem_t work_;
68 sem_t done_;
69 #else
70 public:
71 void SetCounter(int v) { ; }
72 int DecCounter() { ; }
73 void PostWork() { ; }
74 void PostWorkAll() { ; }
75 void WaitWork() { ; }
76 void PostDone() { ; }
77 void WaitDone() { ; }
78 bool CreateThreadPool(int num, void *(*entry)(void *data), void *data) { ; }
79 void JoinAll() { ; }
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_);
91 { counter_ = v; }
92 pthread_mutex_unlock(&mutex_);
96 // Decrements and get the value of the mutex protected counter
97 inline int WorkerThreadManager::DecCounter() {
98 int v;
99 pthread_mutex_lock(&mutex_);
100 { v = --counter_; }
101 pthread_mutex_unlock(&mutex_);
102 return v;
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) {
110 int status;
111 status = pthread_mutex_init(&mutex_, NULL);
112 if (0 != status) {
113 fprintf(stderr, "Failed to initialize mutex!\n");
114 exit(-1);
116 status = sem_init(&work_, 0, 0);
117 if (-1 == status) {
118 fprintf(stderr, "Failed to initialize semaphore!\n");
119 exit(-1);
121 status = sem_init(&done_, 0, 0);
122 if (-1 == status) {
123 fprintf(stderr, "Failed to initialize semaphore!\n");
124 exit(-1);
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");
135 return true;
137 // create worker threads
138 threads_ = new pthread_t[num];
139 num_threads_ = 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);
143 if (0 != status) {
144 fprintf(stderr, "Failed to allocate thread %d!\n", i);
145 return false;
148 return true;
152 // join up all the threads in the pool
153 inline void WorkerThreadManager::JoinAll() {
154 void *retval;
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_