Simple tools for multi threading / objects in plain C Snapshot
|
00001 #ifndef __TPOOL_H__ 00002 #define __TPOOL_H__ 00003 00004 #include <tutils/tqueue.h> 00005 #include <tutils/cbarrier.h> 00006 00007 struct tagRUNNABLE; 00008 struct tagTHREADPOOL; 00009 00010 //--- 00011 00012 typedef void (*RUNNABLE_HANDLER) (struct tagRUNNABLE *request); 00013 00014 00015 /** 00016 @defgroup RUNNABLE 00017 00018 @brief an interface to run a unit of work. 00019 00020 Acts as a work request for thread pool 00021 Includes a callback that is invoked in order to process the request. 00022 00023 Very similar to java concept of java.lang.Runnable. 00024 00025 @{ 00026 */ 00027 typedef struct tagRUNNABLE { 00028 RUNNABLE_HANDLER handle_request; 00029 RUNNABLE_HANDLER free_request; 00030 } RUNNABLE; 00031 00032 /** 00033 @brief constructs a RUNNABLE instance 00034 */ 00035 void RUNNABLE_init(RUNNABLE *runnable, RUNNABLE_HANDLER handler, RUNNABLE_HANDLER free_request ); 00036 00037 /** 00038 @brief free a RUNNABLE instance 00039 */ 00040 void RUNNABLE_free(RUNNABLE *runnable ); 00041 00042 /** 00043 @} 00044 */ 00045 00046 // --- 00047 00048 /** 00049 00050 @defgroup THREADPOOL 00051 00052 @brief a thread pool with fixed number of worker threads. 00053 00054 The pool has a request queue: New requests are enqueued into it, the worker threads dequeue a work request and invoke the 'run' method of work request. 00055 00056 One creation of thread pool the following parameters are specified 00057 - number of worker threads in thread pool. 00058 - maximum number of entries in request queue (or -1 if number of requests is unlimited). 00059 00060 It is very important to set a reasonable size limit on the request queue; 00061 An unlimited queue can often lead to out of memory conditions: If work requests 00062 arrive at a rate faster than what can be processed, a bounded request buffer guards against a situation where the system is run at a load rate that is higher then it's capacity. 00063 00064 In this situation the request queue acts as a bounded buffer; it should 00065 be able to account for temporary fluctuations of the load; it can accomodate temporary peaks (i.e. short periods of time when the load is higher then the peak load), on condition that the request load later falls back to normal. 00066 00067 You might find this class similar to java class java.util.concurrent.ThreadPoolExicutor when used with a thread pool size. 00068 00069 @{ 00070 */ 00071 typedef struct tagTHREADPOOL { 00072 int num_threads; 00073 TQUEUE request_queue; 00074 CYCLIC_BARRIER all_finished; 00075 RUNNABLE_HANDLER process_result; 00076 00077 } THREADPOOL; 00078 00079 /** 00080 @brief constructs a thread pool and starts it. 00081 00082 The method 00083 - creates request queue 00084 - runs fixed number of worker threads 00085 00086 The worker thread 00087 - fetches a work request from the request queue 00088 - invokes the handle_request callback stpred in the work request 00089 - if process_result callback has been registered: invokes process_result 00090 callback (in order to have common policy of processing the results). 00091 00092 @param process_result a callback that receives work request after invoking it's run method. Value can be 0 (in this case it is not invoked) 00093 @param queue_size limit on the request queue (for details see THREADPOOL ) 00094 @param num_threads number of worker threads 00095 @param stack_size_kb Size of thread pool stack in kilobytes (-1 if default stack size) 00096 00097 */ 00098 THREADPOOL *THREADPOOL_init( RUNNABLE_HANDLER process_result, int queue_size, int num_threads, int stack_size_kb ); 00099 00100 /* 00101 @brief shuts down the thread pool and frees it. 00102 00103 Shuts down the thread pool. 00104 - Requests shut down of worker threads. Please not that all requests queued at the time of this call will be discarded. 00105 - Blocks untill the last worker thread has finished. 00106 00107 */ 00108 void THREADPOOL_close( THREADPOOL *pool ); 00109 00110 /** 00111 @brief posts a work request to the pool; blocks if request queue limit is reached 00112 00113 A request is always queued. If request queue limit is reached then this method blocks until the size of the queue falls back, In this case the request is enqueued and this method returns. 00114 00115 Returns 0 on success, -1 on failure (can't allocate memory for request) 00116 */ 00117 int THREADPOOL_send_block_on_queue_full( THREADPOOL *pool, RUNNABLE *request); 00118 00119 /** 00120 @brief posts a work request to the pool; blocks if request queue limit is reached 00121 00122 A request is queued if the request queue did not reach its size limit. 00123 If request queue limit is reached then this method returns an error. 00124 00125 Returns 0 on success, -1 on failure 00126 */ 00127 00128 int THREADPOOL_send_fail_on_queue_full( THREADPOOL *pool, RUNNABLE *request); 00129 00130 /** 00131 @} 00132 */ 00133 00134 00135 #endif 00136 00137