Updated copiright notice.
[bertos.git] / kern / proc.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
30  * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
31  * This file is part of DevLib - See README.devlib for information.
32  * -->
33  *
34  * \brief Simple realtime multitasking scheduler.
35  *        Context switching is only done cooperatively.
36  *
37  * \version $Id$
38  *
39  * \author Bernardo Innocenti <bernie@develer.com>
40  * \author Stefano Fedrigo <aleph@develer.com>
41  */
42
43 /*#*
44  *#* $Log$
45  *#* Revision 1.32  2006/09/20 14:19:23  marco
46  *#* Restored test.
47  *#*
48  *#* Revision 1.31  2006/07/19 12:56:27  bernie
49  *#* Convert to new Doxygen style.
50  *#*
51  *#* Revision 1.30  2006/03/27 04:49:23  bernie
52  *#* CPU_IDLE(): Fix for new emulator.
53  *#*
54  *#* Revision 1.29  2006/02/24 01:17:05  bernie
55  *#* Update for new emulator.
56  *#*
57  *#* Revision 1.28  2006/02/21 16:06:55  bernie
58  *#* Cleanup/update process scheduling.
59  *#*
60  *#* Revision 1.27  2005/11/04 16:20:02  bernie
61  *#* Fix reference to README.devlib in header.
62  *#*
63  *#* Revision 1.26  2005/04/11 19:10:28  bernie
64  *#* Include top-level headers from cfg/ subdir.
65  *#*
66  *#* Revision 1.25  2005/03/15 00:20:54  bernie
67  *#* proc_schedule(): New sanity check.
68  *#*
69  *#* Revision 1.24  2005/01/08 09:20:54  bernie
70  *#* Remove unused variable.
71  *#*
72  *#* Revision 1.23  2004/12/13 12:07:06  bernie
73  *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE.
74  *#*
75  *#* Revision 1.22  2004/12/13 11:51:08  bernie
76  *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE.
77  *#*
78  *#* Revision 1.21  2004/11/28 23:20:25  bernie
79  *#* Remove obsolete INITLIST macro.
80  *#*
81  *#* Revision 1.20  2004/11/16 22:37:14  bernie
82  *#* Replace IPTR with iptr_t.
83  *#*
84  *#* Revision 1.19  2004/10/19 11:47:39  bernie
85  *#* Kill warnings when !CONFIG_PROC_MONITOR.
86  *#*
87  *#* Revision 1.18  2004/10/19 08:54:43  bernie
88  *#* Initialize forbid_cnt; Formatting/comments fixes.
89  *#*
90  *#* Revision 1.17  2004/10/19 08:47:13  bernie
91  *#* proc_rename(), proc_forbid(), proc_permit(): New functions.
92  *#*
93  *#* Revision 1.16  2004/10/03 20:39:28  bernie
94  *#* Import changes from sc/firmware.
95  *#*
96  *#* Revision 1.15  2004/09/20 03:29:39  bernie
97  *#* C++ fixes.
98  *#*
99  *#* Revision 1.14  2004/09/14 21:06:44  bernie
100  *#* Use debug.h instead of kdebug.h.
101  *#*
102  *#* Revision 1.13  2004/08/29 21:58:53  bernie
103  *#* Include macros.h explicityl.
104  *#*
105  *#* Revision 1.11  2004/08/24 16:09:08  bernie
106  *#* Add missing header.
107  *#*
108  *#* Revision 1.10  2004/08/24 16:07:01  bernie
109  *#* Use kputs()/kputchar() when possible.
110  *#*
111  *#* Revision 1.9  2004/08/24 14:26:57  bernie
112  *#* monitor_debug_stacks(): Conditionally compile on CONFIG_KERN_MONITOR.
113  *#*
114  *#* Revision 1.8  2004/08/14 19:37:57  rasky
115  *#* Merge da SC: macros.h, pool.h, BIT_CHANGE, nome dei processi, etc.
116  *#*
117  *#* Revision 1.7  2004/08/02 20:20:29  aleph
118  *#* Merge from project_ks
119  *#*
120  *#* Revision 1.6  2004/07/30 14:24:16  rasky
121  *#* Task switching con salvataggio perfetto stato di interrupt (SR)
122  *#* Kernel monitor per dump informazioni su stack dei processi
123  *#*
124  *#* Revision 1.5  2004/07/14 14:18:09  rasky
125  *#* Merge da SC: Rimosso timer dentro il task, che รจ uno spreco di memoria per troppi task
126  *#*
127  *#* Revision 1.4  2004/07/13 19:21:28  aleph
128  *#* Avoid warning for unused arg when compiled without some CONFIG_KERN_xx options
129  *#*
130  *#* Revision 1.3  2004/06/06 18:37:57  bernie
131  *#* Rename event macros to look like regular functions.
132  *#*
133  *#* Revision 1.2  2004/06/03 11:27:09  bernie
134  *#* Add dual-license information.
135  *#*
136  *#* Revision 1.1  2004/05/23 17:27:00  bernie
137  *#* Import kern/ subdirectory.
138  *#*
139  *#*/
140
141 #include "proc_p.h"
142 #include "proc.h"
143 //#include "hw.h"
144 #include <mware/event.h>
145 #include <cfg/cpu.h>
146 #include <cfg/debug.h>
147 #include <cfg/arch_config.h>  /* ARCH_EMUL */
148 #include <cfg/macros.h>  /* ABS() */
149
150 #include <string.h> /* memset() */
151
152 /**
153  * CPU dependent context switching routines.
154  *
155  * \note This function *MUST* preserve also the status of the interrupts.
156  */
157 EXTERN_C void asm_switch_context(cpustack_t **new_sp, cpustack_t **save_sp);
158 EXTERN_C int asm_switch_version(void);
159
160 /*
161  * The scheduer tracks ready and waiting processes
162  * by enqueuing them in these lists. A pointer to the currently
163  * running process is stored in the CurrentProcess pointer.
164  *
165  * NOTE: these variables are protected by DI/EI locking
166  */
167 REGISTER Process *CurrentProcess;
168 REGISTER List     ProcReadyList;
169
170
171 #if CONFIG_KERN_PREEMPTIVE
172 /*
173  * The time sharing scheduler forces a task switch when
174  * the current process has consumed its quantum.
175  */
176 uint16_t Quantum;
177 #endif
178
179
180 /* In Win32 we must emulate stack on the real process stack */
181 #if (ARCH & ARCH_EMUL)
182 extern List StackFreeList;
183 #endif
184
185 /** The main process (the one that executes main()). */
186 struct Process MainProcess;
187
188
189 static void proc_init_struct(Process *proc)
190 {
191         /* Avoid warning for unused argument. */
192         (void)proc;
193
194 #if CONFIG_KERN_SIGNALS
195         proc->sig_recv = 0;
196 #endif
197
198 #if CONFIG_KERN_PREEMPTIVE
199         proc->forbid_cnt = 0;
200 #endif
201
202 #if CONFIG_KERN_HEAP
203         proc->flags = 0;
204 #endif
205 }
206
207
208 void proc_init(void)
209 {
210         LIST_INIT(&ProcReadyList);
211
212 #if CONFIG_KERN_MONITOR
213         monitor_init();
214 #endif
215
216         /* We "promote" the current context into a real process. The only thing we have
217          * to do is create a PCB and make it current. We don't need to setup the stack
218          * pointer because it will be written the first time we switch to another process.
219          */
220         proc_init_struct(&MainProcess);
221         CurrentProcess = &MainProcess;
222
223         /* Make sure the assembly routine is up-to-date with us */
224         ASSERT(asm_switch_version() == 1);
225 }
226
227
228 /**
229  * Create a new process, starting at the provided entry point.
230  *
231  * \return Process structure of new created process
232  *         if successful, NULL otherwise.
233  */
234 struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(void), iptr_t data, size_t stacksize, cpustack_t *stack_base)
235 {
236         Process *proc;
237         size_t i;
238         size_t proc_size_words = ROUND2(sizeof(Process), sizeof(cpustack_t)) / sizeof(cpustack_t);
239 #if CONFIG_KERN_HEAP
240         bool free_stack = false;
241 #endif
242
243 #if (ARCH & ARCH_EMUL)
244         /* Ignore stack provided by caller and use the large enough default instead. */
245         stack_base = (cpustack_t *)LIST_HEAD(&StackFreeList);
246         REMOVE(LIST_HEAD(&StackFreeList));
247         stacksize = CONFIG_KERN_DEFSTACKSIZE;
248 #elif CONFIG_KERN_HEAP
249         /* Did the caller provide a stack for us? */
250         if (!stack_base)
251         {
252                 /* Did the caller specify the desired stack size? */
253                 if (!stacksize)
254                         stacksize = CONFIG_KERN_DEFSTACKSIZE + sizeof(Process);
255
256                 /* Allocate stack dinamically */
257                 if (!(stack_base = heap_alloc(stacksize)))
258                         return NULL;
259
260                 free_stack = true;
261         }
262 #else
263         /* Stack must have been provided by the user */
264         ASSERT(stack_base);
265         ASSERT(stacksize);
266 #endif
267
268 #if CONFIG_KERN_MONITOR
269         /* Fill-in the stack with a special marker to help debugging */
270         memset(stack_base, CONFIG_KERN_STACKFILLCODE, stacksize / sizeof(cpustack_t));
271 #endif
272
273         /* Initialize the process control block */
274         if (CPU_STACK_GROWS_UPWARD)
275         {
276                 proc = (Process*)stack_base;
277                 proc->stack = stack_base + proc_size_words;
278                 if (CPU_SP_ON_EMPTY_SLOT)
279                         proc->stack++;
280         }
281         else
282         {
283                 proc = (Process*)(stack_base + stacksize / sizeof(cpustack_t) - proc_size_words);
284                 proc->stack = (cpustack_t*)proc;
285                 if (CPU_SP_ON_EMPTY_SLOT)
286                         proc->stack--;
287         }
288
289         proc_init_struct(proc);
290         proc->user_data = data;
291
292 #if CONFIG_KERN_HEAP
293         proc->stack_base = stack_base;
294         proc->stack_size = stack_size;
295         if (free_stack)
296                 proc->flags |= PF_FREESTACK;
297 #endif
298
299         /* Initialize process stack frame */
300         CPU_PUSH_CALL_CONTEXT(proc->stack, proc_exit);
301         CPU_PUSH_CALL_CONTEXT(proc->stack, entry);
302
303         /* Push a clean set of CPU registers for asm_switch_context() */
304         for (i = 0; i < CPU_SAVED_REGS_CNT; i++)
305                 CPU_PUSH_WORD(proc->stack, CPU_REG_INIT_VALUE(i));
306
307         /* Add to ready list */
308         ATOMIC(SCHED_ENQUEUE(proc));
309
310 #if CONFIG_KERN_MONITOR
311         monitor_add(proc, name, stack_base, stacksize);
312 #endif
313
314         return proc;
315 }
316
317 /** Rename a process */
318 void proc_rename(struct Process *proc, const char *name)
319 {
320 #if CONFIG_KERN_MONITOR
321         monitor_rename(proc, name);
322 #else
323         (void)proc; (void)name;
324 #endif
325 }
326
327
328 /**
329  * System scheduler: pass CPU control to the next process in
330  * the ready queue.
331  *
332  * Saving and restoring the context on the stack is done
333  * by a CPU-dependent support routine which must usually be
334  * written in assembly.
335  */
336 void proc_schedule(void)
337 {
338         /* This function must not have any "auto" variables, otherwise
339          * the compiler might put them on the stack of the process
340          * being switched out.
341          */
342         static struct Process *old_process;
343         static cpuflags_t flags;
344
345         /* Remember old process to save its context later */
346         old_process = CurrentProcess;
347
348 #ifdef IRQ_RUNNING
349         /* Scheduling in interrupts is a nono. */
350         ASSERT(!IRQ_RUNNING());
351 #endif
352
353         /* Poll on the ready queue for the first ready process */
354         IRQ_SAVE_DISABLE(flags);
355         while (!(CurrentProcess = (struct Process *)list_remHead(&ProcReadyList)))
356         {
357                 /*
358                  * Make sure we physically reenable interrupts here, no matter what
359                  * the current task status is. This is important because if we
360                  * are idle-spinning, we must allow interrupts, otherwise no
361                  * process will ever wake up.
362                  *
363                  * \todo If there was a way to write sig_wait() so that it does not
364                  * disable interrupts while waiting, there would not be any
365                  * reason to do this.
366                  */
367                 IRQ_ENABLE;
368                 CPU_IDLE;
369                 IRQ_DISABLE;
370         }
371         IRQ_RESTORE(flags);
372
373         /*
374          * Optimization: don't switch contexts when the active
375          * process has not changed.
376          */
377         if (CurrentProcess != old_process)
378         {
379                 static cpustack_t *dummy;
380
381 #if CONFIG_KERN_PREEMPTIVE
382                 /* Reset quantum for this process */
383                 Quantum = CONFIG_KERN_QUANTUM;
384 #endif
385
386                 /* Save context of old process and switch to new process. If there is no
387                  * old process, we save the old stack pointer into a dummy variable that
388                  * we ignore. In fact, this happens only when the old process has just
389                  * exited.
390                  * TODO: Instead of physically clearing the process at exit time, a zombie
391                  * list should be created.
392                  */
393                 asm_switch_context(&CurrentProcess->stack, old_process ? &old_process->stack : &dummy);
394         }
395
396         /* This RET resumes the execution on the new process */
397 }
398
399
400 /**
401  * Terminate the current process
402  */
403 void proc_exit(void)
404 {
405 #if CONFIG_KERN_MONITOR
406         monitor_remove(CurrentProcess);
407 #endif
408
409 #if CONFIG_KERN_HEAP
410         /*
411          * The following code is BROKEN.
412          * We are freeing our own stack before entering proc_schedule()
413          * BAJO: A correct fix would be to rearrange the scheduler with
414          *  an additional parameter which frees the old stack/process
415          *  after a context switch.
416          */
417         if (CurrentProcess->flags & PF_FREESTACK)
418                 heap_free(CurrentProcess->stack_base, CurrentProcess->stack_size);
419         heap_free(CurrentProcess);
420 #endif
421
422 #if (ARCH & ARCH_EMUL)
423 #warning This is wrong
424         /* Reinsert process stack in free list */
425         ADDHEAD(&StackFreeList, (Node *)(CurrentProcess->stack
426                 - (CONFIG_KERN_DEFSTACKSIZE / sizeof(cpustack_t))));
427
428         /*
429          * NOTE: At this point the first two words of what used
430          * to be our stack contain a list node. From now on, we
431          * rely on the compiler not reading/writing the stack.
432          */
433 #endif /* ARCH_EMUL */
434
435         CurrentProcess = NULL;
436         proc_schedule();
437         /* not reached */
438 }
439
440
441 /**
442  * Co-operative context switch
443  */
444 void proc_switch(void)
445 {
446         /* Just like proc_schedule, this function must not have auto variables. */
447         static cpuflags_t flags;
448
449         IRQ_SAVE_DISABLE(flags);
450         SCHED_ENQUEUE(CurrentProcess);
451         IRQ_RESTORE(flags);
452
453         proc_schedule();
454 }
455
456
457 /**
458  * Get the pointer to the current process
459  */
460 struct Process *proc_current(void)
461 {
462         return CurrentProcess;
463 }
464
465 /**
466  * Get the pointer to the user data of the current process
467  */
468 iptr_t proc_current_user_data(void)
469 {
470         return CurrentProcess->user_data;
471 }
472
473
474 #if CONFIG_KERN_PREEMPTIVE
475
476 /**
477  * Disable preemptive task switching.
478  *
479  * The scheduler maintains a per-process nesting counter.  Task switching is
480  * effectively re-enabled only when the number of calls to proc_permit()
481  * matches the number of calls to proc_forbid().
482  *
483  * Calling functions that could sleep while task switching is disabled
484  * is dangerous, although supported.  Preemptive task switching is
485  * resumed while the process is sleeping and disabled again as soon as
486  * it wakes up again.
487  *
488  * \sa proc_permit()
489  */
490 void proc_forbid(void)
491 {
492         /* No need to protect against interrupts here. */
493         ++CurrentProcess->forbid_cnt;
494 }
495
496 /**
497  * Re-enable preemptive task switching.
498  *
499  * \sa proc_forbid()
500  */
501 void proc_permit(void)
502 {
503         /* No need to protect against interrupts here. */
504         --CurrentProcess->forbid_cnt;
505 }
506
507 #endif /* CONFIG_KERN_PREEMPTIVE */