@@ -39,6 +39,24 @@ static inline void set_thread_status(struct thread_object *obj, enum thread_obje
39
39
obj -> status = status ;
40
40
}
41
41
42
+ void get_schedule_lock (uint16_t pcpu_id )
43
+ {
44
+ struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
45
+ spinlock_obtain (& ctl -> scheduler_lock );
46
+ }
47
+
48
+ void release_schedule_lock (uint16_t pcpu_id )
49
+ {
50
+ struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
51
+ spinlock_release (& ctl -> scheduler_lock );
52
+ }
53
+
54
+ static struct acrn_scheduler * get_scheduler (uint16_t pcpu_id )
55
+ {
56
+ struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
57
+ return ctl -> scheduler ;
58
+ }
59
+
42
60
/**
43
61
* @pre obj != NULL
44
62
*/
@@ -55,37 +73,40 @@ void init_sched(uint16_t pcpu_id)
55
73
ctl -> flags = 0UL ;
56
74
ctl -> curr_obj = NULL ;
57
75
ctl -> pcpu_id = pcpu_id ;
76
+ ctl -> scheduler = & sched_noop ;
77
+ if (ctl -> scheduler -> init != NULL ) {
78
+ ctl -> scheduler -> init (ctl );
79
+ }
58
80
}
59
81
60
- void get_schedule_lock (uint16_t pcpu_id )
82
+ void deinit_sched (uint16_t pcpu_id )
61
83
{
62
84
struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
63
- spinlock_obtain (& ctl -> scheduler_lock );
64
- }
65
85
66
- void release_schedule_lock (uint16_t pcpu_id )
67
- {
68
- struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
69
- spinlock_release (& ctl -> scheduler_lock );
86
+ if (ctl -> scheduler -> deinit != NULL ) {
87
+ ctl -> scheduler -> deinit (ctl );
88
+ }
70
89
}
71
90
72
- void insert_thread_obj (struct thread_object * obj , uint16_t pcpu_id )
91
+ void init_thread_data (struct thread_object * obj )
73
92
{
74
- struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
75
-
76
- ctl -> thread_obj = obj ;
93
+ struct acrn_scheduler * scheduler = get_scheduler (obj -> pcpu_id );
94
+ get_schedule_lock (obj -> pcpu_id );
95
+ if (scheduler -> init_data != NULL ) {
96
+ scheduler -> init_data (obj );
97
+ }
98
+ /* initial as BLOCKED status, so we can wake it up to run */
99
+ set_thread_status (obj , THREAD_STS_BLOCKED );
100
+ release_schedule_lock (obj -> pcpu_id );
77
101
}
78
102
79
- void remove_thread_obj ( __unused struct thread_object * obj , uint16_t pcpu_id )
103
+ void deinit_thread_data ( struct thread_object * obj )
80
104
{
81
- struct sched_control * ctl = & per_cpu ( sched_ctl , pcpu_id );
105
+ struct acrn_scheduler * scheduler = get_scheduler ( obj -> pcpu_id );
82
106
83
- ctl -> thread_obj = NULL ;
84
- }
85
-
86
- static struct thread_object * get_next_sched_obj (const struct sched_control * ctl )
87
- {
88
- return ctl -> thread_obj == NULL ? & get_cpu_var (idle ) : ctl -> thread_obj ;
107
+ if (scheduler -> deinit_data != NULL ) {
108
+ scheduler -> deinit_data (obj );
109
+ }
89
110
}
90
111
91
112
struct thread_object * sched_get_current (uint16_t pcpu_id )
@@ -142,11 +163,13 @@ void schedule(void)
142
163
{
143
164
uint16_t pcpu_id = get_pcpu_id ();
144
165
struct sched_control * ctl = & per_cpu (sched_ctl , pcpu_id );
145
- struct thread_object * next = NULL ;
166
+ struct thread_object * next = & per_cpu ( idle , pcpu_id ) ;
146
167
struct thread_object * prev = ctl -> curr_obj ;
147
168
148
169
get_schedule_lock (pcpu_id );
149
- next = get_next_sched_obj (ctl );
170
+ if (ctl -> scheduler -> pick_next != NULL ) {
171
+ next = ctl -> scheduler -> pick_next (ctl );
172
+ }
150
173
bitmap_clear_lock (NEED_RESCHEDULE , & ctl -> flags );
151
174
152
175
/* Don't change prev object's status if it's not running */
@@ -168,9 +191,12 @@ void schedule(void)
168
191
void sleep_thread (struct thread_object * obj )
169
192
{
170
193
uint16_t pcpu_id = obj -> pcpu_id ;
194
+ struct acrn_scheduler * scheduler = get_scheduler (pcpu_id );
171
195
172
196
get_schedule_lock (pcpu_id );
173
- remove_thread_obj (obj , pcpu_id );
197
+ if (scheduler -> sleep != NULL ) {
198
+ scheduler -> sleep (obj );
199
+ }
174
200
if (is_running (obj )) {
175
201
if (obj -> notify_mode == SCHED_NOTIFY_INIT ) {
176
202
make_reschedule_request (pcpu_id , DEL_MODE_INIT );
@@ -185,10 +211,14 @@ void sleep_thread(struct thread_object *obj)
185
211
void wake_thread (struct thread_object * obj )
186
212
{
187
213
uint16_t pcpu_id = obj -> pcpu_id ;
214
+ struct acrn_scheduler * scheduler ;
188
215
189
216
get_schedule_lock (pcpu_id );
190
217
if (is_blocked (obj )) {
191
- insert_thread_obj (obj , pcpu_id );
218
+ scheduler = get_scheduler (pcpu_id );
219
+ if (scheduler -> wake != NULL ) {
220
+ scheduler -> wake (obj );
221
+ }
192
222
set_thread_status (obj , THREAD_STS_RUNNABLE );
193
223
make_reschedule_request (pcpu_id , DEL_MODE_IPI );
194
224
}
@@ -197,6 +227,7 @@ void wake_thread(struct thread_object *obj)
197
227
198
228
void run_thread (struct thread_object * obj )
199
229
{
230
+ init_thread_data (obj );
200
231
get_schedule_lock (obj -> pcpu_id );
201
232
get_cpu_var (sched_ctl ).curr_obj = obj ;
202
233
set_thread_status (obj , THREAD_STS_RUNNING );
0 commit comments