libsheepy

C lib for handling text files, strings and json like data structure with an object oriented system
git clone https://spartatek.se/git/libsheepy.git
Log | Files | Refs | README | LICENSE

tpool.h (5482B)


      1 /**********************************
      2  * @author      Johan Hanssen Seferidis
      3  * License:     MIT
      4  *
      5  **********************************/
      6 
      7 #pragma once
      8 
      9 #if (__OpenBSD__)
     10 // have to include pthread.h for pthread_mutex_t in OpenBSD with GCC 4.9.4
     11 #include "pthread.h"
     12 #endif
     13 
     14 #ifdef __cplusplus
     15 extern "C" {
     16 #endif
     17 
     18 // locks, max 512 threads
     19 #define tpoolLockCount 512
     20 extern pthread_mutex_t tpoolLocks[tpoolLockCount]; // only one thread can have the lock
     21 
     22 // use lock in the tpoolLocks array
     23 void tpoolLock(int position);
     24 // unlock a lock in the tpoolLocks array
     25 void tpoolUlock(int position);
     26 
     27 typedef struct {
     28   union {
     29     char *s;
     30   };
     31   union {
     32     char *s2;
     33   };
     34   // return value
     35   union {
     36     char **list;
     37     int status;
     38   };
     39   void (*cb)(void*);
     40   void *cbArgs;
     41   void *channel;
     42 } tpoolArgs;
     43 
     44 #define tpoolAdd(task, args) tpool_add_work(tpool, task, args)
     45 #define tpoolWait tpool_wait(tpool)
     46 #define tpoolKill tpool_destroy(tpool)
     47 #define tpoolPause tpool_pause(tpool)
     48 #define tpoolResume tpool_resume(tpool)
     49 #define tpoolNum tpool_num_threads_working(tpool)
     50 
     51 /* =================================== API ======================================= */
     52 
     53 
     54 typedef struct tpool_* threadpool;
     55 extern threadpool tpool;
     56 
     57 /**
     58  * @brief  Initialize threadpool
     59  *
     60  * Initializes a threadpool. This function will not return untill all
     61  * threads have initialized successfully.
     62  *
     63  * @example
     64  *
     65  *    ..
     66  *    threadpool tpool;                     //First we declare a threadpool
     67  *    tpool = tpool_init(4);               //then we initialize it to 4 threads
     68  *    ..
     69  *
     70  * @param  num_threads   number of threads to be created in the threadpool
     71  * @return threadpool    created threadpool on success,
     72  *                       NULL on error
     73  */
     74 threadpool tpool_init(int num_threads);
     75 
     76 
     77 /**
     78  * @brief Add work to the job queue
     79  *
     80  * Takes an action and its argument and adds it to the threadpool's job queue.
     81  * If you want to add to work a function with more than one arguments then
     82  * a way to implement this is by passing a pointer to a structure.
     83  *
     84  * NOTICE: You have to cast both the function and argument to not get warnings.
     85  *
     86  * @example
     87  *
     88  *    void print_num(int num){
     89  *       printf("%d\n", num);
     90  *    }
     91  *
     92  *    int main() {
     93  *       ..
     94  *       int a = 10;
     95  *       tpool_add_work(tpool, (void*)print_num, (void*)a);
     96  *       ..
     97  *    }
     98  *
     99  * @param  threadpool    threadpool to which the work will be added
    100  * @param  function_p    pointer to function to add as work
    101  * @param  arg_p         pointer to an argument
    102  * @return 0 on successs, -1 otherwise.
    103  */
    104 int tpool_add_work(threadpool, void (*function_p)(void*), void* arg_p);
    105 
    106 
    107 /**
    108  * @brief Wait for all queued jobs to finish
    109  *
    110  * Will wait for all jobs - both queued and currently running to finish.
    111  * Once the queue is empty and all work has completed, the calling thread
    112  * (probably the main program) will continue.
    113  *
    114  * Smart polling is used in wait. The polling is initially 0 - meaning that
    115  * there is virtually no polling at all. If after 1 seconds the threads
    116  * haven't finished, the polling interval starts growing exponentially
    117  * untill it reaches max_secs seconds. Then it jumps down to a maximum polling
    118  * interval assuming that heavy processing is being used in the threadpool.
    119  *
    120  * @example
    121  *
    122  *    ..
    123  *    threadpool tpool = tpool_init(4);
    124  *    ..
    125  *    // Add a bunch of work
    126  *    ..
    127  *    tpool_wait(tpool);
    128  *    puts("All added work has finished");
    129  *    ..
    130  *
    131  * @param threadpool     the threadpool to wait for
    132  * @return nothing
    133  */
    134 void tpool_wait(threadpool);
    135 
    136 
    137 /**
    138  * @brief Pauses all threads immediately
    139  *
    140  * The threads will be paused no matter if they are idle or working.
    141  * The threads return to their previous states once tpool_resume
    142  * is called.
    143  *
    144  * While the thread is being paused, new work can be added.
    145  *
    146  * @example
    147  *
    148  *    threadpool tpool = tpool_init(4);
    149  *    tpool_pause(tpool);
    150  *    ..
    151  *    // Add a bunch of work
    152  *    ..
    153  *    tpool_resume(tpool); // Let the threads start their magic
    154  *
    155  * @param threadpool    the threadpool where the threads should be paused
    156  * @return nothing
    157  */
    158 void tpool_pause(threadpool);
    159 
    160 
    161 /**
    162  * @brief Unpauses all threads if they are paused
    163  *
    164  * @example
    165  *    ..
    166  *    tpool_pause(tpool);
    167  *    sleep(10);              // Delay execution 10 seconds
    168  *    tpool_resume(tpool);
    169  *    ..
    170  *
    171  * @param threadpool     the threadpool where the threads should be unpaused
    172  * @return nothing
    173  */
    174 void tpool_resume(threadpool);
    175 
    176 
    177 /**
    178  * @brief Destroy the threadpool
    179  *
    180  * This will wait for the currently active threads to finish and then 'kill'
    181  * the whole threadpool to free up memory.
    182  *
    183  * @example
    184  * int main() {
    185  *    threadpool tpool1 = tpool_init(2);
    186  *    threadpool tpool2 = tpool_init(2);
    187  *    ..
    188  *    tpool_destroy(tpool1);
    189  *    ..
    190  *    return 0;
    191  * }
    192  *
    193  * @param threadpool     the threadpool to destroy
    194  * @return nothing
    195  */
    196 void tpool_destroy(threadpool);
    197 
    198 
    199 /**
    200  * @brief Show currently working threads
    201  *
    202  * Working threads are the threads that are performing work (not idle).
    203  *
    204  * @example
    205  * int main() {
    206  *    threadpool tpool1 = tpool_init(2);
    207  *    threadpool tpool2 = tpool_init(2);
    208  *    ..
    209  *    printf("Working threads: %d\n", tpool_num_threads_working(tpool1));
    210  *    ..
    211  *    return 0;
    212  * }
    213  *
    214  * @param threadpool     the threadpool of interest
    215  * @return integer       number of threads working, -1 error
    216  */
    217 int tpool_num_threads_working(threadpool);
    218 
    219 
    220 #ifdef __cplusplus
    221 }
    222 #endif