| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file threadSimpleManager.h
- * @author drose
- * @date 2007-06-18
- */
- #ifndef THREADSIMPLEMANAGER_H
- #define THREADSIMPLEMANAGER_H
- #include "pandabase.h"
- #include "selectThreadImpl.h"
- #ifdef THREAD_SIMPLE_IMPL
- #include "pdeque.h"
- #include "pmap.h"
- #include "pvector.h"
- #include "trueClock.h"
- #include "configVariableDouble.h"
- #include <algorithm>
- #ifdef HAVE_POSIX_THREADS
- #include <pthread.h> // for pthread_t, below
- #endif
- #ifdef WIN32
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN 1
- #endif
- #include <windows.h> // for DWORD, below
- #endif
- class Thread;
- class ThreadSimpleImpl;
- class BlockerSimple;
- struct ThreadContext;
- /**
- * This is the global object that selects the currently-active thread of the
- * various ThreadSimpleImpl objects running, when the currently-active thread
- * yields.
- *
- * This class only exists when we are using the ThreadSimple implementation,
- * which is to say, we are not using "real" threads.
- *
- * Generally, you shouldn't be calling these methods directly. Call the
- * interfaces on Thread instead.
- */
- class EXPCL_PANDA_PIPELINE ThreadSimpleManager {
- private:
- ThreadSimpleManager();
- public:
- void enqueue_ready(ThreadSimpleImpl *thread, bool volunteer);
- void enqueue_sleep(ThreadSimpleImpl *thread, double seconds);
- void enqueue_block(ThreadSimpleImpl *thread, BlockerSimple *blocker);
- bool unblock_one(BlockerSimple *blocker);
- bool unblock_all(BlockerSimple *blocker);
- void enqueue_finished(ThreadSimpleImpl *thread);
- void preempt(ThreadSimpleImpl *thread);
- void next_context();
- void prepare_for_exit();
- INLINE ThreadSimpleImpl *get_current_thread();
- void set_current_thread(ThreadSimpleImpl *current_thread);
- INLINE bool is_same_system_thread() const;
- void remove_thread(ThreadSimpleImpl *thread);
- static void system_sleep(double seconds);
- static void system_yield();
- double get_current_time() const;
- INLINE static ThreadSimpleManager *get_global_ptr();
- void write_status(std::ostream &out) const;
- private:
- static void init_pointers();
- typedef pdeque<ThreadSimpleImpl *> FifoThreads;
- typedef pvector<ThreadSimpleImpl *> Sleeping;
- static void st_choose_next_context(struct ThreadContext *from_context, void *data);
- void choose_next_context(struct ThreadContext *from_context);
- void do_timeslice_accounting(ThreadSimpleImpl *thread, double now);
- void wake_sleepers(Sleeping &sleepers, double now);
- void wake_all_sleepers(Sleeping &sleepers);
- void report_deadlock();
- double determine_timeslice(ThreadSimpleImpl *chosen_thread);
- void kill_non_joinable(FifoThreads &threads);
- void kill_non_joinable(Sleeping &threads);
- // STL function object to sort the priority queue of sleeping threads.
- class CompareStartTime {
- public:
- INLINE bool operator ()(ThreadSimpleImpl *a, ThreadSimpleImpl *b) const;
- };
- public:
- // Defined within the class to avoid static-init ordering problems.
- ConfigVariableDouble _simple_thread_epoch_timeslice;
- ConfigVariableDouble _simple_thread_volunteer_delay;
- ConfigVariableDouble _simple_thread_yield_sleep;
- ConfigVariableDouble _simple_thread_window;
- ConfigVariableDouble _simple_thread_low_weight;
- ConfigVariableDouble _simple_thread_normal_weight;
- ConfigVariableDouble _simple_thread_high_weight;
- ConfigVariableDouble _simple_thread_urgent_weight;
- private:
- ThreadSimpleImpl *volatile _current_thread;
- // The list of ready threads: threads that are ready to execute right now.
- FifoThreads _ready;
- // The list of threads that are ready, but will not be executed until next
- // epoch (for instance, because they exceeded their timeslice budget this
- // epoch).
- FifoThreads _next_ready;
- // The list of threads that are blocked on some ConditionVar or Mutex.
- typedef pmap<BlockerSimple *, FifoThreads> Blocked;
- Blocked _blocked;
- // Priority queue (partially-ordered heap) of sleeping threads, based on
- // wakeup time.
- Sleeping _sleeping;
- // Priority queue (partially-ordered heap) of volunteer threads, based on
- // wakeup time. This are threads that have voluntarily yielded a timeslice.
- // They are treated the same as sleeping threads, unless all threads are
- // sleeping.
- Sleeping _volunteers;
- // Threads which have finished execution and are awaiting cleanup.
- FifoThreads _finished;
- ThreadSimpleImpl *_waiting_for_exit;
- TrueClock *_clock;
- double _tick_scale;
- class TickRecord {
- public:
- unsigned int _tick_count;
- ThreadSimpleImpl *_thread;
- };
- typedef pdeque<TickRecord> TickRecords;
- TickRecords _tick_records;
- unsigned int _total_ticks;
- static bool _pointers_initialized;
- static ThreadSimpleManager *_global_ptr;
- };
- // We include this down here to avoid the circularity problem.
- /* okcircular */
- #include "threadSimpleImpl.h"
- #include "threadSimpleManager.I"
- #endif // THREAD_SIMPLE_IMPL
- #endif
|