00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _EYEDBLIB_PERFORMER_H
00026 #define _EYEDBLIB_PERFORMER_H
00027
00028 #include <stdio.h>
00029 #include <eyedblib/thread.h>
00030
00031 namespace eyedblib {
00032 struct ThreadPerformerArg {
00033 ThreadPerformerArg(void *_data, unsigned int _size = 0) {
00034 data = _data;
00035 size = _size;
00036 #ifdef SPARCV9
00037 pad = 0;
00038 #endif
00039 }
00040
00041 operator void*() {return data;}
00042 void *data;
00043 int size;
00044 #ifdef SPARCV9
00045 int pad;
00046 #endif
00047 };
00048
00049 typedef ThreadPerformerArg (*ThreadPerformerFunction)(ThreadPerformerArg);
00050
00051 class ThreadPerformer {
00052
00053 public:
00054 ThreadPerformer(void (*init)(ThreadPerformer *, void *) = 0,
00055 void *init_arg = 0);
00056 void start(Thread *, ThreadPerformerFunction exec,
00057 ThreadPerformerArg arg = 0);
00058 ThreadPerformerArg wait();
00059 Thread *getThread() {return thr;}
00060 bool isIdle() const {return !thr || thr->isIdle();}
00061
00062 void *getUserData() {return user_data;}
00063 void *setUserData(void *);
00064
00065 ~ThreadPerformer();
00066
00067 private:
00068 void *return_arg;
00069 void *user_data;
00070 friend class ThreadPool;
00071 static void *thread_wrapper(void *);
00072 void resume(Thread *);
00073 Thread *thr;
00074 struct WrapperArg {
00075 ThreadPerformerFunction exec;
00076 void *input_arg;
00077 } wrap_arg;
00078 ThreadPerformer *wait_prev, *wait_next;
00079 ThreadPerformer *run_prev, *run_next;
00080 bool free;
00081 };
00082
00083 class ThreadPool {
00084
00085 public:
00086 ThreadPool(unsigned int thread_cnt);
00087 ThreadPool(void (*init)(ThreadPerformer *, void *), void *init_arg,
00088 unsigned int thread_cnt);
00089
00090 void reset();
00091 ThreadPerformer *start(ThreadPerformerFunction exec,
00092 ThreadPerformerArg arg = 0);
00093 ThreadPerformerArg wait(ThreadPerformer *&);
00094
00095 ThreadPerformer *getOne();
00096
00097 Thread::Profile **getProfiles(unsigned int &cnt) const;
00098 void setProfile(bool);
00099 bool isProfiled() const {return profiled;}
00100 void profileReset();
00101
00102 void release(ThreadPerformer *);
00103 void waitAll();
00104
00105 unsigned int getThreadCount() const {return thread_cnt;}
00106 unsigned int getCurrentThreadPerformerCount() const {return current_thread_performer_cnt;}
00107
00108 ~ThreadPool();
00109
00110 void print(FILE *fd = stdout);
00111
00112 private:
00113 bool profiled;
00114 ThreadPerformer *getOneRealize();
00115 unsigned int thread_cnt;
00116 unsigned int current_thread_performer_cnt;
00117 void init(unsigned int thread_cnt);
00118 void (*init_performer)(ThreadPerformer *, void *);
00119 void *init_performer_arg;
00120 eyedblib::Mutex mut;
00121 ThreadPerformer **performers;
00122 Thread **thrs;
00123 Condition *end_cond;
00124 static void endExecWrapper(Thread *thr, void *);
00125 ThreadPerformer *wait_first;
00126 ThreadPerformer *run_first;
00127 void addToWaitQueue(ThreadPerformer *perf);
00128 ThreadPerformer *peekFromWaitQueue();
00129 void addToRunQueue(ThreadPerformer *perf);
00130 ThreadPerformer *peekFromRunQueue();
00131 Thread *getOneThread();
00132 void beforeStart(ThreadPerformer *perf, Thread *thr);
00133 };
00134
00135 std::ostream &operator<<(std::ostream &, Thread::Profile **);
00136
00137 }
00138
00139 #endif