source: trunk/kernel/kern/thread.h @ 625

Last change on this file since 625 was 625, checked in by alain, 2 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 27.4 KB
Line 
1/*
2 * thread.h -  Thread and related operations definition.
3 *
4 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
5 *         Alain Greiner (2016,2017,2018,2019)
6 *
7 * Copyright (c) UPMC Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#ifndef _THREAD_H_
26#define _THREAD_H_
27
28#include <hal_kernel_types.h>
29#include <shared_syscalls.h>
30#include <hal_special.h>
31#include <hal_kentry.h>
32#include <xlist.h>
33#include <list.h>
34#include <hal_context.h>
35#include <remote_busylock.h>
36#include <core.h>
37#include <chdev.h>
38#include <cluster.h>
39#include <process.h>
40#include <dev_ioc.h>
41#include <dev_nic.h>
42#include <dev_txt.h>
43#include <dev_mmc.h>
44#include <dev_dma.h>
45
46/***************************************************************************************
47 * These macros are used to compose or decompose the global thread identifier (TRDID)
48 * to or from cluster identifier / local thread index (CXY , LTID)
49 **************************************************************************************/
50
51#define LTID_FROM_TRDID( trdid )   (ltid_t)(trdid & 0x0000FFFF)
52#define CXY_FROM_TRDID( trdid )    (cxy_t)(trdid >> 16)
53#define TRDID( cxy , ltid )        (trdid_t)((cxy << 16) | ltid )
54
55/***************************************************************************************
56 * This enum defines the thread types.
57 **************************************************************************************/
58
59typedef enum
60{
61        THREAD_USER    = 0,          /*! user thread (pthread)                            */
62        THREAD_RPC     = 1,          /*! kernel thread executing pending RPCs             */
63        THREAD_DEV     = 2,          /*! kernel thread executing I/O device commands      */
64        THREAD_IDLE    = 3,          /*! kernel idle thread                               */
65}
66thread_type_t;
67
68/***************************************************************************************
69 * This defines the thread flags bit-vector.
70 **************************************************************************************/
71
72#define THREAD_FLAG_DETACHED     0x0001  /*! This thread is detached from parent      */
73#define THREAD_FLAG_JOIN_DONE    0x0002  /*! Parent thread made a join request        */
74#define THREAD_FLAG_KILL_DONE    0x0004  /*! This thread received a kill request      */
75#define THREAD_FLAG_REQ_ACK      0x0010  /*! Acknowledge required from scheduler      */
76#define THREAD_FLAG_REQ_DELETE   0x0020  /*! Destruction required from scheduler      */
77
78/***************************************************************************************
79 * This defines the thread blocking causes bit-vector.
80 **************************************************************************************/
81
82#define THREAD_BLOCKED_GLOBAL    0x0001  /*! thread deactivated / wait activation     */
83#define THREAD_BLOCKED_IO        0x0002  /*! thread wait IO operation completion      */
84#define THREAD_BLOCKED_MAPPER    0x0004  /*! thread wait mapper                       */
85#define THREAD_BLOCKED_EXIT      0x0008  /*! thread blocked in join / wait exit       */
86#define THREAD_BLOCKED_JOIN      0x0010  /*! thread blocked in exit / wait join       */
87#define THREAD_BLOCKED_SEM       0x0020  /*! thread wait semaphore                    */
88#define THREAD_BLOCKED_PAGE      0x0040  /*! thread wait page access                  */
89#define THREAD_BLOCKED_IDLE      0x0080  /*! thread RPC wait RPC_FIFO non empty       */
90#define THREAD_BLOCKED_USERSYNC  0x0100  /*! thread wait (cond/mutex/barrier)         */
91#define THREAD_BLOCKED_RPC       0x0200  /*! thread wait RPC completion               */
92#define THREAD_BLOCKED_ISR       0x0400  /*! thread DEV wait ISR                      */
93#define THREAD_BLOCKED_WAIT      0x0800  /*! thread wait child process termination    */
94#define THREAD_BLOCKED_LOCK      0x1000  /*! thread wait queuelock or rwlock          */
95
96/***************************************************************************************
97 * This structure defines thread instrumentation informations.
98 **************************************************************************************/
99
100typedef struct thread_info_s
101{
102        uint32_t              pgfault_nr;    /*! cumulated number of page fault           */
103        cycle_t               last_cycle;    /*! last cycle counter value (date)          */
104        cycle_t               usr_cycles;    /*! user execution duration (cycles)         */
105        cycle_t               sys_cycles;    /*! system execution duration (cycles)       */
106}
107thread_info_t;
108
109/***************************************************************************************
110 * This structure defines a thread descriptor.
111 * It is used for both the user threads and the kernel threads.
112 * In a process, a user thread is identified by a unique TRDID (thread identifier):
113 * - The TRDID 16 LSB bits contain the LTID (Local Thread Index).
114 * - The TRDID 16 MSB bits contain the CXY of cluster containing the thread.
115 * The main thread LTID value is always 0.
116 * The LTID is used to index the th_tbl[] array in the local process descriptor.
117 * This TRDID is computed by the process_register_thread() function, when the user
118 * thread is registered in the local copy of the process descriptor.
119 *
120 * WARNING (1) Don't modify the first 4 fields order, as this order is used by the
121 *             hal_kentry assembly code for the TSAR architectures.
122 *
123 * WARNING (2) Most of the thread state is private and accessed only by this thread,
124 *             but some fields are shared, and can be modified by other threads.
125 *             - the "blocked" bit_vector can be modified by another thread
126 *               running in another cluster (using atomic instructions),
127 *               to change this thread scheduling status.
128 *             - the "flags" bit_vector can be modified by another thread
129 *               running in another cluster (using atomic instructions),
130 *               to register requests such as ACK or DELETE.
131 *             - the "join_xp" field can be modified by the joining thread,
132 *               and this rendez-vous is protected by the dedicated "join_lock".
133 *
134 * WARNING (3) When this thread is blocked on a shared resource (queuelock, condvar,
135 *             or chdev), it registers in the associated waiting queue, using the
136 *             "wait_list" (local list) or "wait_xlist" (trans-cluster list) fields.
137 **************************************************************************************/
138
139#define THREAD_SIGNATURE    0xDEADBEEF
140
141typedef struct thread_s
142{
143        void              * cpu_context;     /*! CPU context used by sched_yield          */
144        void              * fpu_context;     /*! FPU context used by sched_yield          */
145    void              * uzone_current;   /*! used by hal_do_syscall & hal_do_except   */
146    void              * uzone_previous;  /*! used by hal_do_syscall & hal_do_except   */
147
148        intptr_t            k_stack_base;    /*! kernel stack base address                */
149        uint32_t            k_stack_size;    /*! kernel stack size (bytes)                */
150
151        uint32_t            trdid;           /*! thread index (cxy.ltid)                  */
152        thread_type_t       type;            /*! thread type                              */
153        uint32_t            quantum;         /*! number of clock ticks given to thread    */
154        uint32_t            ticks_nr;        /*! number of ticks used                     */
155        uint32_t            time_last_check; /*! last cpu_time_stamp                      */
156        core_t            * core;            /*! pointer to the owner core                */
157        process_t         * process;         /*! pointer on local process descriptor      */
158    xptr_t              parent;          /*! extended pointer on parent thread        */
159
160    remote_busylock_t   join_lock;       /*! lock protecting the join/exit            */
161    xptr_t              join_xp;         /*! joining/killer thread extended pointer   */
162
163    uint32_t          * ack_rsp_count;   /*! pointer on acknowledge response counter  */
164
165        vseg_t            * user_stack_vseg; /*! local pointer on user stack vseg         */
166
167    void              * entry_func;      /*! pointer on entry function                */
168    void              * entry_args;      /*! pointer on entry function arguments      */
169    uint32_t            main_argc;       /*! main thread number of arguments          */
170    char             ** main_argv;       /*! main thread array of strings arguments   */
171
172    uint32_t            flags;           /*! bit vector of flags                      */
173    uint32_t            blocked;         /*! bit vector of blocking causes            */
174
175        error_t             errno;           /*! errno value set by last system call      */
176    uint32_t            utls;            /*! user thread local storage                */
177
178    bool_t              fork_user;       /*! user defined placement for next fork()   */
179    cxy_t               fork_cxy;        /*! target cluster  for next fork()          */
180
181        list_entry_t        sched_list;      /*! member of threads attached to same core  */
182
183    chdev_t           * chdev;           /*! chdev pointer (for a DEV thread only)    */
184
185    reg_t               save_sr;         /*! used by sched_yield() function           */
186
187    ioc_command_t       ioc_cmd;         /*! IOC device generic command               */
188    txt_command_t       txt_cmd;         /*! TXT device generic command               */
189    nic_command_t       nic_cmd;         /*! NIC device generic command               */
190    mmc_command_t       mmc_cmd;         /*! MMC device generic command               */
191    dma_command_t       dma_cmd;         /*! DMA device generic command               */
192
193        xptr_t              rpc_client_xp;   /*! client thread (for a RPC thread only)    */
194
195    list_entry_t        wait_list;       /*! member of a local waiting queue          */
196    xlist_entry_t       wait_xlist;      /*! member of a trans-cluster waiting queue  */
197
198        uint32_t            busylocks;       /*! number of taken busylocks                */
199
200#if DEBUG_BUSYLOCK
201    xlist_entry_t       busylocks_root;  /*! root of xlist of taken busylocks         */
202#endif
203
204        thread_info_t       info;            /*! embedded thread_info_t                   */
205
206        uint32_t            signature;       /*! for kernel stack overflow detection      */
207}
208thread_t;
209
210/***************************************************************************************
211 * This macro returns a pointer on the calling thread from the core hardware register.
212 **************************************************************************************/
213
214#define CURRENT_THREAD  (hal_get_current_thread())
215
216/***************************************************************************************
217 * This function returns a printable string for a thread type.
218 ***************************************************************************************
219 * @ type    : thread type.
220 * returns pointer on string.
221 **************************************************************************************/
222const char * thread_type_str( thread_type_t type );
223
224/***************************************************************************************
225 * This function is used by the pthread_create() system call to create a "new" thread
226 * in an existing process. It allocates memory for an user thread descriptor in the
227 * local cluster, and initializes it from information contained in the arguments.
228 * The CPU context is initialized from scratch.
229 * It is registered in the local process descriptor specified by the <pid> argument.
230 * The THREAD_BLOCKED_GLOBAL bit is set => the thread must be activated by the caller
231 * to start at the next scheduling point.
232 ***************************************************************************************
233 * @ pid          : process identifier.
234 * @ start_func   : pointer on entry function.
235 * @ start_args   : pointer on function argument (can be NULL).
236 * @ attr         : pointer on pthread attributes descriptor.
237 * @ new_thread   : [out] address of buffer for new thread descriptor pointer.
238 * @ returns 0 if success / returns ENOMEM if error.
239 **************************************************************************************/
240error_t thread_user_create( pid_t             pid,
241                            void            * start_func,
242                            void            * start_arg,
243                            pthread_attr_t  * attr,
244                            thread_t       ** new_thread );
245
246/***************************************************************************************
247 * This function is used by the sys_fork() syscall to create the "child" main thread
248 * in the local cluster. It is called, generally through the RPC_PROCESS_MAKE_FORK,
249 * by the process_make_fork() function. It allocates memory from the local cluster
250 * for a "child" thread descriptor, and initializes it from the "parent" thread
251 * descriptor defined by the <parent_thread_xp> argument.
252 * The new thread is attached to the core that has the lowest load in local cluster.
253 * It is registered in the "child" process defined by the <child_process> argument.
254 * This new thread inherits its user stack from the parent thread, as it uses the
255 * Copy-On-Write mechanism to get a private stack when required.
256 * The content of the parent kernel stack is copied into the child kernel stack, as
257 * the Copy-On-Write mechanism cannot be used for kernel segments (because kernel
258 * uses physical addressing on some architectures).
259 * The CPU and FPU execution contexts are created and linked to the new thread.
260 * but the actual context copy is NOT done, and is done by the sys_fork() function.
261 * The THREAD_BLOCKED_GLOBAL bit is set => the thread must be activated to start.
262 ***************************************************************************************
263 * @ parent_thread_xp  : extended pointer on parent thread descriptor.
264 * @ child_process     : local pointer on child process descriptor.
265 * @ child_thread      : [out] address of buffer for child thread descriptor pointer.
266 * @ returns 0 if success / returns -1 if error.
267 **************************************************************************************/
268error_t thread_user_fork( xptr_t      parent_thread_xp,
269                          process_t * child_process,
270                          thread_t ** child_thread );
271
272/***************************************************************************************
273 * This function is called by the process_make_exec() function to re-initialise the
274 * calling thread descriptor, that will become the new process main thread.
275 * It must be called by the main thread of the calling process.
276 * - The calling thread TRDID is not modified.
277 * - The kernel stack (currently in use) is not modified. 
278 * - A new user stack vseg is created and initialised.
279 * - The function calls the hal_cpu_context_exec() to re-initialize the CPU context
280 *   and the uzone registered in kernel stack, an jump to user code. 
281 ***************************************************************************************
282 * @ entry_func : main thread entry point.
283 * @ argc       : number of main thread arguments.
284 * @ argv       : array of pointers on stringarguments.
285 * @ returns 0 if success / returns ENOMEM if error.
286 **************************************************************************************/
287error_t thread_user_exec( void     * entry_func,
288                          uint32_t   argc,
289                          char    ** argv);
290
291/***************************************************************************************
292 * This function allocates memory for a kernel thread descriptor in the local cluster,
293 * and initializes it from arguments values.
294 * It is called by kernel_init() to statically create all DEV server threads
295 * It is also called to dynamically create RPC threads when required.
296 * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.
297 ***************************************************************************************
298 * @ new_thread   : address of buffer for new thread pointer.
299 * @ type         : kernel thread type.
300 * @ func         : pointer on function.
301 * @ args         : function arguments.
302 * @ core_lid     : local core index.
303 * @ returns 0 if success / returns ENOMEM if error
304 **************************************************************************************/
305error_t thread_kernel_create( thread_t     ** new_thread,
306                              thread_type_t   type,
307                              void          * func,
308                              void          * args,
309                              lid_t           core_lid );
310
311/***************************************************************************************
312 * This function is called by the kernel_init() function to initialize the IDLE thread
313 * descriptor from arguments values.
314 * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.
315 * It returns a kernel panic if failure.
316 ***************************************************************************************
317 * @ thread   : pointer on existing thread descriptor.
318 * @ type     : kernel thread type.
319 * @ func     : pointer on function.
320 * @ args     : function arguments.
321 * @ core_lid : local core index.
322 **************************************************************************************/
323void thread_idle_init( thread_t      * thread,
324                       thread_type_t   type,
325                       void          * func,
326                       void          * args,
327                       lid_t           core_lid );
328
329/***************************************************************************************
330 * This low-level function is called by the sched_handle_signals() function when a
331 * thread is marked for delete. It removes the thread identified by the <thread>
332 * argument from the process th_tbl[], and releases all physical memory allocated for
333 * this. This includes the thread descriptor itself, the associated CPU and FPU context,
334 * and the physical memory allocated for an user thread stack.
335 ***************************************************************************************
336 * @ thread  : pointer on the thread descriptor to release.
337 * @ return the number of threads registered in the process th_tbl[] before deletion.
338 **************************************************************************************/
339uint32_t thread_destroy( thread_t * thread );
340
341/***************************************************************************************
342 * This function defines the code of the thread executed by all cores after kernel_init,
343 * or when no other thread is runnable for a given core.
344 * It enter and infinite loop in wich:
345 * - it unmask the IRQs
346 * - it optionally calls the hal_core_sleep() function to reduce the power consumption
347 *   (this behavior is controlled by the CONFIG_THREAD_IDLE_MODE_SLEEP flag).
348 * - it call the sched_yield() function to find another runnable thread.
349 *
350 * TODO: In the TSAR architecture the hal_core_sleep() function forces the core to
351 * low-power mode. Any IRQ will force the core to exit this low-power mode, but no ISR
352 * is executed. We must analyse if we have the same behaviour for I86 architectures...
353 **************************************************************************************/
354void thread_idle_func( void );
355
356/***************************************************************************************
357 * This function is used by a "blocker" thread running in the same cluster as a "target"
358 * thread to request the scheduler of the target thread to acknowledge that the target
359 * thread is blocked and not running, at the next context switch.
360 * This function executes atomically the following actions :
361 * - it set the request_pending boolean in the target scheduler descriptor.
362 * - it set the REQ_ACK flag in the "flags" field of the target thread descriptor.
363 * - It registers the responses counter pointer in the target thread descriptor.
364 * The request_pending flag is handled as a set/reset flip-flop by the "blocker" thread
365 * and by the "target" scheduler.
366 ***************************************************************************************
367 * @ target        : local pointer on target thread.
368 * @ ack_rsp_count : local pointer on responses counter.
369 **************************************************************************************/
370void thread_set_req_ack( thread_t * target,
371                         uint32_t * ack_rsp_count );
372
373/***************************************************************************************
374 * This function is used by the sched_handle_signal() function executed by the
375 * scheduler of a "target" thread to reset a "blocked not running" acknowledge request
376 * in both the target thread descriptor, and in the target  thread scheduler.
377 ***************************************************************************************
378 * @ target    : local pointer on target thread.
379 **************************************************************************************/
380void thread_reset_req_ack( thread_t * target );
381
382/***************************************************************************************
383 * This function is used by the four sys_thread_cancel(), sys_thread_exit(),
384 * sys_kill() and sys_exit() system calls to mark for delete a given thread.
385 * It set the THREAD_BLOCKED_GLOBAL bit and set the THREAD_FLAG_REQ_DELETE bit in the
386 * thread descriptor identified by the <thread_xp> argument, to ask the scheduler
387 * to asynchronously delete the target thread, at the next scheduling point.
388 * The calling thread can run in any cluster, as it uses remote accesses.
389 * This function makes a kernel panic if the target thread is the main thread,
390 * because * the main thread deletion will cause the process deletion, and a process
391 * must be deleted by the parent process, running the wait function.
392 * If the target thread is running in "attached" mode, and the <is_forced> argument
393 * is false, this function implements the required sychronisation with the joining
394 * thread, blocking the killer thread until the pthread_join() syscall is executed
395 * by the joining thread.
396 ***************************************************************************************
397 * @ thread_xp   : extended pointer on the target thread.
398 * @ pid         : process identifier (to get the owner cluster identifier).
399 * @ is_forced   : the deletion does not depends on the attached mode.
400 **************************************************************************************/
401void thread_delete( xptr_t  thread_xp,
402                    pid_t   pid,
403                    bool_t  is_forced );
404
405/***************************************************************************************
406 * This function registers a blocking cause defined by the <cause> argument
407 * in a remote thread descriptor identified by the <thread_xp> argument.
408 * We need an extended pointer, because this function can be called by another thread
409 * than the target thread, executing the sys_kill() function.
410 * WARNING : this function does not deschedule the target thread, and the descheduling
411 * must be explicitely forced by a sched_yield().
412 ***************************************************************************************
413 * @ thread_xp   : extended pointer on remote thread descriptor.
414 * @ cause       : mask defining the cause (one hot).
415 **************************************************************************************/
416void thread_block( xptr_t   thread_xp,
417                   uint32_t cause );
418
419/***************************************************************************************
420 * This function resets the bit identified by the <cause> argument in a remote
421 * thread descriptor identified by the <thread_xp> argument.
422 * We need an extended pointer, because the client thread of an I/O operation on a
423 * given device is generally not in the same cluster as the associated server thread.
424 * WARNING : this function does not reschedule the remote thread.
425 * The scheduling can be forced by sending an IPI to the core running the remote thread.
426 ***************************************************************************************
427 * @ thread_xp   : extended pointer the remote thread.
428 * @ cause       : mask defining the cause (one hot).
429 * @ return non zero if the bit-vector was actually modified / return 0 otherwise
430 **************************************************************************************/
431uint32_t thread_unblock( xptr_t   thread_xp,
432                         uint32_t cause );
433
434/***************************************************************************************
435 * This function updates the calling thread user_time or kernel_time counters.
436 ***************************************************************************************
437 * @ thread   : local pointer on target thread.
438 * @ is_user  : update user time if true / update kernel time if false
439 **************************************************************************************/
440void thread_time_update( thread_t * thread,
441                         bool_t     is_user );
442
443/***************************************************************************************
444 * This function returns the extended pointer on a thread descriptor identified
445 * by its thread identifier, and process identifier.
446 * It can be called by any thread running in any cluster.
447 ***************************************************************************************
448 * @ pid     : process identifier.
449 * @ trdid   : thread identifier.
450 * @ return the extended pointer if thread found / return XPTR_NULL if not found.
451 **************************************************************************************/
452xptr_t thread_get_xptr( pid_t    pid,
453                        trdid_t  trdid );
454
455/***************************************************************************************
456 * This function checks that the thread identified by the <thread> argument does hold
457 * any busylock (local or remote).
458 * If the xlist of taken busylocks is not empty, it displays the set of taken locks,
459 * and makes a kernel panic. 
460 ***************************************************************************************
461 * @ thread    : local pointer on target thread.
462 * @ func_str  : faulty function name.
463 **************************************************************************************/
464void thread_assert_can_yield( thread_t    * thread,
465                              const char  * func_str );
466
467/***************************************************************************************
468 * This debug function display the list of busylocks (local or remote)
469 * currently owned by a the thread identified by the <thead_xp> argument.
470 * The <string> argument is printed in header (can be the calling function name).
471 * WARNING : the DEBUG_BUSYLOCK parameter must be set in the kernel_config.h file.
472 ***************************************************************************************
473 * @ thread_xp  : extended pointer on target thread.
474 * @ string     : defines the calling context.
475 **************************************************************************************/
476void thread_display_busylocks( xptr_t       thread_xp,
477                               const char * string );
478
479
480
481#endif  /* _THREAD_H_ */
Note: See TracBrowser for help on using the repository browser.