25 #define DEFAULT_WORKERS 0
33 pthread_mutex_t mutex;
37 static int num_workers;
38 static struct worker *workers;
39 static pthread_cond_t worker_cond;
40 static pthread_mutex_t worker_mutex;
44 static void *worker(
void *arg)
46 struct worker *w = arg;
49 pthread_mutex_lock(&w->mutex);
51 pthread_cond_wait(&w->cond, &w->mutex);
53 (*w->func)(w->closure);
58 pthread_mutex_unlock(&w->mutex);
59 pthread_cond_signal(&w->cond);
60 pthread_cond_signal(&worker_cond);
66 static struct worker *get_worker(
void)
70 for (i = 0; i < num_workers; i++) {
71 struct worker *w = &workers[i];
80 void G_begin_execute(
void (*func)(
void *),
void *closure,
void **ref,
int force)
87 pthread_mutex_lock(&worker_mutex);
89 while (w = get_worker(), force && num_workers > 0 && !w)
90 pthread_cond_wait(&worker_cond, &worker_mutex);
94 pthread_mutex_unlock(&worker_mutex);
99 pthread_mutex_lock(&w->mutex);
101 w->closure = closure;
103 pthread_cond_signal(&w->cond);
104 pthread_mutex_unlock(&w->mutex);
106 pthread_mutex_unlock(&worker_mutex);
111 struct worker *w = *ref;
116 pthread_mutex_lock(&w->mutex);
118 pthread_cond_wait(&w->cond, &w->mutex);
119 pthread_mutex_unlock(&w->mutex);
124 const char *p = getenv(
"WORKERS");
127 pthread_mutex_init(&worker_mutex,
NULL);
128 pthread_cond_init(&worker_cond,
NULL);
130 num_workers = p ? atoi(p) : DEFAULT_WORKERS;
131 workers =
G_calloc(num_workers,
sizeof(
struct worker));
133 for (i = 0; i < num_workers; i++) {
134 struct worker *w = &workers[i];
136 pthread_mutex_init(&w->mutex,
NULL);
137 pthread_cond_init(&w->cond,
NULL);
138 pthread_create(&w->thread,
NULL, worker, w);
146 for (i = 0; i < num_workers; i++) {
147 struct worker *w = &workers[i];
150 pthread_cancel(w->thread);
153 for (i = 0; i < num_workers; i++) {
154 struct worker *w = &workers[i];
156 pthread_join(w->thread,
NULL);
157 pthread_mutex_destroy(&w->mutex);
158 pthread_cond_destroy(&w->cond);
161 pthread_mutex_destroy(&worker_mutex);
162 pthread_cond_destroy(&worker_cond);
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
void G_end_execute(void **ref UNUSED)
void G_init_workers(void)
void G_finish_workers(void)
void G_begin_execute(void(*func)(void *), void *closure, void **ref UNUSED, int force UNUSED)