5
5
// http://opensource.org/licenses/MIT>, at your option. This file may not be
6
6
// copied, modified, or distributed except according to those terms.
7
7
8
- use crate :: arch:: irq:: { irq_nested_disable, irq_nested_enable} ;
9
8
use crate :: arch:: switch;
9
+ use crate :: collections:: irqsave;
10
10
use crate :: consts:: * ;
11
11
use crate :: errno:: * ;
12
12
use crate :: logging:: * ;
@@ -61,37 +61,45 @@ impl Scheduler {
61
61
}
62
62
63
63
pub fn spawn ( & mut self , func : extern "C" fn ( ) , prio : TaskPriority ) -> Result < TaskId > {
64
- let prio_number = prio. into ( ) as usize ;
64
+ let closure = || {
65
+ let prio_number = prio. into ( ) as usize ;
65
66
66
- if prio_number >= NO_PRIORITIES {
67
- return Err ( Error :: BadPriority ) ;
68
- }
67
+ if prio_number >= NO_PRIORITIES {
68
+ return Err ( Error :: BadPriority ) ;
69
+ }
70
+
71
+ // Create the new task.
72
+ let tid = self . get_tid ( ) ;
73
+ let task = Rc :: new ( RefCell :: new ( Task :: new ( tid, TaskStatus :: TaskReady , prio) ) ) ;
69
74
70
- // Create the new task.
71
- let tid = self . get_tid ( ) ;
72
- let task = Rc :: new ( RefCell :: new ( Task :: new ( tid, TaskStatus :: TaskReady , prio) ) ) ;
75
+ task. borrow_mut ( ) . create_stack_frame ( func) ;
73
76
74
- task. borrow_mut ( ) . create_stack_frame ( func) ;
77
+ // Add it to the task lists.
78
+ self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
79
+ self . tasks . lock ( ) . insert ( tid, task) ;
80
+ NO_TASKS . fetch_add ( 1 , Ordering :: SeqCst ) ;
75
81
76
- // Add it to the task lists.
77
- self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
78
- self . tasks . lock ( ) . insert ( tid, task) ;
79
- NO_TASKS . fetch_add ( 1 , Ordering :: SeqCst ) ;
82
+ info ! ( "Creating task {}" , tid) ;
80
83
81
- info ! ( "Creating task {}" , tid) ;
84
+ Ok ( tid)
85
+ } ;
82
86
83
- Ok ( tid )
87
+ irqsave ( closure )
84
88
}
85
89
86
90
pub fn exit ( & mut self ) -> ! {
87
- if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
88
- info ! ( "finish task with id {}" , self . current_task. borrow( ) . id) ;
89
- self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskFinished ;
90
- // update the number of tasks
91
- NO_TASKS . fetch_sub ( 1 , Ordering :: SeqCst ) ;
92
- } else {
93
- panic ! ( "unable to terminate idle task" ) ;
94
- }
91
+ let closure = || {
92
+ if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
93
+ info ! ( "finish task with id {}" , self . current_task. borrow( ) . id) ;
94
+ self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskFinished ;
95
+ // update the number of tasks
96
+ NO_TASKS . fetch_sub ( 1 , Ordering :: SeqCst ) ;
97
+ } else {
98
+ panic ! ( "unable to terminate idle task" ) ;
99
+ }
100
+ } ;
101
+
102
+ irqsave ( closure) ;
95
103
96
104
self . reschedule ( ) ;
97
105
@@ -100,14 +108,18 @@ impl Scheduler {
100
108
}
101
109
102
110
pub fn abort ( & mut self ) -> ! {
103
- if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
104
- info ! ( "abort task with id {}" , self . current_task. borrow( ) . id) ;
105
- self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskFinished ;
106
- // update the number of tasks
107
- NO_TASKS . fetch_sub ( 1 , Ordering :: SeqCst ) ;
108
- } else {
109
- panic ! ( "unable to terminate idle task" ) ;
110
- }
111
+ let closure = || {
112
+ if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
113
+ info ! ( "abort task with id {}" , self . current_task. borrow( ) . id) ;
114
+ self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskFinished ;
115
+ // update the number of tasks
116
+ NO_TASKS . fetch_sub ( 1 , Ordering :: SeqCst ) ;
117
+ } else {
118
+ panic ! ( "unable to terminate idle task" ) ;
119
+ }
120
+ } ;
121
+
122
+ irqsave ( closure) ;
111
123
112
124
self . reschedule ( ) ;
113
125
@@ -116,32 +128,40 @@ impl Scheduler {
116
128
}
117
129
118
130
pub fn block_current_task ( & mut self ) -> Rc < RefCell < Task > > {
119
- if self . current_task . borrow ( ) . status == TaskStatus :: TaskRunning {
120
- debug ! ( "block task {}" , self . current_task. borrow( ) . id) ;
131
+ let closure = || {
132
+ if self . current_task . borrow ( ) . status == TaskStatus :: TaskRunning {
133
+ debug ! ( "block task {}" , self . current_task. borrow( ) . id) ;
134
+
135
+ self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskBlocked ;
136
+ self . current_task . clone ( )
137
+ } else {
138
+ panic ! ( "unable to block task {}" , self . current_task. borrow( ) . id) ;
139
+ }
140
+ } ;
121
141
122
- self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskBlocked ;
123
- self . current_task . clone ( )
124
- } else {
125
- panic ! ( "unable to block task {}" , self . current_task. borrow( ) . id) ;
126
- }
142
+ irqsave ( closure)
127
143
}
128
144
129
145
pub fn wakeup_task ( & mut self , task : Rc < RefCell < Task > > ) {
130
- if task. borrow ( ) . status == TaskStatus :: TaskBlocked {
131
- debug ! ( "wakeup task {}" , task. borrow( ) . id) ;
146
+ let closure = || {
147
+ if task. borrow ( ) . status == TaskStatus :: TaskBlocked {
148
+ debug ! ( "wakeup task {}" , task. borrow( ) . id) ;
132
149
133
- task. borrow_mut ( ) . status = TaskStatus :: TaskReady ;
134
- self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
135
- }
150
+ task. borrow_mut ( ) . status = TaskStatus :: TaskReady ;
151
+ self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
152
+ }
153
+ } ;
154
+
155
+ irqsave ( closure) ;
136
156
}
137
157
138
158
pub fn get_current_taskid ( & self ) -> TaskId {
139
- self . current_task . borrow ( ) . id
159
+ irqsave ( || self . current_task . borrow ( ) . id )
140
160
}
141
161
142
162
/// Determines the start address of the stack
143
163
pub fn get_current_stack ( & self ) -> usize {
144
- unsafe { ( * self . current_task . borrow ( ) . stack ) . bottom ( ) }
164
+ irqsave ( || unsafe { ( * self . current_task . borrow ( ) . stack ) . bottom ( ) } )
145
165
}
146
166
147
167
pub fn schedule ( & mut self ) {
@@ -221,8 +241,6 @@ impl Scheduler {
221
241
}
222
242
223
243
pub fn reschedule ( & mut self ) {
224
- let flags = irq_nested_disable ( ) ;
225
- self . schedule ( ) ;
226
- irq_nested_enable ( flags) ;
244
+ irqsave ( || self . schedule ( ) ) ;
227
245
}
228
246
}
0 commit comments