kernel: Scheduler rewrite

This replaces the existing scheduler (but not priority handling)
implementation with a somewhat simpler one.  Behavior as to thread
selection does not change.  New features:

+ Unifies SMP and uniprocessing selection code (with the sole
  exception of the "cache" trick not being possible in SMP).

+ The old static multi-queue implementation is gone and has been
  replaced with a build-time choice of either a "dumb" list
  implementation (faster and significantly smaller for apps with only
  a few threads) or a balanced tree queue which scales well to
  arbitrary numbers of threads and priority levels.  This is
  controlled via the CONFIG_SCHED_DUMB kconfig variable.

+ The balanced tree implementation is usable symmetrically for the
  wait_q abstraction, fixing a scalability glitch Zephyr had when many
  threads were waiting on a single object.  This can be selected via
  CONFIG_WAITQ_FAST.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2018-05-03 14:51:49 -07:00 committed by Anas Nashif
commit 1acd8c2996
10 changed files with 600 additions and 484 deletions

View file

@ -12,6 +12,7 @@
#if !defined(_ASMLANGUAGE)
#include <atomic.h>
#include <misc/dlist.h>
#include <misc/rb.h>
#include <string.h>
#endif
@ -27,7 +28,6 @@
* defined.
*/
/* states: common uses low bits, arch-specific use high bits */
/* Not a real thread */
@ -48,6 +48,9 @@
/* Thread is actively looking at events to see if they are ready */
#define _THREAD_POLLING (1 << 5)
/* Thread is present in the ready queue */
#define _THREAD_QUEUED (1 << 6)
/* end - states */
#ifdef CONFIG_STACK_SENTINEL
@ -69,13 +72,13 @@ struct _ready_q {
#ifndef CONFIG_SMP
/* always contains next thread to run: cannot be NULL */
struct k_thread *cache;
/* bitmap of priorities that contain at least one ready thread */
u32_t prio_bmap[K_NUM_PRIO_BITMAPS];
#endif
/* ready queues, one per priority */
sys_dlist_t q[K_NUM_PRIORITIES];
#ifdef CONFIG_SCHED_DUMB
sys_dlist_t runq;
#else
struct _priq_rb runq;
#endif
};
typedef struct _ready_q _ready_q_t;
@ -90,6 +93,9 @@ struct _cpu {
/* currently scheduled thread */
struct k_thread *current;
/* one assigned idle thread per CPU */
struct k_thread *idle_thread;
int id;
};
@ -158,8 +164,10 @@ typedef struct _kernel _kernel_t;
extern struct _kernel _kernel;
#ifdef CONFIG_SMP
#define _current_cpu (_arch_curr_cpu())
#define _current (_arch_curr_cpu()->current)
#else
#define _current_cpu (&_kernel.cpus[0])
#define _current _kernel.current
#endif