6
6
// copied, modified, or distributed except according to those terms.
7
7
8
8
use crate :: arch:: drop_user_space;
9
- use crate :: arch:: irq:: { irq_nested_disable, irq_nested_enable} ;
10
9
use crate :: arch:: switch;
10
+ use crate :: collections:: irqsave;
11
11
use crate :: consts:: * ;
12
12
use crate :: errno:: * ;
13
13
use crate :: logging:: * ;
@@ -62,26 +62,30 @@ impl Scheduler {
62
62
}
63
63
64
64
pub fn spawn ( & mut self , func : extern "C" fn ( ) , prio : TaskPriority ) -> Result < TaskId > {
65
- let prio_number = prio. into ( ) as usize ;
65
+ let closure = || {
66
+ let prio_number = prio. into ( ) as usize ;
66
67
67
- if prio_number >= NO_PRIORITIES {
68
- return Err ( Error :: BadPriority ) ;
69
- }
68
+ if prio_number >= NO_PRIORITIES {
69
+ return Err ( Error :: BadPriority ) ;
70
+ }
71
+
72
+ // Create the new task.
73
+ let tid = self . get_tid ( ) ;
74
+ let task = Rc :: new ( RefCell :: new ( Task :: new ( tid, TaskStatus :: TaskReady , prio) ) ) ;
70
75
71
- // Create the new task.
72
- let tid = self . get_tid ( ) ;
73
- let task = Rc :: new ( RefCell :: new ( Task :: new ( tid, TaskStatus :: TaskReady , prio) ) ) ;
76
+ task. borrow_mut ( ) . create_stack_frame ( func) ;
74
77
75
- task. borrow_mut ( ) . create_stack_frame ( func) ;
78
+ // Add it to the task lists.
79
+ self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
80
+ self . tasks . lock ( ) . insert ( tid, task) ;
81
+ NO_TASKS . fetch_add ( 1 , Ordering :: SeqCst ) ;
76
82
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 ) ;
83
+ info ! ( "Creating task {}" , tid) ;
81
84
82
- info ! ( "Creating task {}" , tid) ;
85
+ Ok ( tid)
86
+ } ;
83
87
84
- Ok ( tid )
88
+ irqsave ( closure )
85
89
}
86
90
87
91
fn cleanup ( & mut self ) {
@@ -95,12 +99,16 @@ impl Scheduler {
95
99
}
96
100
97
101
pub fn exit ( & mut self ) -> ! {
98
- if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
99
- info ! ( "finish task with id {}" , self . current_task. borrow( ) . id) ;
100
- self . cleanup ( ) ;
101
- } else {
102
- panic ! ( "unable to terminate idle task" ) ;
103
- }
102
+ let closure = || {
103
+ if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
104
+ info ! ( "finish task with id {}" , self . current_task. borrow( ) . id) ;
105
+ self . cleanup ( ) ;
106
+ } else {
107
+ panic ! ( "unable to terminate idle task" ) ;
108
+ }
109
+ } ;
110
+
111
+ irqsave ( closure) ;
104
112
105
113
self . reschedule ( ) ;
106
114
@@ -109,12 +117,16 @@ impl Scheduler {
109
117
}
110
118
111
119
pub fn abort ( & mut self ) -> ! {
112
- if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
113
- info ! ( "abort task with id {}" , self . current_task. borrow( ) . id) ;
114
- self . cleanup ( ) ;
115
- } else {
116
- panic ! ( "unable to terminate idle task" ) ;
117
- }
120
+ let closure = || {
121
+ if self . current_task . borrow ( ) . status != TaskStatus :: TaskIdle {
122
+ info ! ( "abort task with id {}" , self . current_task. borrow( ) . id) ;
123
+ self . cleanup ( ) ;
124
+ } else {
125
+ panic ! ( "unable to terminate idle task" ) ;
126
+ }
127
+ } ;
128
+
129
+ irqsave ( closure) ;
118
130
119
131
self . reschedule ( ) ;
120
132
@@ -123,33 +135,41 @@ impl Scheduler {
123
135
}
124
136
125
137
pub fn block_current_task ( & mut self ) -> Rc < RefCell < Task > > {
126
- if self . current_task . borrow ( ) . status == TaskStatus :: TaskRunning {
127
- debug ! ( "block task {}" , self . current_task. borrow( ) . id) ;
138
+ let closure = || {
139
+ if self . current_task . borrow ( ) . status == TaskStatus :: TaskRunning {
140
+ debug ! ( "block task {}" , self . current_task. borrow( ) . id) ;
141
+
142
+ self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskBlocked ;
143
+ self . current_task . clone ( )
144
+ } else {
145
+ panic ! ( "unable to block task {}" , self . current_task. borrow( ) . id) ;
146
+ }
147
+ } ;
128
148
129
- self . current_task . borrow_mut ( ) . status = TaskStatus :: TaskBlocked ;
130
- self . current_task . clone ( )
131
- } else {
132
- panic ! ( "unable to block task {}" , self . current_task. borrow( ) . id) ;
133
- }
149
+ irqsave ( closure)
134
150
}
135
151
136
152
pub fn wakeup_task ( & mut self , task : Rc < RefCell < Task > > ) {
137
- if task. borrow ( ) . status == TaskStatus :: TaskBlocked {
138
- debug ! ( "wakeup task {}" , task. borrow( ) . id) ;
153
+ let closure = || {
154
+ if task. borrow ( ) . status == TaskStatus :: TaskBlocked {
155
+ debug ! ( "wakeup task {}" , task. borrow( ) . id) ;
139
156
140
- task. borrow_mut ( ) . status = TaskStatus :: TaskReady ;
141
- self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
142
- }
157
+ task. borrow_mut ( ) . status = TaskStatus :: TaskReady ;
158
+ self . ready_queue . lock ( ) . push ( task. clone ( ) ) ;
159
+ }
160
+ } ;
161
+
162
+ irqsave ( closure) ;
143
163
}
144
164
145
165
pub fn get_current_taskid ( & self ) -> TaskId {
146
- self . current_task . borrow ( ) . id
166
+ irqsave ( || self . current_task . borrow ( ) . id )
147
167
}
148
168
149
169
/// Determines the start address of the stack
150
170
#[ no_mangle]
151
171
pub fn get_current_stack ( & self ) -> usize {
152
- unsafe { ( * self . current_task . borrow ( ) . stack ) . bottom ( ) }
172
+ irqsave ( || unsafe { ( * self . current_task . borrow ( ) . stack ) . bottom ( ) } )
153
173
}
154
174
155
175
pub fn get_root_page_table ( & self ) -> usize {
@@ -237,8 +257,6 @@ impl Scheduler {
237
257
}
238
258
239
259
pub fn reschedule ( & mut self ) {
240
- let flags = irq_nested_disable ( ) ;
241
- self . schedule ( ) ;
242
- irq_nested_enable ( flags) ;
260
+ irqsave ( || self . schedule ( ) ) ;
243
261
}
244
262
}
0 commit comments