uThreads  0.3.0
kThread.h
1 /*******************************************************************************
2  * Copyright © 2015, 2016 Saman Barghi
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  *******************************************************************************/
17 
18 #ifndef UTHREADS_KTHREADS_H_
19 #define UTHREADS_KTHREADS_H_
20 
21 #include <thread>
22 #include <mutex>
23 #include <condition_variable>
24 #include <functional>
25 #include "../generic/basics.h"
26 #include "Cluster.h"
27 #include "uThread.h"
28 
29 class KTLocal;
30 class KTVar;
31 
54 class kThread: public Link<kThread> {
55  friend class uThread;
56  friend class Cluster;
57  friend class IOHandler;
58  friend class Scheduler;
59 private:
60  // First 64 bytes (CACHELINE_SIZE)
61  /*
62  * Pointer to the cluster this kThread
63  * belongs to. Each kThread only belongs to
64  * one Cluster and can pull uThreads from
65  * the ReadyQueue of that Cluster. kThreads
66  * can however push uThreads to ReadyQueue
67  * of other clusters upon uThread migration.
68  */
69  Cluster* localCluster; // (8 bytes)
70 
71  /*
72  * Scheduler object
73  */
74  Scheduler* scheduler; // (8 bytes)
75 
76 
77  KTVar* ktvar; // (8 bytes)
78 
79  /*
80  * Pointer to the current running uThread
81  */
82  uThread* currentUT; // (8 bytes)
83 
84  /*
85  * Each kThread has a main uThread that is
86  * only used when there is no uThread available
87  * on the ReadyQueue. kThread then switches to
88  * this uThread and block on the ReadyQueue waiting
89  * for more uThreads to arrive.
90  */
91  uThread* mainUT; // (8 bytes)
92 
93  // First 64 bytes (CACHELINE_SIZE)
94 
95  /* Holds the id of the underlying kernel thread */
96  std::thread::id threadID;
97 
98  /*
99  * The actual kernel thread behind this kThread.
100  * on Linux it will be a pthread.
101  */
102  std::thread threadSelf;
103 
104 
105  //Only used for defaultKT
106  kThread();
107  /*
108  * Create kThreads that runs a single uThread
109  * with the assigned function. These kThreads do
110  * not consumer from the ReadyQueu or switch context
111  * to another uThread.
112  */
113  kThread(Cluster&, std::function<void(ptr_t)>, ptr_t);
114 
115  /*
116  * defaultKT represents the main thread
117  * when program starts. This is the thread
118  * responsible for running the main function.
119  * defaultKT is created at the start of the
120  * program and cannot be accessed by user.
121  */
122  static kThread defaultKT;
123 
124  /*
125  * Pointer to the current kThread. This thread local variable
126  * is used by running uThreads to identify the current
127  * kThread that they are being executed over.
128  */
129  static __thread kThread* currentKT;
130 
131  static std::atomic_uint totalNumberofKTs;
132  /*
133  * This function initializes the required
134  * variables for the kThread and then call
135  * defaultRun.
136  */
137  void run();
138  /*
139  * The main loop of the kThread. This function
140  * is only used by mainUT of the kThread. It loops
141  * and pulls uThreads from the ReadyQueue or
142  * blocks until uThreads are available.
143  */
144  static void defaultRun(void*) __noreturn;
145  /*
146  * Same as run() but instead of running the defaultRun
147  * run the passed function. It is used to create kThreads
148  * that do not get involved with the ReadyQueue such as
149  * IOHandler thread.
150  */
151  void runWithFunc(std::function<void(ptr_t)>, ptr_t);
152  //Initialization function for kThread
153  void initialize();
154  //Initialize mainUT
155  void initializeMainUT(bool);
156  //Switch the context to the passed uThread.
157  void switchContext(uThread*, void* args = nullptr);
158  //Pull a uThread from readyQueue and switch the context
159  void switchContext(void* args = nullptr);
160 
161  /*
162  * This function is called after context of the uThread
163  * is switched. It is necessary in order to schedule the
164  * previous thread or perform the required maintentance
165  * before gonig forward.
166  */
167  static inline void postSwitchFunc(uThread*, void*) __noreturn;
168 
169  /*
170  * This struct points to an argument and a function. The function
171  * is called after suspending a uThread and switching to a new
172  * uThread. Two arguments is passed to this function: the old uThread*
173  * and the arguments passed by the calling function.
174  */
175  static __thread funcvoid2_t postSuspendFunc;
176 
177 
178  static __thread KTLocal* ktlocal;
179 
180  void initialSynchronization();
181 
182 
183 public:
184  //TODO: add a function to create multiple kThreads on a given cluster
189  kThread(Cluster&);
190  virtual ~kThread();
191 
193  kThread(const kThread&) = delete;
195  const kThread& operator=(const kThread&) = delete;
196 
203  std::thread::native_handle_type getThreadNativeHandle();
210  std::thread::id getID();
211 
219  static kThread* currentkThread(){return kThread::currentKT;}
220 
226  static uint getTotalNumberOfkThreads(){return totalNumberofKTs.load();}
227 };
228 
229 #endif /* UTHREADS_KTHREADS_H_ */
std::thread::native_handle_type getThreadNativeHandle()
return the native hanlde for the kernel thread
Definition: kThread.cpp:202
static kThread * currentkThread()
Get the pointer to the current kThread.
Definition: kThread.h:219
Object to represent kernel threads.
Definition: kThread.h:54
static uint getTotalNumberOfkThreads()
Definition: kThread.h:226
user-level threads (fiber)
Definition: uThread.h:63
Scheduler and Cluster of kThreads.
Definition: Cluster.h:61
const kThread & operator=(const kThread &)=delete
kThread cannot be copied or assigned.
std::thread::id getID()
returns the kernel thread ID
Definition: kThread.cpp:209