SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/thread.h (Article 6.5) and /sos/thread.h (Article 7)


001 /* Copyright (C) 2004,2005 David Decotigny        001 /* Copyright (C) 2004,2005 David Decotigny
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007    
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012    
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA. 
017 */                                                017 */
018 #ifndef _SOS_THREAD_H_                            018 #ifndef _SOS_THREAD_H_
019 #define _SOS_THREAD_H_                            019 #define _SOS_THREAD_H_
020                                                   020 
021 /**                                               021 /**
022  * @file thread.h                                 022  * @file thread.h
023  *                                                023  *
024  * SOS Thread management API                      024  * SOS Thread management API
025  */                                               025  */
026                                                   026 
027 #include <sos/errno.h>                            027 #include <sos/errno.h>
028                                                   028 
029 /* Forward declaration */                         029 /* Forward declaration */
030 struct sos_thread;                                030 struct sos_thread;
031                                                   031 
032 #include <hwcore/cpu_context.h>                   032 #include <hwcore/cpu_context.h>
033 #include <sos/sched.h>                            033 #include <sos/sched.h>
034 #include <sos/kwaitq.h>                           034 #include <sos/kwaitq.h>
035 #include <sos/time.h>                             035 #include <sos/time.h>
                                                   >> 036 #include <sos/process.h>
