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 ]

001 /* Copyright (C) 2004,2005 David Decotigny
002 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007    
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012    
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA. 
017 */
018 #ifndef _SOS_THREAD_H_
019 #define _SOS_THREAD_H_
020 
021 /**
022  * @file thread.h
023  *
024  * SOS Thread management API
025  */
026 
027 #include <sos/errno.h>
028 
029 /* Forward declaration */
030 struct sos_thread;
031 
032 #include <hwcore/cpu_context.h>
033 #include <sos/sched.h>
034 #include <sos/kwaitq.h>
035 #include <sos/time.h>
036 
037 /**
038  * The possible states of a valid thread
039  */
040 typedef enum { SOS_THR_CREATED, /**< Thread created, not fully initialized */
041                SOS_THR_READY,   /**< Thread fully initialized or
042                                      waiting for CPU after having been
043                                      blocked or preempted */
044                SOS_THR_RUNNING, /**< Thread currently running on CPU */
045                SOS_THR_BLOCKED, /**< Thread waiting for I/O (+ in at LEAST
046                                      one kwaitq) and/or sleeping (+ in NO
047                                      kwaitq) */
048                SOS_THR_ZOMBIE,  /**< Thread terminated execution, waiting to
049                                      be deleted by kernel */
050              } sos_thread_state_t;
051 
052 
053 /**
054  * TCB (Thread Control Block): structure describing a thread. Don't
055  * access these fields directly: prefer using the accessor functions
056  * below.
057  */
058 struct sos_thread
059 {
060 #define SOS_THR_MAX_NAMELEN 32
061   char name[SOS_THR_MAX_NAMELEN];
062 
063   sos_thread_state_t  state;
064 
065   /**
066    * The hardware context of the thread.
067    *
068    * It will reflect the CPU state of the thread:
069    *  - From an interrupt handler: the state of the thread at the time
070    *    of the OUTERMOST irq. An IRQ is not allowed to make context
071    *    switches, so this context will remain valid from the begining of
072    *    the outermost IRQ handler to the end of it, no matter if there
073    *    are other IRQ handlers nesting in one another. You may safely
074    *    use it from IRQ handlers to query the state of the interrupted
075    *    thread, no matter if there has been other IRQ handlers
076    *    executing meanwhile.
077    *  - From normal kernel code, exceptions and syscall: the state of
078    *    the thread the last time there was a context switch from this
079    *    thread to another one. Thus this field WON'T reflect the
080    *    current's thread cpu_state in these cases. So, in these cases,
081    *    simply DO NOT USE IT outside thread.c ! Note: for syscall and
082    *    exception handlers, the VALID state of the interrupted thread is
083    *    passed as an argument to the handlers.
084    */
085   struct sos_cpu_state *cpu_state;
086 
087   /* Kernel stack parameters */
088   sos_vaddr_t kernel_stack_base_addr;
089   sos_size_t  kernel_stack_size;
090 
091   /* Data specific to each state */
092   union
093   {
094     struct
095     {
096       struct sos_thread     *rdy_prev, *rdy_next;
097     } ready;
098   }; /* Anonymous union (gcc extenion) */
099 
100 
101   /*
102    * Data used by the kwaitq subsystem: list of kwaitqueues the thread
103    * is waiting for.
104    *
105    * @note: a RUNNING or READY thread might be in one or more
106    * waitqueues ! The only property we have is that, among these
107    * waitqueues (if any), _at least_ one has woken the thread.
108    */
109   struct sos_kwaitq_entry *kwaitq_list;
110 
111 
112   /**
113    * Chaining pointers for global ("gbl") list of threads (debug)
114    */
115   struct sos_thread *gbl_prev, *gbl_next;
116 };
117 
118 
119 /**
120  * Definition of the function executed by a kernel thread
121  */
122 typedef void (*sos_kernel_thread_start_routine_t)(void *arg);
123 
124 
125 /**
126  * Initialize the subsystem responsible for thread management
127  *
128  * Initialize the primary kernel thread so that it can be handled the
129  * same way as an ordinary thread created by sos_thread_create().
130  */
131 sos_ret_t sos_thread_subsystem_setup(sos_vaddr_t init_thread_stack_base_addr,
132                                      sos_size_t init_thread_stack_size);
133 
134 
135 /**
136  * Create a new kernel thread
137  */
138 struct sos_thread *
139 sos_create_kernel_thread(const char *name,
140                          sos_kernel_thread_start_routine_t start_func,
141                          void *start_arg);
142 
143 
144 /**
145  * Terminate the execution of the current thread. For kernel threads,
146  * it is called by default when the start routine returns.
147  */
148 void sos_thread_exit() __attribute__((noreturn));
149 
150 
151 /**
152  * Get the identifier of the thread currently running on CPU. Trivial
153  * function.
154  */
155 struct sos_thread *sos_thread_get_current();
156 
157 
158 /**
159  * If thr == NULL, get the state of the current thread. Trivial
160  * function.
161  *
162  * @note NOT protected against interrupts
163  */
164 sos_thread_state_t sos_thread_get_state(struct sos_thread *thr);
165 
166 
167 /**
168  * Yield CPU to another ready thread.
169  *
170  * @note This is a BLOCKING FUNCTION
171  */
172 sos_ret_t sos_thread_yield();
173 
174 
175 /**
176  * Release the CPU for (at least) the given delay.
177  *
178  * @param delay The delay to wait for. If delay == NULL then wait
179  * forever that any event occurs.
180  *
181  * @return SOS_OK when delay expired (and delay is reset to zero),
182  * -SOS_EINTR otherwise (and delay contains the amount of time
183  * remaining).
184  *
185  * @note This is a BLOCKING FUNCTION
186  */
187 sos_ret_t sos_thread_sleep(/* in/out */struct sos_time *delay);
188 
189 
190 /**
191  * 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 result, the interrupted
193  * kwaitq/sleep function call of the thread will return with
194  * -SOS_EINTR.
195  *
196  * @return -SOS_EINVAL if thread does not exist, or -SOS_EFATAL if
197  * marked ZOMBIE.
198  *
199  * @note As a result, the semaphore/mutex/conditions/... functions
200  * return values SHOULD ALWAYS be checked ! If they are != SOS_OK,
201  * then the caller should consider that the resource is not aquired
202  * because somebody woke the thread by some way.
203  */
204 sos_ret_t sos_thread_force_unblock(struct sos_thread *thread);
205 
206 
207 #endif /* _SOS_THREAD_H_ */

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