Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

WKFThreads.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  * RCS INFORMATION:
00003  *
00004  *      $RCSfile: WKFThreads.h,v $
00005  *      $Author: johns $        $Locker:  $             $State: Exp $
00006  *      $Revision: 1.9 $       $Date: 2011/02/07 19:57:51 $
00007  *
00008  ***************************************************************************
00009  * WKFThreads.h - code for spawning threads on various platforms.
00010  *                Code donated by John Stone, john.stone@gmail.com
00011  *                This code was originally written for the
00012  *                Tachyon Parallel/Multiprocessor Ray Tracer.
00013  *                Improvements have been donated by Mr. Stone on an
00014  *                ongoing basis.  This code is provided under the
00015  *                three clause BSD Open Source License.
00016  *
00017  * NOTE: The latest version of this source file can be re-generated by
00018  *       running the sequence of 'sed' commands shown at the top of the
00019  *       "threads.c" file within the Tachyon source distribution.
00020  *
00021  ***************************************************************************/
00022 /* Tachyon copyright reproduced below */
00023 /*
00024  * Copyright (c) 1994-2011 John E. Stone
00025  * All rights reserved.
00026  *
00027  * Redistribution and use in source and binary forms, with or without
00028  * modification, are permitted provided that the following conditions
00029  * are met:
00030  * 1. Redistributions of source code must retain the above copyright
00031  *    notice, this list of conditions and the following disclaimer.
00032  * 2. Redistributions in binary form must reproduce the above copyright
00033  *    notice, this list of conditions and the following disclaimer in the
00034  *    documentation and/or other materials provided with the distribution.
00035  * 3. The name of the author may not be used to endorse or promote products
00036  *    derived from this software without specific prior written permission.
00037  *
00038  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00039  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00040  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00041  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00042  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00043  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00044  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00045  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00046  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00047  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00048  * SUCH DAMAGE.
00049  */
00050 
00051 #ifndef WKF_THREADS_INC
00052 #define WKF_THREADS_INC 1
00053 
00054 #ifdef __cplusplus
00055 extern "C" {
00056 #endif
00057 
00058 /* POSIX Threads */
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 /* Use native condition variables only with Windows Server 2008 and newer... */
00082 #define WKFUSEWIN2008CONDVARS 1
00083 typedef CONDITION_VARIABLE wkf_cond_t;
00084 #else
00085 /* Every version of Windows prior to Vista/WS2008 must emulate */
00086 /* variables using manually resettable events or other schemes */
00087 
00088 /* For higher performance, use interlocked memory operations   */
00089 /* rather than locking/unlocking mutexes when manipulating     */
00090 /* internal state.                                             */
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 /* _MSC_VER */
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  * Routines for querying processor counts, and managing CPU affinity
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  * Thread management
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  * Mutex management
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  * Condition variable management
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  * This is a symmetric barrier routine designed to be used
00202  * in implementing a sleepable thread pool.
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  * tile stack
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  * Thread pool.
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

Generated on Wed May 23 01:50:37 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002