root/core/thread_params_traits.hpp

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. id
  2. to_string

   1 #ifndef libjmmcg_core_thread_params_traits_hpp
   2 #define libjmmcg_core_thread_params_traits_hpp
   3 
   4 /******************************************************************************
   5 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/thread_params_traits.hpp 2055 2017-05-13 19:35:47Z jmmcg $
   6 **
   7 **      Copyright © 2004 by J.M.McGuiness, coder@hussar.me.uk
   8 **
   9 ** This library is free software; you can redistribute it and/or
  10 ** modify it under the terms of the GNU Lesser General Public
  11 ** License as published by the Free Software Foundation; either
  12 ** version 2.1 of the License, or (at your option) any later version.
  13 **
  14 ** This library is distributed in the hope that it will be useful,
  15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17 ** Lesser General Public License for more details.
  18 **
  19 ** You should have received a copy of the GNU Lesser General Public
  20 ** License along with this library; if not, write to the Free Software
  21 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23 
  24 #ifdef _MSC_VER
  25 #       pragma warning(disable:4786)    // identifier was truncated to '255' characters in the debug information
  26 #endif
  27 
  28 #include "non_copyable.hpp"
  29 #include "ttypes.hpp"
  30 #include <boost/mpl/assert.hpp>
  31 #include <cassert>
  32 
  33 namespace jmmcg { namespace ppd {
  34 
  35         /**
  36                 These parameters allow the users to choose a thread pool that has the
  37                 properties they would like. Note that not all combinations make sense,
  38                 so will give compilation errors, as they are not implemented, and of the
  39                 rest, some of those may not be implemented. Contact the author if you need
  40                 a specific specialisation!
  41         */
  42         namespace generic_traits {
  43                 enum class creation_cost {
  44                         sequential_creation,
  45                         expensive_to_create,    ///< E.g. x86 ISA & Win32
  46                         cheap_to_create ///< E.g. IBM BlueGene/[C|P] (or Cyclops)
  47                 };
  48                 enum class destruction_cost {
  49                         sequential_destruction,
  50                         expensive_to_destroy,   ///< E.g. x86 ISA & Win32
  51                         cheap_to_destroy        ///< E.g. IBM BlueGene/[C|P] (or Cyclops)
  52                 };
  53                 enum class synchronisation_cost {       ///< The cost of the base read-modify-write operation used to implement a mutex.
  54                         sequential_sync,
  55                         expensive_to_synchronise,       ///< E.g. x86 ISA & Win32
  56                         cheap_to_synchronise    ///< E.g. IBM BlueGene/[C|P] (or Cyclops)
  57                 };
  58                 enum class return_data {
  59                         joinable,       ///< The work has a return value.
  60                         nonjoinable     ///< The work does not have a return value.
  61                 };
  62                 enum class api_type {
  63                         no_api, ///< For sequential operation. i.e. no threading. Ususally one would use the constant platform_api, which is suitably declared as one of the threading models, below.
  64                         MS_Win32,       ///< Usually "heavy-weight" threads, e.g. x86, alpha.
  65                         posix_pthreads, ///< Usually "heavy-weight" threads, e.g. x86, alpha, SPARC. On Solaris, Linux, etc.
  66                         IBM_cyclops     ///< IBM BlueGene/[C|P] (or Cyclops), ~10^6-~10^9 lightweight threads, NUMA architecture.
  67                 };
  68 
  69                 inline tostream & __fastcall FORCE_INLINE
  70                 operator<<(tostream &os, api_type const &api) {
  71                         switch (api) {
  72                                 case api_type::MS_Win32:
  73                                         os<<_T("MS_Win32");
  74                                         break;
  75                                 case api_type::posix_pthreads:
  76                                         os<<_T("posix_pthreads");
  77                                         break;
  78                                 case api_type::IBM_cyclops:
  79                                         os<<_T("IBM_cyclops");
  80                                         break;
  81                                 case api_type::no_api:
  82                                 default:
  83                                         os<<_T("no_api");
  84                         }
  85                         return os;
  86                 }
  87                 /// The various memory access modes that the assorted locks may support.
  88                 /**
  89                         To assist in allowing compile-time computation of the algorithmic order of the threading model.
  90                 */
  91                 enum class memory_access_modes {
  92                         erew_memory_access,     ///< Exclusive-Read, Exclusive-Write memory access.
  93                         crew_memory_access      ///< Concurrent-Read, Exclusive-Write memory access.
  94                 };
  95         }
  96 
  97         /// A namespace to hold various traits relating to selecting the specific specialisation of thread_pool they would like.
  98         /**
  99                 These parameters allow the users to choose a thread_pool that has the properties they would like. Note that not all combinations make sense, so will give compilation errors, as they are not implemented, and of the rest, some of those may not be implemented. Contact the author if you need a specific specialisation!
 100         */
 101         namespace pool_traits {
 102                 /// Various models of work distribution.
 103                 namespace work_distribution_mode_t {
 104                         namespace queue_model_t {
 105                                 /// The thread_pool owns a single queue into which input_work is placed & from which thread_wk_t is distributed.
 106                                 /**
 107                                         Work stealing from the queue; the adding work to and removing work from the queue is the limiting resource, possibly lock-free or with some sort of lock_type, that may have some sort of anon_semaphore to indicate to waiting pool_threads that it contains work.
 108                                         
 109                                         \see intrusive::slist, safe_colln
 110                                 */
 111                                 struct pool_owns_queue {};
 112 
 113                                 enum class stealing_mode_t {
 114                                         random  ///< When a pool_thread runs out of work it chooses another pool_thread to steal from at random.
 115                                 };
 116                                 /// The pool_threads own a queue each into which work that thread places work it generates.
 117                                 template<stealing_mode_t SM>
 118                                 struct thread_owns_queue {
 119                                         static constexpr stealing_mode_t stealing_mode=SM;
 120                                 };
 121                         }
 122                         ///. Master-slave; the master thread would be the limiting resource.
 123                         template<class QM=queue_model_t::pool_owns_queue>
 124                         struct one_thread_distributes {
 125                                 BOOST_MPL_ASSERT((std::is_same<QM, queue_model_t::pool_owns_queue>));
 126                                 using queue_model=queue_model_t::pool_owns_queue;
 127                         };
 128                         template<class QM>
 129                         struct worker_threads_get_work {
 130                                 using queue_model=QM;
 131                         };
 132                 }
 133                 /// Control the size of the thread pool in various ways.
 134                 enum class size_mode_t {
 135                         sequential,     ///< Specify a serial thread pool, i.e. no threading.
 136                         fixed_size,     ///< Specify n threads to be in the pool.
 137                         time_average_size,      ///< Allow some automated mechanism to control the pool size.
 138                         tracks_to_max,  ///< Have a maximum of n threads, but less or zero according to outstanding work.
 139                         infinite        ///< Specify a situation where a thread is spawned per job, with no limits.
 140                 };
 141                 /// Specifiy if the thread_pool can sort work by some form of priority, executing the highest first.
 142                 enum class priority_mode_t {
 143                         normal, ///< No priority, a strict fifo.
 144                         priority        ///< The work items should have some form of partial ordering specified upon them.
 145                 };
 146         }
 147 
 148         /**
 149                 Clearly you should provide some useful types for these when you specialise this class for an API!
 150         */
 151         template<generic_traits::api_type API>
 152         class thread_params {
 153         public:
 154                 typedef int stack_size_type;
 155 
 156                 static constexpr generic_traits::api_type api_type=API;
 157                 static constexpr stack_size_type max_stack_size=std::numeric_limits<stack_size_type>::max();
 158 
 159                 typedef int handle_type;
 160                 typedef int pid_type;
 161                 typedef int tid_type;
 162 
 163                 typedef int processor_mask_type;
 164 
 165                 typedef int suspend_count;
 166                 typedef int suspend_period_ms;
 167 
 168                 typedef int security_type;
 169                 typedef void core_work_fn_ret_t;
 170                 typedef void core_work_fn_arg_t;
 171 
 172 #pragma GCC diagnostic push
 173 #pragma GCC diagnostic ignored "-Wattributes"
 174 
 175                 typedef core_work_fn_ret_t (__cdecl core_work_fn_type)(void);
 176 
 177 #pragma GCC diagnostic pop
 178 
 179                 typedef int arglist_type;
 180                 typedef void initflag_type;
 181 
 182                 enum creation_flags {
 183                         create_running,
 184                         create_suspended
 185                 };
 186                 enum priority_type {
 187                         lowest,
 188                         idle,
 189                         below_normal,
 190                         normal,
 191                         above_normal,
 192                         highest,
 193                         time_critical,
 194                         unknown_priority
 195                 };
 196 
 197                 /**
 198                         Note that these states are in a specific order - the higher the number, the more severe any error.
 199                 */
 200                 enum states {
 201                         no_kernel_thread=0,     ///< This is not a failure - the thread may not be started yet, or may have exited.
 202                         suspended,
 203                         active,
 204                         cancelled,
 205                         // Error conditions now...
 206                         get_exit_code_failure,
 207                         deadlocked_with_another_thread,
 208                         invalid_thread,
 209                         thread_id_not_found,
 210                         failed_to_cancel,
 211                         null_this_pointer,
 212                         jmmcg_exception,
 213                         stl_exception,
 214                         unknown_exception,
 215                         terminated,
 216                         unknown
 217                 };
 218                 enum thread_cancel_state {
 219                         cancel_enable,
 220                         cancel_disable
 221                 };
 222 
 223                 const security_type security;
 224                 const stack_size_type stack_size;
 225                 core_work_fn_type * const work_fn;
 226                 arglist_type arglist;
 227 
 228                 handle_type handle;
 229                 tid_type id;
 230 
 231                 explicit __stdcall thread_params(core_work_fn_type * const sa, const security_type se=0, const stack_size_type ss=0) noexcept(true) FORCE_INLINE
 232                 : security(se), stack_size(ss), work_fn(sa), arglist(), handle(), id() {
 233                         assert(work_fn);
 234                 }
 235 
 236                 const jmmcg::tstring to_string() const {
 237                         jmmcg::tostringstream ss;
 238                         ss<<_T("API type: 0x")<<std::hex<<api_type
 239                                 <<_T(", work function ptr: 0x")<<std::hex<<work_fn
 240                                 <<_T(", argument list: 0x")<<std::hex<<arglist
 241                                 <<_T(", handle: 0x")<<std::hex<<handle
 242                                 <<_T(", ID: 0x")<<std::hex<<id;
 243                         return ss.str();
 244                 }
 245         };
 246 
 247         template<generic_traits::api_type API> inline tostream & __fastcall FORCE_INLINE
 248         operator<<(tostream &os, thread_params<API> const &p) {
 249                 os<<p.to_string();
 250                 return os;
 251         }
 252 
 253         template<generic_traits::creation_cost Cr, generic_traits::destruction_cost Dr, generic_traits::synchronisation_cost Sy>
 254         struct model_traits {
 255                 static constexpr generic_traits::creation_cost creation=Cr;
 256                 static constexpr generic_traits::destruction_cost destruction=Dr;
 257                 static constexpr generic_traits::synchronisation_cost synchronisation=Sy;
 258         };
 259 
 260         /**
 261                 These typedefs provide quick ways to get to the various implemented threading models.
 262         */
 263         typedef model_traits<generic_traits::creation_cost::sequential_creation, generic_traits::destruction_cost::sequential_destruction, generic_traits::synchronisation_cost::sequential_sync> sequential_mode;      /// I.e. single-threaded, no locks.
 264         typedef model_traits<generic_traits::creation_cost::expensive_to_create, generic_traits::destruction_cost::expensive_to_destroy, generic_traits::synchronisation_cost::expensive_to_synchronise> heavyweight_threading; /// E.g. x86 or SPARC.
 265         typedef model_traits<generic_traits::creation_cost::cheap_to_create, generic_traits::destruction_cost::cheap_to_destroy, generic_traits::synchronisation_cost::cheap_to_synchronise> lightweight_threading;     /// E.g. IBM BlueGene/[C|P] (or Cyclops)
 266 
 267 } }
 268 
 269 #ifdef WIN32
 270 #       include "../experimental/NT-based/NTSpecific/thread_params_traits.hpp"
 271 #else
 272 #       include "../unix/thread_params_traits.hpp"
 273 #endif
 274 
 275 #endif

/* [<][>][^][v][top][bottom][index][help] */