Merge from trunk.
[bertos.git] / bertos / kern / coop.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, 2008 Develer S.r.l. (http://www.develer.com/)
30  * Copyright 1999, 2000, 2001, 2008 Bernie Innocenti <bernie@codewiz.org>
31  * -->
32  *
33  * \brief Simple cooperative multitasking scheduler.
34  *
35  * \version $Id$
36  * \author Bernie Innocenti <bernie@codewiz.org>
37  * \author Stefano Fedrigo <aleph@develer.com>
38  */
39
40 #include "proc_p.h"
41 #include "proc.h"
42
43 // Log settings for cfg/log.h.
44 #define LOG_LEVEL   KERN_LOG_LEVEL
45 #define LOG_FORMAT  KERN_LOG_FORMAT
46 #include <cfg/log.h>
47
48 #include <cpu/irq.h>
49 #include <cpu/types.h>
50 #include <cpu/attr.h>
51 #include <cpu/frame.h>
52
53 /**
54  * Define function prototypes exported outside.
55  *
56  * Required to silent gcc "no previous prototype" warnings.
57  */
58 void coop_yield(void);
59 void coop_switch(void);
60 void coop_wakeup(Process *proc);
61
62 /**
63  * Give the control of the CPU to another process.
64  *
65  * \note Assume the current process has been already added to a wait queue.
66  *
67  * \warning This should be considered an internal kernel function, even if it
68  * is allowed, usage from application code is strongly discouraged.
69  */
70 void coop_switch(void)
71 {
72         ATOMIC(proc_schedule());
73 }
74
75 /**
76  * Immediately wakeup a process, dispatching it to the CPU.
77  */
78 void coop_wakeup(Process *proc)
79 {
80         ASSERT(proc_preemptAllowed());
81         ASSERT(current_process);
82         IRQ_ASSERT_DISABLED();
83
84         if (prio_proc(proc) >= prio_curr())
85         {
86                 Process *old_process = current_process;
87
88                 SCHED_ENQUEUE(current_process);
89                 current_process = proc;
90                 proc_switchTo(current_process, old_process);
91         }
92         else
93                 SCHED_ENQUEUE_HEAD(proc);
94 }
95
96 /**
97  * Co-operative context switch
98  */
99 void coop_yield(void)
100 {
101         ATOMIC(SCHED_ENQUEUE(current_process));
102         coop_switch();
103 }