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 <hwcore/mm_context.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 MMU translation tables'
044       configuration */
045   struct sos_mm_context  *mm_context;
046 
047   /** Second important resource: the CPU execution contexts, aka the
048       threads executing in the context of this process. */
049   struct sos_thread      *thread_list;
050   sos_count_t            nb_threads;
051 
052   /** Reference counter, including threads */
053   sos_count_t            ref_cnt;
054 
055   struct sos_process     *prev, *next;
056 };
057 
058 
059 /** The list of processes in the system */
060 static struct sos_process *process_list = NULL;
061 
062 
063 /** The cache for the sos_process structures */
064 struct sos_kslab_cache *cache_struct_process;
065 
066 
067 /**
068  * Helper function for debugging purposes
069  */
070 void sos_process_dumplist()
071 {
072   struct sos_thread * cur_thr = sos_thread_get_current();
073   struct sos_process * proc;
074   int nb_procs;
075 
076   sos_bochs_printf("<ps>\n");
077   list_foreach(process_list, proc, nb_procs)
078     {
079       struct sos_thread * thr;
080       int    nb_thrs;
081 
082       sos_bochs_printf("  proc@%p: '%s', %d threads, %d refs\n",
083                        proc, proc->name?proc->name:"(none)",
084                        proc->nb_threads, proc->ref_cnt);
085 
086       list_foreach_forward_named(proc->thread_list, thr, nb_thrs,
087                                  prev_in_process, next_in_process)
088         {
089           if (thr == cur_thr)
090             sos_bochs_printf("    thr@%p: [CURRENT]\n", thr);
091           else
092             sos_bochs_printf("    thr@%p: %cstate=%d eip=%p\n",
093                              thr,
094                              sos_cpu_context_is_in_user_mode(thr->cpu_state)?'u':'k',
095                              thr->state,
096                              (void*)sos_cpu_context_get_PC(thr->cpu_state));
097         }
098     }
099   sos_bochs_printf("  ======= %d processes =======\n", nb_procs);
100   sos_bochs_printf("</ps>\n");
101 }
102 
103 
104 sos_ret_t sos_process_subsystem_setup()
105 {
106   /* Create the cache for the process structures */
107   cache_struct_process = sos_kmem_cache_create("struct_process",
108                                                sizeof(struct sos_process),
109                                                3,
110                                                0,
111                                                SOS_KSLAB_CREATE_MAP
112                                                | SOS_KSLAB_CREATE_ZERO);
113   if (! cache_struct_process)
114     return -SOS_ENOMEM;
115 
116   return SOS_OK;
117 }
118 
119 
120 struct sos_process *sos_process_create_empty(const char *name)
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   /* Initialize a new mm_context */
133   proc->mm_context = sos_mm_context_create();
134   if (NULL == proc->mm_context)
135     {
136       /* Error */
137       sos_kmem_cache_free((sos_vaddr_t)proc);
138       return NULL;
139     }
140 
141   if (!name)
142     {
143         name = "[UNNAMED]";
144     }
145 
146   strzcpy(proc->name, name, SOS_PROCESS_MAX_NAMELEN);
147 
148   /* Add it to the global list of processes */
149   sos_disable_IRQs(flags);
150   list_add_tail(process_list, proc);
151   sos_restore_IRQs(flags);
152 
153   /* Mark the process as referenced */
154   proc->ref_cnt = 1;
155   return proc;
156 }
157 
158 
159 inline
160 sos_ret_t sos_process_ref(struct sos_process *proc)
161 {
162   sos_ui32_t flags;
163   sos_disable_IRQs(flags);
164   proc->ref_cnt ++;
165   sos_restore_IRQs(flags);
166   return SOS_OK;
167 }
168 
169 
170 sos_count_t sos_process_get_nb_threads(const struct sos_process *proc)
171 {
172   sos_count_t retval;
173   sos_ui32_t flags;
174   sos_disable_IRQs(flags);
175   retval = proc->nb_threads;
176   sos_restore_IRQs(flags);
177   return retval;
178 }
179 
180 
181 struct sos_mm_context *
182 sos_process_get_mm_context(const struct sos_process *proc)
183 {
184   return proc->mm_context;
185 }
186 
187 
188 /* ***************************************************
189  * Restricted functions
190  */
191 
192 
193 sos_ret_t sos_process_register_thread(struct sos_process *in_proc,
194                                       struct sos_thread *thr)
195 {
196   sos_ui32_t flags;
197 
198   /* The process is assumed to be referenced by somebody */
199   SOS_ASSERT_FATAL(in_proc->ref_cnt > 0);
200 
201   /* Only threads that are being created are allowed to be attached to
202      a process */
203   SOS_ASSERT_FATAL(thr->state == SOS_THR_CREATED);
204 
205   /* Update the list of the threads in the process */
206   thr->process = in_proc;
207 
208   /* Increment the reference count for the process */
209   sos_process_ref(in_proc);
210 
211   /* Add the thread to the process thread's list */
212   sos_disable_IRQs(flags);
213   list_add_tail_named(in_proc->thread_list, thr,
214                       prev_in_process, next_in_process);
215   in_proc->nb_threads ++;
216   sos_restore_IRQs(flags);
217 
218   return SOS_OK;
219 }
220 
221 
222 /** The function responsible for releasing the resources held by the
223     process. */
224 sos_ret_t sos_process_unref(struct sos_process *proc)
225 {
226   sos_ui32_t flags;
227   sos_ret_t retval;
228 
229   SOS_ASSERT_FATAL(proc->ref_cnt > 0);
230 
231   sos_disable_IRQs(flags);
232   proc->ref_cnt --;
233   if (proc->ref_cnt > 0)
234     {
235       sos_restore_IRQs(flags);
236       return -SOS_EBUSY;
237     }
238   list_delete(process_list, proc);
239   sos_restore_IRQs(flags);
240 
241   /* First: release the mm_context */
242   retval = sos_mm_context_unref(proc->mm_context);
243   SOS_ASSERT_FATAL(SOS_OK == retval);
244 
245   /* Free the process structure */
246   sos_kmem_cache_free((sos_vaddr_t)proc);
247 
248   return SOS_OK;
249 }
250 
251 
252 sos_ret_t sos_process_unregister_thread(struct sos_thread *thr)
253 {
254   sos_ui32_t flags;
255   struct sos_process * in_proc = thr->process;
256 
257   SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBIE);
258   
259   /* Update the list of the threads in the process */
260   thr->process = NULL;
261   sos_disable_IRQs(flags);
262   list_delete_named(in_proc->thread_list, thr,
263                     prev_in_process, next_in_process);
264   SOS_ASSERT_FATAL(in_proc->nb_threads > 0);
265   in_proc->nb_threads --;
266   sos_restore_IRQs(flags);
267  
268   /* Unreference the process */
269   sos_process_unref(in_proc);
270 
271   return SOS_OK;
272 }
273 
274 
275 sos_ret_t sos_process_set_name(struct sos_process * proc,
276                                const char * new_name)
277 {
278   strzcpy(proc->name, new_name, SOS_PROCESS_MAX_NAMELEN);
279   return SOS_OK;
280 }

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