Simple tools for multi threading / objects in plain C Snapshot
tpool.h
Go to the documentation of this file.
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