#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include "flint.h"
#if FLINT_USES_PTHREAD
#include <pthread.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
#if FLINT_USES_PTHREAD
pthread_t pth;
pthread_mutex_t mutex;
pthread_cond_t sleep1;
pthread_cond_t sleep2;
#endif
volatile int idx;
volatile int available;
volatile int max_workers;
void (* fxn)(void *);
void * fxnarg;
volatile int working;
volatile int exit;
} thread_pool_entry_struct;
typedef thread_pool_entry_struct thread_pool_entry_t[1];
typedef struct
{
#if FLINT_USES_CPUSET && FLINT_USES_PTHREAD
void * original_affinity;
#endif
#if FLINT_USES_PTHREAD
pthread_mutex_t mutex;
#endif
thread_pool_entry_struct * tdata;
slong length;
} thread_pool_struct;
typedef thread_pool_struct thread_pool_t[1];
FLINT_DLL extern thread_pool_t global_thread_pool;
FLINT_DLL extern int global_thread_pool_initialized;
void * thread_pool_idle_loop(void * varg);
void thread_pool_init(thread_pool_t T, slong size);
int thread_pool_set_affinity(thread_pool_t T,
int * cpus, slong length);
int thread_pool_restore_affinity(thread_pool_t T);
slong thread_pool_get_size(thread_pool_t T);
int thread_pool_set_size(thread_pool_t T, slong new_size);
slong thread_pool_request(thread_pool_t T,
thread_pool_handle * out, slong requested);
void thread_pool_wake(thread_pool_t T, thread_pool_handle i,
int max_workers, void (*f)(void*), void * a);
void thread_pool_wait(thread_pool_t T, thread_pool_handle i);
void thread_pool_give_back(thread_pool_t T, thread_pool_handle i);
void thread_pool_clear(thread_pool_t T);
void _thread_pool_distribute_work_2(slong start, slong stop,
slong * Astart, slong * Astop, slong Alen,
slong * Bstart, slong * Bstop, slong FLINT_UNUSED(Blen));
ulong _thread_pool_find_work_2(ulong a, ulong alpha,
ulong b, ulong beta, ulong yn, ulong yd);
#ifdef __cplusplus
}
#endif
#endif