Back to home page

Enduro/X

 
 

    


0001 /**********************************
0002  * @author      Johan Hanssen Seferidis
0003  * License:     MIT
0004  *
0005  **********************************/
0006 
0007 #ifndef _THPOOL_
0008 #define _THPOOL_
0009 
0010 #ifdef __cplusplus
0011 extern "C" {
0012 #endif
0013 
0014 /* =================================== API ======================================= */
0015 
0016     
0017 /**
0018  * Add job only if no job queue len exists (flag)
0019  * In case if job exists, on return this indicates
0020  * that job was not added, due to fact that job was already
0021  * in q
0022  */
0023 #define NDRX_THPOOL_ONEJOB          0x00000001
0024 
0025 typedef struct thpool_* threadpool;
0026 
0027 /** thread pool init call */
0028 typedef  int (*ndrx_thpool_tpsvrthrinit_t)(int argc, char **argv);
0029 
0030 /** thread done call if any */
0031 typedef  void (*ndrx_thpool_tpsvrthrdone_t)(void);
0032 
0033 /**
0034  * @brief  Initialize threadpool
0035  *
0036  * Initializes a threadpool. This function will not return untill all
0037  * threads have initialized successfully.
0038  *
0039  * @example
0040  *
0041  *    ..
0042  *    threadpool thpool;                     //First we declare a threadpool
0043  *    thpool = thpool_init(4);               //then we initialize it to 4 threads
0044  *    ..
0045  *
0046  * @param num_threads   number of threads to be created in the threadpool
0047  * @param p_ret return of threads
0048  * @param pf_init thread init function
0049  * @param pf_done thread done function
0050  * @param argc command line argument count
0051  * @param argv cli arguments for init func
0052  * @return threadpool    created threadpool on success,
0053  *                       NULL on error
0054  */
0055 threadpool ndrx_thpool_init(int num_threads, int *p_ret, 
0056         ndrx_thpool_tpsvrthrinit_t pf_init, ndrx_thpool_tpsvrthrdone_t pf_done,
0057         int argc, char **argv);
0058 
0059 
0060 /**
0061  * @brief Add work to the job queue
0062  *
0063  * Takes an action and its argument and adds it to the threadpool's job queue.
0064  * If you want to add to work a function with more than one arguments then
0065  * a way to implement this is by passing a pointer to a structure.
0066  *
0067  * NOTICE: You have to cast both the function and argument to not get warnings.
0068  *
0069  * @example
0070  *
0071  *    void print_num(int num){
0072  *       printf("%d\n", num);
0073  *    }
0074  *
0075  *    int main() {
0076  *       ..
0077  *       int a = 10;
0078  *       thpool_add_work(thpool, (void*)print_num, (void*)a);
0079  *       ..
0080  *    }
0081  *
0082  * @param  threadpool    threadpool to which the work will be added
0083  * @param  function_p    pointer to function to add as work
0084  * @param  arg_p         pointer to an argument
0085  * @return 0 on successs, -1 otherwise.
0086  */
0087 int ndrx_thpool_add_work(threadpool, void (*function_p)(void*, int *), void* arg_p);
0088 
0089 
0090 /**
0091  * Add work with flags
0092  * @param thpool_p thread pool on which we operate
0093  * @param function_p work callback work callback func
0094  * @param arg_p data to func
0095  * @param flags
0096  * @param max_len if set > 0, then wait until enqueue jobs are less than this number
0097  * @return EXSUCCEED/EXFAIL
0098  */
0099 int ndrx_thpool_add_work2(threadpool, void (*function_p)(void*, int *), void* arg_p, long flags, int max_len);
0100 
0101 /**
0102  * @brief Wait for all queued jobs to finish
0103  *
0104  * Will wait for all jobs - both queued and currently running to finish.
0105  * Once the queue is empty and all work has completed, the calling thread
0106  * (probably the main program) will continue.
0107  *
0108  * Smart polling is used in wait. The polling is initially 0 - meaning that
0109  * there is virtually no polling at all. If after 1 seconds the threads
0110  * haven't finished, the polling interval starts growing exponentially
0111  * untill it reaches max_secs seconds. Then it jumps down to a maximum polling
0112  * interval assuming that heavy processing is being used in the threadpool.
0113  *
0114  * @example
0115  *
0116  *    ..
0117  *    threadpool thpool = thpool_init(4);
0118  *    ..
0119  *    // Add a bunch of work
0120  *    ..
0121  *    thpool_wait(thpool);
0122  *    puts("All added work has finished");
0123  *    ..
0124  *
0125  * @param threadpool     the threadpool to wait for
0126  * @return nothing
0127  */
0128 void ndrx_thpool_wait(threadpool);
0129 
0130 /**
0131  * Wait for one thread to become free
0132  * @param thpool_p thread pool
0133  */
0134 void ndrx_thpool_wait_one(threadpool);
0135 
0136 /**
0137  * Get number of non working and non job scheduled threads
0138  * @param threadpool thread pool
0139  * @return number of threads fully free (no job scheduled)
0140  */
0141 int ndrx_thpool_nr_not_working(threadpool);
0142 
0143 /**
0144  * Wait for jobs to be less than given number
0145  * @param thpool_p thread pool which to work
0146  * @param less_than jobs/working threads to be less than this number
0147  * @param timeout number of milliseconds to wait
0148  * @param cond ptr to variable, if becomes true, terminate the wait 
0149  * @return EXFAIL (something bad has happended), EXSUCCEED (timedout), EXTRUE (got
0150  *  condition)
0151  */
0152 int ndrx_thpool_timedwait_less(threadpool, int less_than, long timeout, int *cond);
0153 
0154 /**
0155  * Signal on pool / waiting on one
0156  * @param thpool_p thread pool which to work
0157  */
0158 void ndrx_thpool_signal_one(threadpool);
0159 
0160 /**
0161  * @brief Destroy the threadpool
0162  *
0163  * This will wait for the currently active threads to finish and then 'kill'
0164  * the whole threadpool to free up memory.
0165  *
0166  * @example
0167  * int main() {
0168  *    threadpool thpool1 = thpool_init(2);
0169  *    threadpool thpool2 = thpool_init(2);
0170  *    ..
0171  *    thpool_destroy(thpool1);
0172  *    ..
0173  *    return 0;
0174  * }
0175  *
0176  * @param threadpool     the threadpool to destroy
0177  * @return nothing
0178  */
0179 void ndrx_thpool_destroy(threadpool);
0180 
0181 
0182 #ifdef __cplusplus
0183 }
0184 #endif
0185 
0186 #endif