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