036                                                   037 
037 /**                                               038 /**
038  * The possible states of a valid thread          039  * The possible states of a valid thread
039  */                                               040  */
040 typedef enum { SOS_THR_CREATED, /**< Thread cr    041 typedef enum { SOS_THR_CREATED, /**< Thread created, not fully initialized */
041                SOS_THR_READY,   /**< Thread fu    042                SOS_THR_READY,   /**< Thread fully initialized or
042                                      waiting f    043                                      waiting for CPU after having been
043                                      blocked o    044                                      blocked or preempted */
044                SOS_THR_RUNNING, /**< Thread cu    045                SOS_THR_RUNNING, /**< Thread currently running on CPU */
045                SOS_THR_BLOCKED, /**< Thread wa    046                SOS_THR_BLOCKED, /**< Thread waiting for I/O (+ in at LEAST
046                                      one kwait    047                                      one kwaitq) and/or sleeping (+ in NO
047                                      kwaitq) *    048                                      kwaitq) */
048                SOS_THR_ZOMBIE,  /**< Thread te    049                SOS_THR_ZOMBIE,  /**< Thread terminated execution, waiting to
049                                      be delete    050                                      be deleted by kernel */
050              } sos_thread_state_t;                051              } sos_thread_state_t;
051                                                   052 
052                                                   053 
053 /**                                               054 /**
054  * TCB (Thread Control Block): structure descr    055  * TCB (Thread Control Block): structure describing a thread. Don't
055  * access these fields directly: prefer using     056  * access these fields directly: prefer using the accessor functions
056  * below.                                         057  * below.
057  */                                               058  */
058 struct sos_thread                                 059 struct sos_thread
059 {                                                 060 {
060 #define SOS_THR_MAX_NAMELEN 32                    061 #define SOS_THR_MAX_NAMELEN 32
061   char name[SOS_THR_MAX_NAMELEN];                 062   char name[SOS_THR_MAX_NAMELEN];
062                                                   063 
063   sos_thread_state_t  state;                      064   sos_thread_state_t  state;
                                                   >> 065   sos_sched_priority_t priority;
064                                                   066 
065   /**                                             067   /**
066    * The hardware context of the thread.          068    * The hardware context of the thread.
067    *                                              069    *
068    * It will reflect the CPU state of the thre    070    * It will reflect the CPU state of the thread:
069    *  - From an interrupt handler: the state o    071    *  - From an interrupt handler: the state of the thread at the time
070    *    of the OUTERMOST irq. An IRQ is not al    072    *    of the OUTERMOST irq. An IRQ is not allowed to make context
071    *    switches, so this context will remain     073    *    switches, so this context will remain valid from the begining of
072    *    the outermost IRQ handler to the end o    074    *    the outermost IRQ handler to the end of it, no matter if there
073    *    are other IRQ handlers nesting in one     075    *    are other IRQ handlers nesting in one another. You may safely
074    *    use it from IRQ handlers to query the     076    *    use it from IRQ handlers to query the state of the interrupted
075    *    thread, no matter if there has been ot    077    *    thread, no matter if there has been other IRQ handlers
076    *    executing meanwhile.                      078    *    executing meanwhile.
077    *  - From normal kernel code, exceptions an    079    *  - From normal kernel code, exceptions and syscall: the state of
078    *    the thread the last time there was a c    080    *    the thread the last time there was a context switch from this
079    *    thread to another one. Thus this field    081    *    thread to another one. Thus this field WON'T reflect the
080    *    current's thread cpu_state in these ca    082    *    current's thread cpu_state in these cases. So, in these cases,
081    *    simply DO NOT USE IT outside thread.c     083    *    simply DO NOT USE IT outside thread.c ! Note: for syscall and
082    *    exception handlers, the VALID state of    084    *    exception handlers, the VALID state of the interrupted thread is
083    *    passed as an argument to the handlers.    085    *    passed as an argument to the handlers.
084    */                                             086    */
085   struct sos_cpu_state *cpu_state;                087   struct sos_cpu_state *cpu_state;
086                                                   088 
087   /* Kernel stack parameters */                   089   /* Kernel stack parameters */
088   sos_vaddr_t kernel_stack_base_addr;             090   sos_vaddr_t kernel_stack_base_addr;
089   sos_size_t  kernel_stack_size;                  091   sos_size_t  kernel_stack_size;
090                                                   092 
                                                   >> 093   /* Process this thread belongs to. Always NULL for a kernel
                                                   >> 094      thread */
                                                   >> 095   struct sos_process *process;
                                                   >> 096 
                                                   >> 097   /**
                                                   >> 098    * Address space currently "squatted" by the thread, or used to be
                                                   >> 099    * active when the thread was interrupted/preempted. This is the MMU
                                                   >> 100    * configuration expected before the cpu_state of the thread is
                                                   >> 101    * restored on CPU.
                                                   >> 102    *   - For kernel threads: should normally be NULL, meaning that the
                                                   >> 103    *     thread will squat the current mm_context currently set in the
                                                   >> 104    *     MMU. Might be NON NULL when a kernel thread squats a given
                                                   >> 105    *     process to manipulate its address space.
                                                   >> 106    *   - For user threads: should normally be NULL. More precisely:
                                                   >> 107    *       - in user mode: the thread->process.mm_context is ALWAYS
                                                   >> 108    *         set on MMU. squatted_mm_context is ALWAYS NULL in this
                                                   >> 109    *         situation, meaning that the thread in user mode uses its
                                                   >> 110    *         process-space as expected
                                                   >> 111    *       - in kernel mode: NULL means that we keep on using the
                                                   >> 112    *         mm_context currently set on MMU, which might be the
                                                   >> 113    *         mm_context of another process. This is natural since a
                                                   >> 114    *         thread in kernel mode normally only uses data in kernel
                                                   >> 115    *         space. BTW, this limits the number of TLB flushes. However,
                                                   >> 116    *         there are exceptions where this squatted_mm_context will
                                                   >> 117    *         NOT be NULL. One is the copy_from/to_user API, which can
                                                   >> 118    *         force the effective mm_context so that the MMU will be
                                                   >> 119    *         (re)configured upon every context to the thread to match
                                                   >> 120    *         the squatted_mm_context. Another exception is when a parent
                                                   >> 121    *         thread creates the address space of a child process, in
                                                   >> 122    *         which case the parent thread might temporarilly decide to
                                                   >> 123    *         switch to the child's process space.
                                                   >> 124    *
                                                   >> 125    * This is the SOS implementation of the Linux "Lazy TLB" and
                                                   >> 126    * address-space loaning.
                                                   >> 127    */
                                                   >> 128   struct sos_mm_context *squatted_mm_context;
                                                   >> 129 
091   /* Data specific to each state */               130   /* Data specific to each state */
092   union                                           131   union
093   {                                               132   {
094     struct                                        133     struct
095     {                                             134     {
                                                   >> 135       struct sos_sched_queue *rdy_queue;
096       struct sos_thread     *rdy_prev, *rdy_ne    136       struct sos_thread     *rdy_prev, *rdy_next;
097     } ready;                                      137     } ready;
                                                   >> 138 
                                                   >> 139     struct
                                                   >> 140     {
                                                   >> 141       struct sos_time user_time_spent_in_slice;
                                                   >> 142     } running;
098   }; /* Anonymous union (gcc extenion) */         143   }; /* Anonymous union (gcc extenion) */
099                                                   144 
100                                                   145 
101   /*                                              146   /*
102    * Data used by the kwaitq subsystem: list o    147    * Data used by the kwaitq subsystem: list of kwaitqueues the thread
103    * is waiting for.                              148    * is waiting for.
104    *                                              149    *
105    * @note: a RUNNING or READY thread might be    150    * @note: a RUNNING or READY thread might be in one or more
106    * waitqueues ! The only property we have is    151    * waitqueues ! The only property we have is that, among these
107    * waitqueues (if any), _at least_ one has w    152    * waitqueues (if any), _at least_ one has woken the thread.
108    */                                             153    */
109   struct sos_kwaitq_entry *kwaitq_list;           154   struct sos_kwaitq_entry *kwaitq_list;
110                                                   155 
111                                                   156 
112   /**                                             157   /**
                                                   >> 158    * Some statistics
                                                   >> 159    */
                                                   >> 160   struct rusage
                                                   >> 161   {
                                                   >> 162     /* Updated by sched.c */
                                                   >> 163     struct sos_time ru_utime; /* Time spent in user mode */
                                                   >> 164     struct sos_time ru_stime; /* Time spent in kernel mode */
                                                   >> 165   } rusage;
                                                   >> 166 
                                                   >> 167 
                                                   >> 168   /**
                                                   >> 169    * Chaining pointers for the list of threads in the parent process
                                                   >> 170    */
                                                   >> 171   struct sos_thread *prev_in_process, *next_in_process;
                                                   >> 172 
                                                   >> 173 
                                                   >> 174   /**
113    * Chaining pointers for global ("gbl") list    175    * Chaining pointers for global ("gbl") list of threads (debug)
114    */                                             176    */
115   struct sos_thread *gbl_prev, *gbl_next;         177   struct sos_thread *gbl_prev, *gbl_next;
116 };                                                178 };
117                                                   179 
118                                                   180 
119 /**                                               181 /**
120  * Definition of the function executed by a ke    182  * Definition of the function executed by a kernel thread
121  */                                               183  */
122 typedef void (*sos_kernel_thread_start_routine    184 typedef void (*sos_kernel_thread_start_routine_t)(void *arg);
123                                                   185 
124                                                   186 
125 /**                                               187 /**
126  * Initialize the subsystem responsible for th    188  * Initialize the subsystem responsible for thread management
127  *                                                189  *
128  * Initialize the primary kernel thread so tha    190  * Initialize the primary kernel thread so that it can be handled the
129  * same way as an ordinary thread created by s    191  * same way as an ordinary thread created by sos_thread_create().
130  */                                               192  */
131 sos_ret_t sos_thread_subsystem_setup(sos_vaddr    193 sos_ret_t sos_thread_subsystem_setup(sos_vaddr_t init_thread_stack_base_addr,
132                                      sos_size_    194                                      sos_size_t init_thread_stack_size);
133                                                   195 
134                                                   196 
135 /**                                               197 /**
136  * Create a new kernel thread                     198  * Create a new kernel thread
137  */                                               199  */
138 struct sos_thread *                               200 struct sos_thread *
139 sos_create_kernel_thread(const char *name,        201 sos_create_kernel_thread(const char *name,
140                          sos_kernel_thread_sta    202                          sos_kernel_thread_start_routine_t start_func,
141                          void *start_arg);     !! 203                          void *start_arg,
                                                   >> 204                          sos_sched_priority_t priority);
                                                   >> 205 
                                                   >> 206 
                                                   >> 207 /**
                                                   >> 208  * Create a new user thread
                                                   >> 209  */
                                                   >> 210 struct sos_thread *
                                                   >> 211 sos_create_user_thread(const char *name,
                                                   >> 212                        struct sos_process *process,
                                                   >> 213                        sos_uaddr_t user_initial_PC,
                                                   >> 214                        sos_ui32_t  user_start_arg1,
                                                   >> 215                        sos_ui32_t  user_start_arg2,
                                                   >> 216                        sos_uaddr_t user_initial_SP,
                                                   >> 217                        sos_sched_priority_t priority);
142                                                   218 
143                                                   219 
144 /**                                               220 /**
145  * Terminate the execution of the current thre    221  * Terminate the execution of the current thread. For kernel threads,
146  * it is called by default when the start rout    222  * it is called by default when the start routine returns.
147  */                                               223  */
148 void sos_thread_exit() __attribute__((noreturn    224 void sos_thread_exit() __attribute__((noreturn));
149                                                   225 
150                                                   226 
151 /**                                               227 /**
152  * Get the identifier of the thread currently     228  * Get the identifier of the thread currently running on CPU. Trivial
153  * function.                                      229  * function.
154  */                                               230  */
155 struct sos_thread *sos_thread_get_current();      231 struct sos_thread *sos_thread_get_current();
156                                                   232 
157                                                   233 
158 /**                                               234 /**
                                                   >> 235  * If thr == NULL, set the priority of the current thread. Trivial
                                                   >> 236  * function.
                                                   >> 237  *
                                                   >> 238  * @note NOT protected against interrupts
                                                   >> 239  */
                                                   >> 240 sos_sched_priority_t sos_thread_get_priority(struct sos_thread *thr);
                                                   >> 241 
                                                   >> 242 
                                                   >> 243 /**
159  * If thr == NULL, get the state of the curren    244  * If thr == NULL, get the state of the current thread. Trivial
160  * function.                                      245  * function.
161  *                                                246  *
162  * @note NOT protected against interrupts         247  * @note NOT protected against interrupts
163  */                                               248  */
164 sos_thread_state_t sos_thread_get_state(struct    249 sos_thread_state_t sos_thread_get_state(struct sos_thread *thr);
165                                                   250 
166                                                   251 
167 /**                                               252 /**
                                                   >> 253  * If thr == NULL, set the priority of the current thread
                                                   >> 254  *
                                                   >> 255  * @note NO context-switch ever occurs in this function !
                                                   >> 256  */
                                                   >> 257 sos_ret_t sos_thread_set_priority(struct sos_thread *thr,
                                                   >> 258                                   sos_sched_priority_t priority);
                                                   >> 259 
                                                   >> 260 
                                                   >> 261 /**
168  * Yield CPU to another ready thread.             262  * Yield CPU to another ready thread.
169  *                                                263  *
170  * @note This is a BLOCKING FUNCTION              264  * @note This is a BLOCKING FUNCTION
171  */                                               265  */
172 sos_ret_t sos_thread_yield();                     266 sos_ret_t sos_thread_yield();
173                                                   267 
174                                                   268 
175 /**                                               269 /**
176  * Release the CPU for (at least) the given de    270  * Release the CPU for (at least) the given delay.
177  *                                                271  *
178  * @param delay The delay to wait for. If dela    272  * @param delay The delay to wait for. If delay == NULL then wait
179  * forever that any event occurs.                 273  * forever that any event occurs.
180  *                                                274  *
181  * @return SOS_OK when delay expired (and dela    275  * @return SOS_OK when delay expired (and delay is reset to zero),
182  * -SOS_EINTR otherwise (and delay contains th    276  * -SOS_EINTR otherwise (and delay contains the amount of time
183  * remaining).                                    277  * remaining).
184  *                                                278  *
185  * @note This is a BLOCKING FUNCTION              279  * @note This is a BLOCKING FUNCTION
186  */                                               280  */
187 sos_ret_t sos_thread_sleep(/* in/out */struct     281 sos_ret_t sos_thread_sleep(/* in/out */struct sos_time *delay);
188                                                   282 
189                                                   283 
190 /**                                               284 /**
191  * Mark the given thread as READY (if not alre    285  * Mark the given thread as READY (if not already ready) even if it is
192  * blocked in a kwaitq or in a sleep ! As a re    286  * blocked in a kwaitq or in a sleep ! As a result, the interrupted
193  * kwaitq/sleep function call of the thread wi    287  * kwaitq/sleep function call of the thread will return with
194  * -SOS_EINTR.                                    288  * -SOS_EINTR.
195  *                                                289  *
196  * @return -SOS_EINVAL if thread does not exis    290  * @return -SOS_EINVAL if thread does not exist, or -SOS_EFATAL if
197  * marked ZOMBIE.                                 291  * marked ZOMBIE.
198  *                                                292  *
199  * @note As a result, the semaphore/mutex/cond    293  * @note As a result, the semaphore/mutex/conditions/... functions
200  * return values SHOULD ALWAYS be checked ! If    294  * return values SHOULD ALWAYS be checked ! If they are != SOS_OK,
201  * then the caller should consider that the re    295  * then the caller should consider that the resource is not aquired
202  * because somebody woke the thread by some wa    296  * because somebody woke the thread by some way.
203  */                                               297  */
204 sos_ret_t sos_thread_force_unblock(struct sos_    298 sos_ret_t sos_thread_force_unblock(struct sos_thread *thread);
                                                   >> 299 
                                                   >> 300 /**
                                                   >> 301  * Dump the backtrace of the current thread to console and/or bochs
                                                   >> 302  */
                                                   >> 303 void sos_thread_dump_backtrace(sos_bool_t on_console,
                                                   >> 304                                sos_bool_t on_bochs);
                                                   >> 305 
                                                   >> 306 
                                                   >> 307 /* **********************************************
                                                   >> 308  * Restricted functions
                                                   >> 309  */
                                                   >> 310 
                                                   >> 311 
                                                   >> 312 /**
                                                   >> 313  * Restricted function to change the current mm_context AND the
                                                   >> 314  * squatted_mm_context of the current thread in order to access the data
                                                   >> 315  * in this context
                                                   >> 316  *
                                                   >> 317  *   @param mm_ctxt The mm_ctxt to restore. Might be NULL, meaning that:
                                                   >> 318  *    - for a Kernel thread: the current MMU configuration is never
                                                   >> 319  *      modified. The address space to use is limited to the kernel
                                                   >> 320  *      space, user space might change due to preemptions to other
                                                   >> 321  *      processes
                                                   >> 322  *    - for a User thread in kernel mode: same as for kernel threads
                                                   >> 323  *    - when a User thread will go back in user context: the MMU will
                                                   >> 324  *      be reconfigured to match the mm_context of the thread's
                                                   >> 325  *      process
                                                   >> 326  *
                                                   >> 327  * @note A non NULL parameter is allowed only if the
                                                   >> 328  * squatted_mm_context is not already set. A NULL parameter is allowed
                                                   >> 329  * only if the squatted_mm_context was already set.
                                                   >> 330  *
                                                   >> 331  * @note The use of this function is RESERVED to the syscall handler
                                                   >> 332  * and the copy_from/to_user functions
                                                   >> 333  */
                                                   >> 334 sos_ret_t
                                                   >> 335 sos_thread_change_current_mm_context(struct sos_mm_context *mm_ctxt);
                                                   >> 336 
                                                   >> 337 
                                                   >> 338 /**
                                                   >> 339  * Restricted callback called when a syscall goes back in user mode,
                                                   >> 340  * to reconfigure the MMU to match that of the current thread's
                                                   >> 341  * process MMU context.
                                                   >> 342  *
                                                   >> 343  * @note The use of this function is RESERVED to the syscall wrapper
                                                   >> 344  */
                                                   >> 345 void sos_thread_prepare_syscall_switch_back(struct sos_cpu_state *cpu_state);
                                                   >> 346 
                                                   >> 347 
                                                   >> 348 /**
                                                   >> 349  * Restricted callback called when an exception handler goes back to
                                                   >> 350  * the interrupted thread to reconfigure the MMU to match that of the
                                                   >> 351  * current thread's process MMU context.
                                                   >> 352  *
                                                   >> 353  * @note The use of this function is RESERVED to the exception wrappers
                                                   >> 354  */
                                                   >> 355 void sos_thread_prepare_exception_switch_back(struct sos_cpu_state *cpu_state);
                                                   >> 356 
                                                   >> 357 
                                                   >> 358 /**
                                                   >> 359  * Restricted callback called when an IRQ is entered while the CPU was
                                                   >> 360  * NOT already servicing any other IRQ (ie the outermost IRQ handler
                                                   >> 361  * is entered). This callback simply updates the "cpu_state" field so
                                                   >> 362  * that IRQ handlers always know the state of the interrupted thread,
                                                   >> 363  * even if they are imbricated in other IRQ handlers.
                                                   >> 364  *
                                                   >> 365  * @note The use of this function is RESERVED to the irq wrappers
                                                   >> 366  */
                                                   >> 367 void
                                                   >> 368 sos_thread_prepare_irq_servicing(struct sos_cpu_state *interrupted_state);
                                                   >> 369 
                                                   >> 370 
                                                   >> 371 /**
                                                   >> 372  * Restricted callback called when the outermost IRQ handler returns,
                                                   >> 373  * to select the thread to return to. This callbacks implements:
                                                   >> 374  *   - preemption of user threads in user mode (time sharing / FIFO)
                                                   >> 375  *   - non-preemption of user threads in kernel mode (interrupted thread
                                                   >> 376  *     is restored on CPU "as is")
                                                   >> 377  *   - non-preemption of kernel threads (same remark)
                                                   >> 378  * The MMU is reconfigured correctly to match the address space of the
                                                   >> 379  * selected thread.
                                                   >> 380  *
                                                   >> 381  * @return The CPU context of the thread to return to
                                                   >> 382  *
                                                   >> 383  * @note The use of this function is RESERVED to the irq wrappers
                                                   >> 384  */
                                                   >> 385 struct sos_cpu_state *
                                                   >> 386 sos_thread_prepare_irq_switch_back(void);
205                                                   387 
206                                                   388 
207 #endif /* _SOS_THREAD_H_ */                       389 #endif /* _SOS_THREAD_H_ */
                                                      

source navigation ] diff markup ] identifier search ] general search ]