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) 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 
019 #include <sos/assert.h>
020 #include <sos/list.h>
021 #include <sos/kmem_slab.h>
022 #include <hwcore/irq.h>
023 #include <drivers/bochs.h>
024 
025 #include <sos/umem_vmm.h>
026 
027 #include "process.h"
028 
029 
030 #define SOS_PROCESS_MAX_NAMELEN 32
031 
032 
033 /**
034  * Definition of a process in SOS. A process is basically the
035  * collection of all the resources requested by a user program. The
036  * threads are one of these resources, the mm_context is one other
037  * example of such resources.
038  */
039 struct sos_process
040 {
041   char name[SOS_PROCESS_MAX_NAMELEN];
042 
043   /** First important resource: the address space */
044   struct sos_umem_vmm_as *address_space;
045 
046   /** Second important resource: the CPU execution contexts, aka the
047       threads executing in the context of this process. */
048   struct sos_thread      *thread_list;
049   sos_count_t            nb_threads;
050 
051   /** Reference counter, including threads */
052   sos_count_t            ref_cnt;
053 
054   struct sos_process     *prev, *next;
055 };
056 
057 
058 /** The list of processes in the system */
059 static struct sos_process *process_list = NULL;
060 
061 
062 /** The cache for the sos_process structures */
063 struct sos_kslab_cache *cache_struct_process;
064 
065 
066 /**
067  * Helper function for debugging purposes
068  */
069 void sos_process_dumplist()
070 {
071   struct sos_thread * cur_thr = sos_thread_get_current();
072   struct sos_process * proc;
073   int nb_procs;
074 
075   sos_bochs_printf("<ps>\n");
076   list_foreach(process_list, proc, nb_procs)
077     {
078       struct sos_thread * thr;
079       int    nb_thrs;
080 
081       sos_bochs_printf("  proc@%p: '%s', %d threads, %d refs\n",
082                        proc, proc->name?proc->name:"(none)",
083                        proc->nb_threads, proc->ref_cnt);
084 
085       list_foreach_forward_named(proc->thread_list, thr, nb_thrs,
086                                  prev_in_process, next_in_process)
087         {
088           if (thr == cur_thr)
089             sos_bochs_printf("    thr@%p: [CURRENT]\n", thr);
090           else
091             sos_bochs_printf("    thr@%p: %cstate=%d eip=%p\n",
092                              thr,
093                              sos_cpu_context_is_in_user_mode(thr->cpu_state)?'u':'k',
094                              thr->state,
095                              (void*)sos_cpu_context_get_PC(thr->cpu_state));
096         }
097     }
098   sos_bochs_printf("  ======= %d processes =======\n", nb_procs);
099   sos_bochs_printf("</ps>\n");
100 }
101 
102 
103 sos_ret_t sos_process_subsystem_setup()
104 {
105   /* Create the cache for the process structures */
106   cache_struct_process = sos_kmem_cache_create("struct_process",
107                                                sizeof(struct sos_process),
108                                                3,
109                                                0,
110                                                SOS_KSLAB_CREATE_MAP
111                                                | SOS_KSLAB_CREATE_ZERO);
112   if (! cache_struct_process)
113     return -SOS_ENOMEM;
114 
115   return SOS_OK;
116 }
117 
118 
119 struct sos_process *sos_process_create(const char *name,
120                                        sos_bool_t do_copy_current_process)
121 {
122   sos_ui32_t flags;
123   struct sos_process *proc;
124 
125   proc = (struct sos_process*) sos_kmem_cache_alloc(cache_struct_process, 0);
126   if (! proc)
127     return NULL;
128 
129   /* proc is already filled with 0 (cache has SOS_KSLAB_CREATE_ZERO
130      flag) */
131 
132   if (do_copy_current_process)
133     proc->address_space = sos_umem_vmm_duplicate_current_thread_as(proc);
134   else
135     proc->address_space = sos_umem_vmm_create_empty_as(proc);
136 
137   if (NULL == proc->address_space)
138     {
139       /* Error */
140       sos_kmem_cache_free((sos_vaddr_t)proc);
141       return NULL;
142     }
143 
144   if (!name)
145     {
146       struct sos_thread * cur_thr = sos_thread_get_current();
147       if (do_copy_current_process)
148         name = cur_thr->process->name;
149       else
150         name = "[UNNAMED]";
151     }
152 
153   strzcpy(proc->name, name, SOS_PROCESS_MAX_NAMELEN);
154 
155   /* Add it to the global list of processes */
156   sos_disable_IRQs(flags);
157   list_add_tail(process_list, proc);
158   sos_restore_IRQs(flags);
159 
160   /* Mark the process as referenced */
161   proc->ref_cnt = 1;
162   return proc;
163 }
164 
165 
166 inline
167 sos_ret_t sos_process_ref(struct sos_process *proc)
168 {
169   sos_ui32_t flags;
170   sos_disable_IRQs(flags);
171   proc->ref_cnt ++;
172   sos_restore_IRQs(flags);
173   return SOS_OK;
174 }
175 
176 
177 sos_count_t sos_process_get_nb_threads(const struct sos_process *proc)
178 {
179   sos_count_t retval;
180   sos_ui32_t flags;
181   sos_disable_IRQs(flags);
182   retval = proc->nb_threads;
183   sos_restore_IRQs(flags);
184   return retval;
185 }
186 
187 
188 struct sos_mm_context *
189 sos_process_get_mm_context(const struct sos_process *proc)
190 {
191   return sos_umem_vmm_get_mm_context(proc->address_space);
192 }
193 
194 
195 struct sos_umem_vmm_as *
196 sos_process_get_address_space(const struct sos_process *proc)
197 {
198   return proc->address_space;
199 }
200 
201 
202 sos_ret_t sos_process_set_address_space(struct sos_process *proc,
203                                         struct sos_umem_vmm_as *new_as)
204 {
205   if (proc->address_space)
206     {
207       sos_ret_t retval = sos_umem_vmm_delete_as(proc->address_space);
208       if (SOS_OK != retval)
209         return retval;
210     }
211 
212   proc->address_space = new_as;
213   return SOS_OK;
214 }
215 
216 
217 /* ***************************************************
218  * Restricted functions
219  */
220 
221 
222 sos_ret_t sos_process_register_thread(struct sos_process *in_proc,
223                                       struct sos_thread *thr)
224 {
225   sos_ui32_t flags;
226 
227   /* The process is assumed to be referenced by somebody */
228   SOS_ASSERT_FATAL(in_proc->ref_cnt > 0);
229 
230   /* Only threads that are being created are allowed to be attached to
231      a process */
232   SOS_ASSERT_FATAL(thr->state == SOS_THR_CREATED);
233 
234   /* Update the list of the threads in the process */
235   thr->process = in_proc;
236 
237   /* Increment the reference count for the process */
238   sos_process_ref(in_proc);
239 
240   /* Add the thread to the process thread's list */
241   sos_disable_IRQs(flags);
242   list_add_tail_named(in_proc->thread_list, thr,
243                       prev_in_process, next_in_process);
244   in_proc->nb_threads ++;
245   sos_restore_IRQs(flags);
246 
247   return SOS_OK;
248 }
249 
250 
251 /** The function responsible for releasing the resources held by the
252     process. */
253 sos_ret_t sos_process_unref(struct sos_process *proc)
254 {
255   sos_ui32_t flags;
256   sos_ret_t retval;
257 
258   SOS_ASSERT_FATAL(proc->ref_cnt > 0);
259 
260   sos_disable_IRQs(flags);
261   proc->ref_cnt --;
262   if (proc->ref_cnt > 0)
263     {
264       sos_restore_IRQs(flags);
265       return -SOS_EBUSY;
266     }
267   list_delete(process_list, proc);
268   sos_restore_IRQs(flags);
269 
270   /* First: free the user address space */
271   retval = sos_umem_vmm_delete_as(proc->address_space);
272   SOS_ASSERT_FATAL(SOS_OK == retval);
273 
274   /* Free the process structure */
275   sos_kmem_cache_free((sos_vaddr_t)proc);
276 
277   return SOS_OK;
278 }
279 
280 
281 sos_ret_t sos_process_unregister_thread(struct sos_thread *thr)
282 {
283   sos_ui32_t flags;
284   struct sos_process * in_proc = thr->process;
285 
286   SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBIE);
287   
288   /* Update the list of the threads in the process */
289   thr->process = NULL;
290   sos_disable_IRQs(flags);
291   list_delete_named(in_proc->thread_list, thr,
292                     prev_in_process, next_in_process);
293   SOS_ASSERT_FATAL(in_proc->nb_threads > 0);
294   in_proc->nb_threads --;
295   sos_restore_IRQs(flags);
296  
297   /* Unreference the process */
298   sos_process_unref(in_proc);
299 
300   return SOS_OK;
301 }
302 
303 
304 sos_ret_t sos_process_set_name(struct sos_process * proc,
305                                const char * new_name)
306 {
307   strzcpy(proc->name, new_name, SOS_PROCESS_MAX_NAMELEN);
308   return SOS_OK;
309 }

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