Skip to content
Snippets Groups Projects
Commit 830ce74f authored by Paul Sokolovsky's avatar Paul Sokolovsky
Browse files

extmod/modutimeq: Make scheduling fair (round-robin).

By adding back monotonically increasing field in addition to time field.
As heapsort is not stable, without this, among entried added and readded
at the same time instant, some might be always selected, and some might
never be selected, leading to scheduling starvation.
parent bdd48e67
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2014 Damien P. George * Copyright (c) 2014 Damien P. George
* Copyright (c) 2016 Paul Sokolovsky * Copyright (c) 2016-2017 Paul Sokolovsky
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
struct qentry { struct qentry {
mp_uint_t time; mp_uint_t time;
mp_uint_t id;
mp_obj_t callback; mp_obj_t callback;
mp_obj_t args; mp_obj_t args;
}; };
...@@ -54,6 +55,7 @@ typedef struct _mp_obj_utimeq_t { ...@@ -54,6 +55,7 @@ typedef struct _mp_obj_utimeq_t {
struct qentry items[]; struct qentry items[];
} mp_obj_utimeq_t; } mp_obj_utimeq_t;
STATIC mp_uint_t utimeq_id;
STATIC mp_obj_utimeq_t *get_heap(mp_obj_t heap_in) { STATIC mp_obj_utimeq_t *get_heap(mp_obj_t heap_in) {
return MP_OBJ_TO_PTR(heap_in); return MP_OBJ_TO_PTR(heap_in);
...@@ -63,6 +65,11 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) { ...@@ -63,6 +65,11 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) {
mp_uint_t item_tm = item->time; mp_uint_t item_tm = item->time;
mp_uint_t parent_tm = parent->time; mp_uint_t parent_tm = parent->time;
mp_uint_t res = parent_tm - item_tm; mp_uint_t res = parent_tm - item_tm;
if (res == 0) {
// TODO: This actually should use the same "ring" logic
// as for time, to avoid artifacts when id's overflow.
return item->id < parent->id;
}
if ((mp_int_t)res < 0) { if ((mp_int_t)res < 0) {
res += MODULO; res += MODULO;
} }
...@@ -125,6 +132,7 @@ STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) { ...@@ -125,6 +132,7 @@ STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
} }
mp_uint_t l = heap->len; mp_uint_t l = heap->len;
heap->items[l].time = MP_OBJ_SMALL_INT_VALUE(args[1]); heap->items[l].time = MP_OBJ_SMALL_INT_VALUE(args[1]);
heap->items[l].id = utimeq_id++;
heap->items[l].callback = args[2]; heap->items[l].callback = args[2];
heap->items[l].args = args[3]; heap->items[l].args = args[3];
heap_siftdown(heap, 0, heap->len); heap_siftdown(heap, 0, heap->len);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment