📄 omnithread.h
字号:
void wait(void); // wait for the condition variable to be signalled. The mutex is // implicitly released before waiting and locked again after waking up. // If wait() is called by multiple threads, a signal may wake up more // than one thread. See POSIX threads documentation for details. int timedwait(unsigned long secs, unsigned long nanosecs = 0); // timedwait() is given an absolute time to wait until. To wait for a // relative time from now, use omni_thread::get_time. See POSIX threads // documentation for why absolute times are better than relative. // Returns 1 (true) if successfully signalled, 0 (false) if time // expired. void signal(void); // if one or more threads have called wait(), signal wakes up at least // one of them, possibly more. See POSIX threads documentation for // details. void broadcast(void); // broadcast is like signal but wakes all threads which have called // wait().private: // dummy copy constructor and operator= to prevent copying omni_condition(const omni_condition&); omni_condition& operator=(const omni_condition&);OMNI_THREAD_EXPOSE: OMNI_CONDITION_IMPLEMENTATION};/////////////////////////////////////////////////////////////////////////////// Counting semaphore/////////////////////////////////////////////////////////////////////////////class _OMNITHREAD_NTDLL_ omni_semaphore {public: omni_semaphore(unsigned int initial = 1); ~omni_semaphore(void); void wait(void); // if semaphore value is > 0 then decrement it and carry on. If it's // already 0 then block. int trywait(void); // if semaphore value is > 0 then decrement it and return 1 (true). // If it's already 0 then return 0 (false). void post(void); // if any threads are blocked in wait(), wake one of them up. Otherwise // increment the value of the semaphore.private: // dummy copy constructor and operator= to prevent copying omni_semaphore(const omni_semaphore&); omni_semaphore& operator=(const omni_semaphore&);OMNI_THREAD_EXPOSE: OMNI_SEMAPHORE_IMPLEMENTATION};//// A helper class for semaphores, similar to omni_mutex_lock above.//class _OMNITHREAD_NTDLL_ omni_semaphore_lock { omni_semaphore& sem;public: omni_semaphore_lock(omni_semaphore& s) : sem(s) { sem.wait(); } ~omni_semaphore_lock(void) { sem.post(); }private: // dummy copy constructor and operator= to prevent copying omni_semaphore_lock(const omni_semaphore_lock&); omni_semaphore_lock& operator=(const omni_semaphore_lock&);};/////////////////////////////////////////////////////////////////////////////// Thread/////////////////////////////////////////////////////////////////////////////class _OMNITHREAD_NTDLL_ omni_thread {public: enum priority_t { PRIORITY_LOW, PRIORITY_NORMAL, PRIORITY_HIGH }; enum state_t { STATE_NEW, // thread object exists but thread hasn't // started yet. STATE_RUNNING, // thread is running. STATE_TERMINATED // thread has terminated but storage has not // been reclaimed (i.e. waiting to be joined). }; // // Constructors set up the thread object but the thread won't start until // start() is called. The create method can be used to construct and start // a thread in a single call. // omni_thread(void (*fn)(void*), void* arg = NULL, priority_t pri = PRIORITY_NORMAL); omni_thread(void* (*fn)(void*), void* arg = NULL, priority_t pri = PRIORITY_NORMAL); // these constructors create a thread which will run the given function // when start() is called. The thread will be detached if given a // function with void return type, undetached if given a function // returning void*. If a thread is detached, storage for the thread is // reclaimed automatically on termination. Only an undetached thread // can be joined. void start(void); // start() causes a thread created with one of the constructors to // start executing the appropriate function.protected: omni_thread(void* arg = NULL, priority_t pri = PRIORITY_NORMAL); // this constructor is used in a derived class. The thread will // execute the run() or run_undetached() member functions depending on // whether start() or start_undetached() is called respectively. void start_undetached(void); // can be used with the above constructor in a derived class to cause // the thread to be undetached. In this case the thread executes the // run_undetached member function. virtual ~omni_thread(void); // destructor cannot be called by user (except via a derived class). // Use exit() or cancel() instead. This also means a thread object must // be allocated with new - it cannot be statically or automatically // allocated. The destructor of a class that inherits from omni_thread // shouldn't be public either (otherwise the thread object can be // destroyed while the underlying thread is still running).public: void join(void**); // join causes the calling thread to wait for another's completion, // putting the return value in the variable of type void* whose address // is given (unless passed a null pointer). Only undetached threads // may be joined. Storage for the thread will be reclaimed. void set_priority(priority_t); // set the priority of the thread. static omni_thread* create(void (*fn)(void*), void* arg = NULL, priority_t pri = PRIORITY_NORMAL); static omni_thread* create(void* (*fn)(void*), void* arg = NULL, priority_t pri = PRIORITY_NORMAL); // create spawns a new thread executing the given function with the // given argument at the given priority. Returns a pointer to the // thread object. It simply constructs a new thread object then calls // start. static void exit(void* return_value = NULL); // causes the calling thread to terminate. static omni_thread* self(void); // returns the calling thread's omni_thread object. // If the calling thread is not the main thread and // is not created using this library, returns 0. static void yield(void); // allows another thread to run. static void sleep(unsigned long secs, unsigned long nanosecs = 0); // sleeps for the given time. static void get_time(unsigned long* abs_sec, unsigned long* abs_nsec, unsigned long rel_sec = 0, unsigned long rel_nsec=0); // calculates an absolute time in seconds and nanoseconds, suitable for // use in timed_waits on condition variables, which is the current time // plus the given relative offset. static void stacksize(unsigned long sz); static unsigned long stacksize(); // Use this value as the stack size when spawning a new thread. // The default value (0) means that the thread library default is // to be used.private: virtual void run(void* arg) {} virtual void* run_undetached(void* arg) { return NULL; } // can be overridden in a derived class. When constructed using the // the constructor omni_thread(void*, priority_t), these functions are // called by start() and start_undetached() respectively. void common_constructor(void* arg, priority_t pri, int det); // implements the common parts of the constructors. omni_mutex mutex; // used to protect any members which can change after construction, // i.e. the following 2 members: state_t _state; priority_t _priority; static omni_mutex* next_id_mutex; static int next_id; int _id; void (*fn_void)(void*); void* (*fn_ret)(void*); void* thread_arg; int detached;public: priority_t priority(void) { // return this thread's priority. omni_mutex_lock l(mutex); return _priority; } state_t state(void) { // return thread state (invalid, new, running or terminated). omni_mutex_lock l(mutex); return _state; } int id(void) { return _id; } // return unique thread id within the current process. // This class plus the instance of it declared below allows us to execute // some initialisation code before main() is called. class _OMNITHREAD_NTDLL_ init_t { static int count; public: init_t(void); }; friend class init_t;OMNI_THREAD_EXPOSE: OMNI_THREAD_IMPLEMENTATION};#ifndef __rtems__static omni_thread::init_t omni_thread_init;#else// RTEMS calls global Ctor/Dtor in a context that is not// a posix thread. Calls to functions to pthread_self() in// that context returns NULL. // So, for RTEMS we will make the thread initialization at the// beginning of the Init task that has a posix context.#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -