8000 py/scheduler: Convert micropythyon.schedule() to a circular buffer. · micropython/micropython@8977c7e · GitHub
[go: up one dir, main page]

Skip to content

Commit 8977c7e

Browse files
pi-anldpgeorge
authored andcommitted
py/scheduler: Convert micropythyon.schedule() to a circular buffer.
This means the schedule operates on a first-in, first-executed manner rather than the current last-in, first executed.
1 parent 2befcb8 commit 8977c7e

File tree

5 files changed

+29
-12
lines changed

5 files changed

+29
-12
lines changed

py/mpstate.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ typedef struct _mp_state_vm_t {
209209

210210
#if MICROPY_ENABLE_SCHEDULER
211211
volatile int16_t sched_state;
212-
uint16_t sched_sp;
212+
uint8_t sched_len;
213+
uint8_t sched_idx;
213214
#endif
214215

215216
#if MICROPY_PY_THREAD_GIL

py/runtime.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ void mp_init(void) {
6363
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
6464
#if MICROPY_ENABLE_SCHEDULER
6565
MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
66-
MP_STATE_VM(sched_sp) = 0;
66+
MP_STATE_VM(sched_idx) = 0;
67+
MP_STATE_VM(sched_len) = 0;
6768
#endif
6869

6970
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF

py/runtime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void mp_handle_pending_tail(mp_uint_t atomic_state);
7070
#if MICROPY_ENABLE_SCHEDULER
7171
void mp_sched_lock(void);
7272
void mp_sched_unlock(void);
73-
static inline unsigned int mp_sched_num_pending(void) { return MP_STATE_VM(sched_sp); }
73+
static inline unsigned int mp_sched_num_pending(void) { return MP_STATE_VM(sched_len); }
7474
bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg);
7575
#endif
7676

py/scheduler.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@
3030

3131
#if MICROPY_ENABLE_SCHEDULER
3232

33+
#define IDX_MASK(i) ((i) & (MICROPY_SCHEDULER_DEPTH - 1))
34+
35+
static inline bool mp_sched_full(void) {
36+
MP_STATIC_ASSERT(MICROPY_SCHEDULER_DEPTH <= 255); // MICROPY_SCHEDULER_DEPTH must fit in 8 bits
37+
MP_STATIC_ASSERT((IDX_MASK(MICROPY_SCHEDULER_DEPTH) == 0)); // MICROPY_SCHEDULER_DEPTH must be a power of 2
38+
39+
return mp_sched_num_pending() == MICROPY_SCHEDULER_DEPTH;
40+
}
41+
42+
static inline bool mp_sched_empty(void) {
43+
return mp_sched_num_pending() == 0;
44+
}
45+
3346
// A variant of this is inlined in the VM at the pending exception check
3447
void mp_handle_pending(void) {
3548
if (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) {
@@ -51,8 +64,10 @@ void mp_handle_pending(void) {
5164
// or by the VM's inlined version of that function.
5265
void mp_handle_pending_tail(mp_uint_t atomic_state) {
5366
MP_STATE_VM(sched_state) = MP_SCHED_LOCKED;
54-
if (MP_STATE_VM(sched_sp) > 0) {
55-
mp_sched_item_t item = MP_STATE_VM(sched_stack)[--MP_STATE_VM(sched_sp)];
67+
if (!mp_sched_empty()) {
68+
mp_sched_item_t item = MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_idx)];
69+
MP_STATE_VM(sched_idx) = IDX_MASK(MP_STATE_VM(sched_idx) + 1);
70+
--MP_STATE_VM(sched_len);
5671
MICROPY_END_ATOMIC_SECTION(atomic_state);
5772
mp_call_function_1_protected(item.func, item.arg);
5873
} else {
@@ -87,13 +102,13 @@ void mp_sched_unlock(void) {
87102
bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg) {
88103
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
89104
bool ret;
90-
if (MP_STATE_VM(sched_sp) < MICROPY_SCHEDULER_DEPTH) {
105+
if (!mp_sched_full()) {
91106
if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) {
92107
MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
93108
}
94-
MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_sp)].func = function;
95-
MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_sp)].arg = arg;
96-
++MP_STATE_VM(sched_sp);
109+
uint8_t iput = IDX_MASK(MP_STATE_VM(sched_idx) + MP_STATE_VM(sched_len)++);
110+
MP_STATE_VM(sched_stack)[iput].func = function;
111+
MP_STATE_VM(sched_stack)[iput].arg = arg;
97112
ret = true;
98113
} else {
99114
// schedule stack is full

tests/unix/extra_coverage.py.exp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ sched(2)=1
7070
sched(3)=1
7171
sched(4)=0
7272
unlocked
73-
3
74-
2
75-
1
7673
0
74+
1
75+
2
76+
3
7777
0123456789 b'0123456789'
7878
7300
7979
7300

0 commit comments

Comments
 (0)
0