00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifndef WKF_THREADS_INC
00052 #define WKF_THREADS_INC 1
00053
00054 #ifdef __cplusplus
00055 extern "C" {
00056 #endif
00057
00058
00059 #if defined(_AIX) || defined(__APPLE__) || defined(_CRAY) || defined(__hpux) || defined(__irix) || defined(__linux) || defined(__osf__) || defined(__PARAGON__)
00060 #if !defined(USEPOSIXTHREADS)
00061 #define USEPOSIXTHREADS
00062 #endif
00063 #endif
00064
00065 #ifdef WKFTHREADS
00066 #ifdef USEPOSIXTHREADS
00067 #include <pthread.h>
00068
00069 typedef pthread_t wkf_thread_t;
00070 typedef pthread_mutex_t wkf_mutex_t;
00071 typedef pthread_cond_t wkf_cond_t;
00072 #endif
00073
00074
00075 #ifdef _MSC_VER
00076 #include <windows.h>
00077 typedef HANDLE wkf_thread_t;
00078 typedef CRITICAL_SECTION wkf_mutex_t;
00079
00080 #if 0 && (NTDDI_VERSION >= NTDDI_WS08 || _WIN32_WINNT > 0x0600)
00081
00082 #define WKFUSEWIN2008CONDVARS 1
00083 typedef CONDITION_VARIABLE wkf_cond_t;
00084 #else
00085
00086
00087
00088
00089
00090
00091 #if 1
00092 #define WKFUSEINTERLOCKEDATOMICOPS 1
00093 #endif
00094 #define WKF_COND_SIGNAL 0
00095 #define WKF_COND_BROADCAST 1
00096 typedef struct {
00097 LONG waiters;
00099 CRITICAL_SECTION waiters_lock;
00100 HANDLE events[2];
00101 } wkf_cond_t;
00102 #endif
00103
00104 #endif
00105 #endif
00106
00107
00108 #ifndef WKFTHREADS
00109 typedef int wkf_thread_t;
00110 typedef int wkf_mutex_t;
00111 typedef int wkf_cond_t;
00112 #endif
00113
00114
00115 typedef struct wkf_run_barrier_struct {
00116 int padding1[8];
00117 wkf_mutex_t lock;
00118 int n_clients;
00119 int n_waiting;
00120 int phase;
00121 void * (*fctn)(void *);
00122 void * parms;
00123 void * (*rslt)(void *);
00124 void * rsltparms;
00125 wkf_cond_t wait_cv;
00126 int padding2[8];
00127 } wkf_run_barrier_t;
00128
00129
00130
00131
00132
00134 int wkf_thread_numphysprocessors(void);
00135
00137 int wkf_thread_numprocessors(void);
00138
00140 int * wkf_cpu_affinitylist(int *cpuaffinitycount);
00141
00143 int wkf_thread_set_self_cpuaffinity(int cpu);
00144
00146 int wkf_thread_setconcurrency(int);
00147
00148
00149
00150
00151
00153 int wkf_thread_create(wkf_thread_t *, void * fctn(void *), void *);
00154
00156 int wkf_thread_join(wkf_thread_t, void **);
00157
00158
00159
00160
00161
00163 int wkf_mutex_init(wkf_mutex_t *);
00164
00166 int wkf_mutex_lock(wkf_mutex_t *);
00167
00169 int wkf_mutex_trylock(wkf_mutex_t *);
00170
00172 int wkf_mutex_spin_lock(wkf_mutex_t *);
00173
00175 int wkf_mutex_unlock(wkf_mutex_t *);
00176
00178 int wkf_mutex_destroy(wkf_mutex_t *);
00179
00180
00181
00182
00183
00185 int wkf_cond_init(wkf_cond_t *);
00186
00188 int wkf_cond_destroy(wkf_cond_t *);
00189
00191 int wkf_cond_wait(wkf_cond_t *, wkf_mutex_t *);
00192
00194 int wkf_cond_signal(wkf_cond_t *);
00195
00197 int wkf_cond_broadcast(wkf_cond_t *);
00198
00199
00200
00201
00202
00203
00205 int wkf_thread_run_barrier_init(wkf_run_barrier_t *barrier, int n_clients);
00206
00208 void wkf_thread_run_barrier_destroy(wkf_run_barrier_t *barrier);
00209
00211 void * (*wkf_thread_run_barrier(wkf_run_barrier_t *barrier,
00212 void * fctn(void*),
00213 void * parms,
00214 void **rsltparms))(void *);
00215
00217 int wkf_thread_run_barrier_poll(wkf_run_barrier_t *barrier);
00218
00219
00225 typedef struct wkf_tasktile_struct {
00226 int start;
00227 int end;
00228 } wkf_tasktile_t;
00229
00230
00231
00232
00233
00234 #define WKF_TILESTACK_EMPTY -1
00235
00239 typedef struct {
00240 wkf_mutex_t mtx;
00241 int growthrate;
00242 int size;
00243 int top;
00244 wkf_tasktile_t *s;
00245 } wkf_tilestack_t;
00246
00248 int wkf_tilestack_init(wkf_tilestack_t *s, int size);
00249
00251 void wkf_tilestack_destroy(wkf_tilestack_t *);
00252
00254 int wkf_tilestack_compact(wkf_tilestack_t *);
00255
00257 int wkf_tilestack_push(wkf_tilestack_t *, const wkf_tasktile_t *);
00258
00260 int wkf_tilestack_pop(wkf_tilestack_t *, wkf_tasktile_t *);
00261
00263 int wkf_tilestack_popall(wkf_tilestack_t *);
00264
00266 int wkf_tilestack_empty(wkf_tilestack_t *);
00267
00268
00274 #define WKF_SCHED_DONE -1
00275 #define WKF_SCHED_CONTINUE 0
00278 typedef struct wkf_shared_iterator_struct {
00279 wkf_mutex_t mtx;
00280 int start;
00281 int end;
00282 int current;
00283 int fatalerror;
00284 } wkf_shared_iterator_t;
00285
00287 int wkf_shared_iterator_init(wkf_shared_iterator_t *it);
00288
00290 int wkf_shared_iterator_destroy(wkf_shared_iterator_t *it);
00291
00293 int wkf_shared_iterator_set(wkf_shared_iterator_t *it, wkf_tasktile_t *tile);
00294
00301 int wkf_shared_iterator_next_tile(wkf_shared_iterator_t *it, int reqsize,
00302 wkf_tasktile_t *tile);
00303
00305 int wkf_shared_iterator_setfatalerror(wkf_shared_iterator_t *it);
00306
00308 int wkf_shared_iterator_getfatalerror(wkf_shared_iterator_t *it);
00309
00310
00311
00312
00313
00315 #define WKF_THREADPOOL_DEVLIST_CPUSONLY NULL
00316
00318 #define WKF_THREADPOOL_DEVID_CPU -1
00319
00321 typedef struct wkf_threadpool_workerdata_struct {
00322 int padding1[8];
00323 wkf_shared_iterator_t *iter;
00324 wkf_tilestack_t *errorstack;
00325 int threadid;
00326 int threadcount;
00327 int devid;
00328 float devspeed;
00329 void *parms;
00330 void *thrpool;
00331 int padding2[8];
00332 } wkf_threadpool_workerdata_t;
00333
00334 typedef struct wkf_threadpool_struct {
00335 int workercount;
00336 int *devlist;
00337 wkf_shared_iterator_t iter;
00338 wkf_tilestack_t errorstack;
00339 wkf_thread_t *threads;
00340 wkf_threadpool_workerdata_t *workerdata;
00341 wkf_run_barrier_t runbar;
00342 } wkf_threadpool_t;
00343
00345 wkf_threadpool_t * wkf_threadpool_create(int workercount, int *devlist);
00346
00348 int wkf_threadpool_launch(wkf_threadpool_t *thrpool,
00349 void *fctn(void *), void *parms, int blocking);
00350
00352 int wkf_threadpool_wait(wkf_threadpool_t *thrpool);
00353
00355 int wkf_threadpool_destroy(wkf_threadpool_t *thrpool);
00356
00358 int wkf_threadpool_get_workercount(wkf_threadpool_t *thrpool);
00359
00361 int wkf_threadpool_worker_getid(void *voiddata, int *threadid, int *threadcount);
00362
00364 int wkf_threadpool_worker_getdevid(void *voiddata, int *devid);
00365
00372 int wkf_threadpool_worker_setdevspeed(void *voiddata, float speed);
00373
00378 int wkf_threadpool_worker_getdevspeed(void *voiddata, float *speed);
00379
00384 int wkf_threadpool_worker_devscaletile(void *voiddata, int *tilesize);
00385
00387 int wkf_threadpool_worker_getdata(void *voiddata, void **clientdata);
00388
00390 int wkf_threadpool_sched_dynamic(wkf_threadpool_t *thrpool, wkf_tasktile_t *tile);
00391
00396 int wkf_threadpool_next_tile(void *thrpool, int reqsize, wkf_tasktile_t *tile);
00397
00402 int wkf_threadpool_tile_failed(void *thrpool, wkf_tasktile_t *tile);
00403
00405 int wkf_threadpool_setfatalerror(void *thrparms);
00406
00408 int wkf_threadpool_getfatalerror(void *thrparms);
00409
00410
00418 typedef struct wkf_threadlaunch_struct {
00419 int padding1[8];
00420 wkf_shared_iterator_t *iter;
00421 int threadid;
00422 int threadcount;
00423 void * clientdata;
00424 int padding2[8];
00425 } wkf_threadlaunch_t;
00426
00428 int wkf_threadlaunch(int numprocs, void *clientdata, void * fctn(void *),
00429 wkf_tasktile_t *tile);
00430
00432 int wkf_threadlaunch_getid(void *thrparms, int *threadid, int *threadcount);
00433
00435 int wkf_threadlaunch_getdata(void *thrparms, void **clientdata);
00436
00441 int wkf_threadlaunch_next_tile(void *voidparms, int reqsize,
00442 wkf_tasktile_t *tile);
00443
00445 int wkf_threadlaunch_setfatalerror(void *thrparms);
00446
00447
00448 #ifdef __cplusplus
00449 }
00450 #endif
00451
00452 #endif