diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index c0419e77c..290aea40b 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -16,7 +16,6 @@ set( "data/readylist/readylist.ref.c" "data/intconfig/intconfig.ref.c" "data/stacks/stacks.ref.S" - "data/runlist/runlist.ref.c" "data/globals/globals.ref.c" "data/context/context.v${ARCHV}opt.S" "data/vm/vm.ref.c" diff --git a/kernel/bugs b/kernel/bugs index 742485038..ca7b3a401 100644 --- a/kernel/bugs +++ b/kernel/bugs @@ -37,17 +37,3 @@ Other specing / assertions * For every data element in a struct, spec where it should be updated * Add collection of assertions that we can check on function entry/exit * Add structure verifier that can make sure structures are sane - - - -runlist valid states -==================== - -An empty runlist is apparently not a valid state; should probably -document this in the spec and maybe make an assertion. - - - - - - diff --git a/kernel/build/offsets/offsets.ref.c b/kernel/build/offsets/offsets.ref.c index 4c4864c6a..ad1f9336f 100644 --- a/kernel/build/offsets/offsets.ref.c +++ b/kernel/build/offsets/offsets.ref.c @@ -119,7 +119,7 @@ int main(int argc, char **argv) PRINT_KG_OFFSET(hthreads_mask); PRINT_KG_OFFSET(hthreads); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED PRINT_KG_OFFSET(cluster_clusters); PRINT_KG_OFFSET(cluster_hthreads); PRINT_KG_OFFSET(cluster_mask); diff --git a/kernel/checkers/checker_runlist/checker_runlist.check.c b/kernel/checkers/checker_runlist/checker_runlist.check.c deleted file mode 100644 index d34cea562..000000000 --- a/kernel/checkers/checker_runlist/checker_runlist.check.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include -#include -#include -#include -#include -#include - -s32_t checker_runlist() -{ - u32_t i; - for (i = 0; i < H2K_gp->hthreads; i++) { - if (0 <= H2K_gp->runlist_prios[i] && H2K_gp->runlist_prios[i] <= MAX_PRIO) { - if (H2K_gp->runlist_prios[i] != H2K_gp->runlist[i]->prio) FAIL("runlist_prios does not match priority of scheduled thread"); - } else { - if (H2K_gp->runlist[i]) FAIL("Priority out of range but readylist non-null"); - } - } - return 1; -} - diff --git a/kernel/checkers/checker_runlist/checker_runlist.h b/kernel/checkers/checker_runlist/checker_runlist.h deleted file mode 100644 index 7b08593f0..000000000 --- a/kernel/checkers/checker_runlist/checker_runlist.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#ifndef H2K_CHECKER_RUNLIST_H -#define H2K_CHECKER_RUNLIST_H 1 - -#include - -s32_t checker_runlist(); - -#endif - diff --git a/kernel/checkers/checker_runlist/make.inc b/kernel/checkers/checker_runlist/make.inc deleted file mode 100644 index d00f59119..000000000 --- a/kernel/checkers/checker_runlist/make.inc +++ /dev/null @@ -1 +0,0 @@ -include $(MAKE_INC_DEFAULT) diff --git a/kernel/data/globals/globals.h b/kernel/data/globals/globals.h index c034daf3b..df3b20b2c 100644 --- a/kernel/data/globals/globals.h +++ b/kernel/data/globals/globals.h @@ -97,7 +97,7 @@ typedef struct { pa_t gpio_reg; #endif -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED u32_t cluster_clusters; // number of clusters u32_t cluster_hthreads; // hardware threads per cluster u32_t cluster_mask[4]; // bitmask of threads in cluster @@ -216,7 +216,7 @@ static inline H2K_kg_t PURITY *H2K_gp_llvm() #undef PURITY #endif -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED static inline u32_t H2K_hthread_cluster(u32_t hthread) { return (hthread / H2K_gp->cluster_hthreads); diff --git a/kernel/data/globals/globals.ref.c b/kernel/data/globals/globals.ref.c index aec8c54c6..a6d9cc49d 100644 --- a/kernel/data/globals/globals.ref.c +++ b/kernel/data/globals/globals.ref.c @@ -69,7 +69,7 @@ void H2K_kg_init(u32_t phys_offset, u32_t multicore_shift, u32_t devpage_offset, have_hvx = (H2K_cfg_table(CFG_TABLE_COPROC_TYPE) & CFG_TABLE_COPROC_TYPE_HVX_MASK) != 0; have_silver = (H2K_cfg_table(CFG_TABLE_COPROC_TYPE) & CFG_TABLE_COPROC_TYPE_SILVER_MASK) != 0; H2K_kg.coproc_contexts = (have_hvx || have_silver ? H2K_cfg_table(CFG_TABLE_COPROC_CONTEXTS) : 0); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED /* FIXME: need a cfg_table entry for this */ H2K_kg.cluster_clusters = (u32_t)(Q6_R_popcount_P(H2K_cfg_table(CFG_TABLE_HTHREADS_MASK)) > 8 ? 4 : 2); // hack H2K_kg.cluster_hthreads = (u32_t)(Q6_R_popcount_P(H2K_cfg_table(CFG_TABLE_HTHREADS_MASK)) / H2K_kg.cluster_clusters); @@ -144,7 +144,7 @@ void H2K_kg_init(u32_t phys_offset, u32_t multicore_shift, u32_t devpage_offset, H2K_kg.hmx_units = (H2K_cfg_table(CFG_TABLE_HMX_INT8_RATE) != 0); // exists? H2K_kg.info_boot_flags.boot_have_hmx = (H2K_kg.hmx_units > 0); #endif -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED H2K_kg.coproc_max_save = ((H2K_kg.coproc_contexts + H2K_kg.hmx_units) / H2K_kg.cluster_clusters) + (((H2K_kg.coproc_contexts + H2K_kg.hmx_units) % H2K_kg.cluster_clusters) != 0); H2K_kg.coproc_max_save = (H2K_kg.coproc_max < CLUSTER_SCHED_MIN_COPROCS ? CLUSTER_SCHED_MIN_COPROCS : H2K_kg.coproc_max); #endif @@ -230,7 +230,7 @@ void H2K_kg_init(u32_t phys_offset, u32_t multicore_shift, u32_t devpage_offset, } -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED void H2K_cluster_config(void) { u32_t i; diff --git a/kernel/data/readylist/readylist.h b/kernel/data/readylist/readylist.h index 5b6d8ca37..334c714bb 100644 --- a/kernel/data/readylist/readylist.h +++ b/kernel/data/readylist/readylist.h @@ -13,7 +13,6 @@ #include #include #include -#include /* Get the best ready priority */ static inline u32_t H2K_ready_best_prio() @@ -86,7 +85,29 @@ static inline void H2K_ready_remove(H2K_thread_context *thread) if (H2K_gp->ready[prio] == NULL) H2K_ready_clear_prio(prio); } -#ifdef CLUSTER_SCHED +static inline void H2K_ready_append_arm(H2K_thread_context *thread) +{ + H2K_ready_append(thread); + H2K_set_bestwait(H2K_ready_best_prio()); +} + +/* Take the thread and place it in the ready structure, + * the first thread to be scheduled at its priority */ +static inline void H2K_ready_insert_arm(H2K_thread_context *thread) +{ + H2K_ready_insert(thread); + H2K_set_bestwait(H2K_ready_best_prio()); +} + +/* Remove a specific thread from the ready list */ +/* The caller guarantees that the thread is actually in the ready list correctly */ +static inline void H2K_ready_remove_arm(H2K_thread_context *thread) +{ + H2K_ready_remove(thread); + H2K_set_bestwait(H2K_ready_best_prio()); +} + +#if CLUSTER_SCHED static inline void H2K_update_coprocs(u32_t hthread, u32_t hthread_xe, u32_t hthread_xe2, u32_t hthread_xe3,u32_t head_xe, u32_t head_xe2, u32_t head_xe3) { xex(hthread, head_xe, head_xe2, head_xe3, hthread_xe, hthread_xe2, hthread_xe3); if (hthread_xe) { @@ -123,7 +144,7 @@ static inline void H2K_update_coprocs(u32_t hthread, u32_t hthread_xe, u32_t hth static inline H2K_thread_context *H2K_ready_head(u32_t prio, u32_t hthread) { H2K_thread_context *head = H2K_gp->ready[prio]; -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED if ((!H2K_gp->cluster_sched) || H2K_gp->coproc_max == -1) { return head; } @@ -223,7 +244,7 @@ static inline H2K_thread_context *H2K_ready_getbest(u32_t hthread) H2K_log("hthread %d getbest\n", hthread); prio = H2K_ready_best_prio(); if (prio >= MAX_PRIOS) { // !H2K_ready_any_valid(), go to sleep -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED if (!H2K_gp->cluster_sched) { return NULL; } @@ -246,7 +267,7 @@ static inline H2K_thread_context *H2K_ready_getbest(u32_t hthread) ret = H2K_ready_head(prio, hthread); if (ret != NULL) { - H2K_ready_remove(ret); + H2K_ready_remove_arm(ret); } return ret; } diff --git a/kernel/data/readylist/readylist.spec b/kernel/data/readylist/readylist.spec index 937f46872..8bbac86db 100644 --- a/kernel/data/readylist/readylist.spec +++ b/kernel/data/readylist/readylist.spec @@ -4,6 +4,26 @@ .. module:: readylist +Overview +-------- + +The readylist API is split into two groups: + +* **Base functions** (:c:func:`H2K_ready_append`, :c:func:`H2K_ready_insert`, + :c:func:`H2K_ready_remove`) — manipulate the ready list without touching the + hardware BESTWAIT comparator. Used at mid-reschedule sites where a following + :c:func:`H2K_dosched()` call on the same HW thread will re-arm BESTWAIT. + +* **Arming variants** (:c:func:`H2K_ready_append_arm`, :c:func:`H2K_ready_insert_arm`, + :c:func:`H2K_ready_remove_arm`) — manipulate the ready list AND arm the hardware + BESTWAIT comparator with the new best ready priority. Used at wake/sleep-transition + sites where the thread is switched to immediately, or at :c:func:`H2K_ready_getbest()` + to ensure BESTWAIT is always re-armed after removing the best thread. + +The BESTWAIT comparator is a hardware mechanism that raises a reschedule interrupt +whenever any HW thread's STID.PRIO is strictly worse (higher number) than the armed +BESTWAIT value. + H2K_kg.ready and H2K_kg.ready_valids ------------------------------------ @@ -200,6 +220,81 @@ more elements in the ring, we call :c:func:`H2K_ready_clear_prio()` with the thread's priority. +H2K_ready_append_arm +-------------------- + +.. c:function:: static inline void H2K_ready_append_arm(H2K_thread_context *thread) + + :param thread: the thread to add + +Description +~~~~~~~~~~~ + +Appends the thread to the ready list and arms the hardware BESTWAIT comparator. + +Functionality +~~~~~~~~~~~~~ + +Calls :c:func:`H2K_ready_append()` to add the thread to the ready list, then +calls :c:func:`H2K_set_bestwait()` with the result of :c:func:`H2K_ready_best_prio()` +to arm the hardware reschedule-interrupt comparator with the best ready priority. + +Used at wake/sleep-transition sites where a thread is being placed on the ready +list and will be switched to immediately or returned without a following :c:func:`H2K_dosched()` +call on the same HW thread. The BESTWAIT arm ensures the hardware comparator is active to +trigger a reschedule interrupt if a running thread's priority becomes worse than +the newly-ready thread's priority. + + +H2K_ready_insert_arm +-------------------- + +.. c:function:: static inline void H2K_ready_insert_arm(H2K_thread_context *thread) + + :param thread: the thread to add + +Description +~~~~~~~~~~~ + +Inserts the thread to the ready list and arms the hardware BESTWAIT comparator. + +Functionality +~~~~~~~~~~~~~ + +Calls :c:func:`H2K_ready_insert()` to add the thread to the ready list, then +calls :c:func:`H2K_set_bestwait()` with the result of :c:func:`H2K_ready_best_prio()` +to arm the hardware reschedule-interrupt comparator with the best ready priority. + +Used at wake/sleep-transition sites where a thread is being inserted at the head +of the ready list (higher priority within the same priority level) and will be +switched to immediately without a following :c:func:`H2K_dosched()` call. + + +H2K_ready_remove_arm +-------------------- + +.. c:function:: static inline void H2K_ready_remove_arm(H2K_thread_context *thread) + + :param thread: the thread to remove + +Description +~~~~~~~~~~~ + +Removes the thread from the ready list and arms the hardware BESTWAIT comparator. + +Functionality +~~~~~~~~~~~~~ + +Calls :c:func:`H2K_ready_remove()` to remove the thread from the ready list, then +calls :c:func:`H2K_set_bestwait()` with the result of :c:func:`H2K_ready_best_prio()` +to arm the hardware reschedule-interrupt comparator with the best ready priority. + +Used in :c:func:`H2K_ready_getbest()` to ensure BESTWAIT is always re-armed after +removing the best thread from the ready list. Also used in :c:func:`H2K_resched()` +to immediately close the disarmed window after a hardware reschedule interrupt +fires (which resets BESTWAIT to 0x1FF). + + H2K_ready_getbest ----------------- @@ -211,7 +306,7 @@ H2K_ready_getbest Description ~~~~~~~~~~~ -Removes the best priority thread from the ready list. +Removes the best priority thread from the ready list and re-arms BESTWAIT. Functionality ~~~~~~~~~~~~~ @@ -222,7 +317,9 @@ We call :c:func:`H2K_ready_best_prio()` to obtain the priority of the best prior We then get the thread pointed to by the H2K_kg.ready pointer at the correct priority. -This thread is removed from the ready list by calling :c:func:`H2K_ready_remove()`, and returned. +This thread is removed from the ready list by calling :c:func:`H2K_ready_remove_arm()`, +which also re-arms BESTWAIT with the new best priority (or 0x1FF if no threads remain), +and the thread is returned. @@ -232,6 +329,9 @@ This thread is removed from the ready list by calling :c:func:`H2K_ready_remove( Testing ------- +Base Functions (H2K_ready_append, H2K_ready_insert, H2K_ready_remove, H2K_ready_getbest) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Samples ~~~~~~~ @@ -264,6 +364,12 @@ Harness ~~~~~~~ The readylist module is reasonably self-contained, so the test harness will only -use the header file and object file. +use the header file and object file. + +BESTWAIT Arming Functions (H2K_ready_append_arm, H2K_ready_insert_arm, H2K_ready_remove_arm) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The `_arm` variants are tested separately in the H2K_bestwait test suite +(``kernel/data/readylist/tests/H2K_bestwait/test.c``), which validates the +hardware BESTWAIT/SCHEDCFG comparator behavior and the arming discipline. diff --git a/kernel/data/readylist/tests/H2K_bestwait/Makefile b/kernel/data/readylist/tests/H2K_bestwait/Makefile new file mode 100644 index 000000000..71b74048c --- /dev/null +++ b/kernel/data/readylist/tests/H2K_bestwait/Makefile @@ -0,0 +1,7 @@ +STANDALONE=1 + +OBJS+=test.o +EXEC=test.elf + +include Makefile.inc +OSLIB= diff --git a/kernel/sched/lowprio/test/Makefile.inc b/kernel/data/readylist/tests/H2K_bestwait/Makefile.inc similarity index 80% rename from kernel/sched/lowprio/test/Makefile.inc rename to kernel/data/readylist/tests/H2K_bestwait/Makefile.inc index d3a8c046c..81cc0e9a7 100644 --- a/kernel/sched/lowprio/test/Makefile.inc +++ b/kernel/data/readylist/tests/H2K_bestwait/Makefile.inc @@ -1,7 +1,5 @@ # Need to define how to get back to the main H2 dir -H2DIR=${UPDIR}../../../.. +H2DIR=${UPDIR}../../../../../.. # Everything else defined here include ${H2DIR}/scripts/Makefile.inc.test - - diff --git a/kernel/data/readylist/tests/H2K_bestwait/test.c b/kernel/data/readylist/tests/H2K_bestwait/test.c new file mode 100644 index 000000000..befe4ca65 --- /dev/null +++ b/kernel/data/readylist/tests/H2K_bestwait/test.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +/* + * bestwait_sim_check + * ================== + * + * How it works: + * - BESTWAIT holds the priority of the best task waiting to run. + * - When the effective priority of ANY hardware thread (STID.PRIO) is worse + * than BESTWAIT, the hardware raises the reschedule interrupt (the interrupt + * number programmed into SCHEDCFG.INTNO) and resets BESTWAIT to 0x1FF. + * - IPEND reflects pending interrupts; "the hardware automatically sets bits + * in this register when an interrupt is received or delivered." + * + * This test arranges the exact trigger condition and checks: + * PART A: the BESTWAIT and SCHEDCFG registers can be read/written (storage). + * PART B: negative case - it does NOT fire when no thread is worse. + * PART C: equal priorities - it does NOT fire when STID.PRIO equals BESTWAIT. + * PART D: it does NOT fire when SCHEDCFG.EN=0 (the feature must be enabled, + * which the boot path H2K_init_setup normally does). + * PART E: hardware steering delivers RESCHED to a qualified thread whose + * RESCHED imask bit is clear (the boot/hw-steering model). This verifies + * that BESTWAIT fires again and is not stale by re-arming it and checking + * that the interrupt is posted again with IAD=0 and IPEND raising the + * RESCHED_INT_MASK bit. + * + * Interrupts are kept globally disabled (clear_gie) so that, if the interrupt + * is posted, it stays pending in IPEND for us to observe rather than being taken. + */ + +#include +#include +#include +#include +#include + +static int failures; + +static void check(const char *what, int ok) +{ + printf(" [%s] %s\n", ok ? "PASS" : "FAIL", what); + if (!ok) + failures++; +} + +int main() +{ + u32_t bw, sc, ipend, iad, best_ready; + u32_t hthread = get_hwtnum(); + + /* Keep interrupts globally disabled so a posted RESCHED_INT remains pending + * in IPEND (taken interrupts auto-clear their IPEND bit; see spec 6.1). */ + H2K_clear_gie(); + H2K_clear_ipend(0xffffffff); + + puts("PART A: BESTWAIT / SCHEDCFG behave as readable/writable registers"); + u32_t garbage_value = 0x123; + H2K_set_bestwait(garbage_value); + bw = H2K_get_bestwait(); + iad = H2K_get_iad(); + ipend = H2K_get_ipend(); + + printf(" BESTWAIT: wrote 0x%x, read 0x%x\n", garbage_value, bw); + printf(" IPEND=0x%x (RESCHED bit %d), IAD=0x%x, BESTWAIT now 0x%x\n", + ipend, (ipend & RESCHED_INT_INTMASK) ? 1 : 0, iad, bw); + check("BESTWAIT round-trips", bw == garbage_value); + check("IAD is 0", iad == 0); + + H2K_set_bestwait(BESTWAIT_MASK); + + sc = SCHEDCFG_EN | SCHEDCFG_INTNO(RESCHED_INT); + H2K_set_schedcfg(sc); + printf(" SCHEDCFG: wrote 0x%x, read 0x%x\n", sc, H2K_get_schedcfg()); + check("SCHEDCFG round-trips", H2K_get_schedcfg() == sc); + + puts("PART B: negative case - comparator must NOT fire when no thread is " + "worse than BESTWAIT"); + + /* Make this thread a GOOD priority (10) and arm BESTWAIT WORSE (50). + * 10 (us) is better than 50 (bestwait) -> nothing is worse -> no fire. */ + H2K_clear_ipend(0xffffffff); + set_thread_stid_prio(hthread, 10); + best_ready = 50; + H2K_set_bestwait(best_ready); + ipend = H2K_get_ipend(); + iad = H2K_get_iad(); + bw = H2K_get_bestwait(); + printf(" state: STID.PRIO=10, BESTWAIT=0x%x\n", best_ready); + printf(" IPEND=0x%x (RESCHED bit %d), IAD=0x%x, BESTWAIT now 0x%x\n", + ipend, (ipend & RESCHED_INT_INTMASK) ? 1 : 0, iad, bw); + check("comparator did NOT post RESCHED_INT (no thread worse)", + (ipend & RESCHED_INT_INTMASK) == 0); + check("IAD is 0", iad == 0); + check("BESTWAIT retained its value (not auto-reset)", bw == best_ready); + + puts("PART C: equal priorities - comparator must NOT fire when STID.PRIO equals BESTWAIT"); + + /* Make this thread priority equal to BESTWAIT (50). + * 50 (us) is NOT worse than 50 (bestwait) -> no fire. */ + H2K_clear_ipend(0xffffffff); + set_thread_stid_prio(hthread, 50); + best_ready = 50; + H2K_set_bestwait(best_ready); + ipend = H2K_get_ipend(); + iad = H2K_get_iad(); + bw = H2K_get_bestwait(); + printf(" state: STID.PRIO=50, BESTWAIT=0x%x (equal priorities)\n", best_ready); + printf(" IPEND=0x%x (RESCHED bit %d), IAD=0x%x, BESTWAIT now 0x%x\n", + ipend, (ipend & RESCHED_INT_INTMASK) ? 1 : 0, iad, bw); + check("comparator did NOT fire when priorities are equal", + (ipend & RESCHED_INT_INTMASK) == 0); + check("IAD is 0", iad == 0); + check("BESTWAIT retained its value when equal", bw == best_ready); + + puts("PART D: does the feature require SCHEDCFG.EN? (mimics the scenario " + "unit test, which never calls H2K_init_setup and so never enables it)"); + + /* Clear only the EN bit (keep INTNO) to confirm EN specifically gates + * the feature -- not just any SCHEDCFG write. */ + sc = ~SCHEDCFG_EN | SCHEDCFG_INTNO(RESCHED_INT); + H2K_set_schedcfg(sc); + printf(" SCHEDCFG: wrote 0x%x, read 0x%x\n", sc, H2K_get_schedcfg()); + asm volatile ("isync"); + H2K_clear_ipend(0xffffffff); + set_thread_stid_prio(hthread, 200); + best_ready = 50; + H2K_set_bestwait(best_ready); + ipend = H2K_get_ipend(); + iad = H2K_get_iad(); + bw = H2K_get_bestwait(); + printf(" SCHEDCFG=~EN|INTNO (EN=0, INTNO kept), STID.PRIO=200, BESTWAIT=50\n"); + printf(" IPEND=0x%x (RESCHED bit %d), IAD=0x%x, BESTWAIT now 0x%x\n", + ipend, (ipend & RESCHED_INT_INTMASK) ? 1 : 0, iad, bw); + printf(" OBSERVATION: with EN=0, comparator fires=%d " + "(if 0, SCHEDCFG.EN is REQUIRED)\n", + (ipend & RESCHED_INT_INTMASK) ? 1 : 0); + check("comparator does NOT fire when SCHEDCFG.EN=0", + (ipend & RESCHED_INT_INTMASK) == 0); + check("IAD is 0", iad == 0); + check("Bestwait retains its value (not auto-reset) when EN=0", bw == best_ready); + + puts("PART E: hardware steering delivers RESCHED to a qualified thread whose " + "RESCHED imask bit is clear (the boot/hw-steering model)"); + + /* Model the hw-steering setup: feature enabled, this thread's RESCHED imask + * bit cleared via iassignw (every thread qualified), STID.PRIO made worse + * than BESTWAIT. The hardware should steer RESCHED_INT to this thread and + * post it in IPEND. Re-enable interrupts briefly is NOT done here (we keep + * GIE off so the posted bit stays observable in IPEND). */ + sc = SCHEDCFG_EN | SCHEDCFG_INTNO(RESCHED_INT); + H2K_set_schedcfg(sc); + printf(" SCHEDCFG: wrote 0x%x, read 0x%x\n", sc, H2K_get_schedcfg()); + asm volatile ("isync"); + iassignw(RESCHED_INT, 0); /* clear RESCHED imask bit on all threads */ + H2K_clear_ipend(0xffffffff); + set_thread_stid_prio(hthread, 200); + best_ready = 50; + H2K_set_bestwait(best_ready); + ipend = H2K_get_ipend(); + iad = H2K_get_iad(); + bw = H2K_get_bestwait(); + printf(" IPEND=0x%x (RESCHED bit %d), IAD=0x%x, BESTWAIT now 0x%x\n", + ipend, (ipend & RESCHED_INT_INTMASK) ? 1 : 0, iad, bw); + check("RESCHED steered to this qualified thread", + (ipend & RESCHED_INT_INTMASK) != 0); + check("IAD is 0", iad == 0); + check("Bestwait retains its value (not auto-reset)", bw == BESTWAIT_MASK); + + /* Re-arm BESTWAIT to verify it fires again (not stale) */ + H2K_clear_ipend(0xffffffff); + set_thread_stid_prio(hthread, 200); + best_ready = 50; + H2K_set_bestwait(best_ready); + ipend = H2K_get_ipend(); + iad = H2K_get_iad(); + bw = H2K_get_bestwait(); + printf(" IPEND=0x%x (RESCHED bit %d), IAD=0x%x, BESTWAIT now 0x%x\n", + ipend, (ipend & RESCHED_INT_INTMASK) ? 1 : 0, iad, bw); + check("BESTWAIT fires again (not stale)", (ipend & RESCHED_INT_INTMASK) != 0); + check("IAD is 0", iad == 0); + + + + if (failures == 0) { + puts("TEST PASSED"); + return 0; + } + + /* If PART B fails, the demonstration is that the sim is storage-only. */ + puts("TEST FAILED"); + return 1; +} diff --git a/kernel/data/readylist/tests/Makefile b/kernel/data/readylist/tests/Makefile new file mode 100644 index 000000000..28e4bbadf --- /dev/null +++ b/kernel/data/readylist/tests/Makefile @@ -0,0 +1,5 @@ + +SUBDIRS+=H2K_bestwait +SUBDIRS+=readylist + +include Makefile.inc diff --git a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/Makefile.inc b/kernel/data/readylist/tests/Makefile.inc similarity index 100% rename from kernel/sched/check_sanity/test/tests/H2K_check_sanity/Makefile.inc rename to kernel/data/readylist/tests/Makefile.inc diff --git a/kernel/data/readylist/test/Makefile b/kernel/data/readylist/tests/readylist/Makefile similarity index 100% rename from kernel/data/readylist/test/Makefile rename to kernel/data/readylist/tests/readylist/Makefile diff --git a/kernel/data/readylist/test/Makefile.inc b/kernel/data/readylist/tests/readylist/Makefile.inc similarity index 100% rename from kernel/data/readylist/test/Makefile.inc rename to kernel/data/readylist/tests/readylist/Makefile.inc diff --git a/kernel/data/readylist/test/test.c b/kernel/data/readylist/tests/readylist/test.c similarity index 99% rename from kernel/data/readylist/test/test.c rename to kernel/data/readylist/tests/readylist/test.c index 4a2945fc0..9c4e34284 100644 --- a/kernel/data/readylist/test/test.c +++ b/kernel/data/readylist/tests/readylist/test.c @@ -90,7 +90,7 @@ H2K_thread_context *H2K_ready_getbest_TB() return H2K_ready_getbest(CURRENT_HTHREAD); } -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED void H2K_ready_REG_SSR_XE_CLEAR_TB() { H2K_set_ssr(H2K_get_ssr() & ~SSR_XE_BIT_MASK); @@ -230,7 +230,7 @@ __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); if (H2K_ready_getbest_TB() != &c) FAIL("ready_best_prio failed (c) "); if (H2K_ready_getbest_TB() != NULL) FAIL("ready_best_prio failed (empty) "); -# ifdef CLUSTER_SCHED +# if CLUSTER_SCHED u32_t hthreadmask = H2K_cfg_table(CFG_TABLE_HTHREADS_MASK); u32_t hthreads = (u32_t)Q6_R_popcount_P(hthreadmask); diff --git a/kernel/data/runlist/make.inc b/kernel/data/runlist/make.inc deleted file mode 100644 index d00f59119..000000000 --- a/kernel/data/runlist/make.inc +++ /dev/null @@ -1 +0,0 @@ -include $(MAKE_INC_DEFAULT) diff --git a/kernel/data/runlist/runlist.h b/kernel/data/runlist/runlist.h deleted file mode 100644 index 8725971c8..000000000 --- a/kernel/data/runlist/runlist.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#ifndef RUNLIST_H -#define RUNLIST_H 1 - -#include -#include -#include -#include -#include - -static inline void H2K_runlist_push(H2K_thread_context *newthread) -{ - u32_t hthread = newthread->hthread; - u32_t prio = newthread->prio; - newthread->status = H2K_STATUS_RUNNING; - H2K_gp->runlist[hthread] = newthread; - H2K_gp->runlist_prios[hthread] = (s16_t)prio; -} - -static inline u32_t H2K_runlist_worst_prio() -{ - s32_t worst_prio = -1; - s32_t hthread = -1; - s32_t i; - for (i = 0; i < H2K_gp->hthreads; i++) { - if (H2K_gp->runlist_prios[i] IS_WORSE_THAN worst_prio) { - worst_prio = H2K_gp->runlist_prios[i]; - hthread = i; - } - } - return hthread == -1 ? MAX_PRIOS : (u32_t)worst_prio; -} - -static inline u32_t H2K_runlist_worst_prio_hthread() -{ - s32_t worst_prio = -1; - s32_t hthread = -1; - s32_t i; - for (i = 0; i < H2K_gp->hthreads; i++) { - if (H2K_gp->runlist_prios[i] IS_WORSE_THAN worst_prio) { - worst_prio = H2K_gp->runlist_prios[i]; - hthread = i; - } - } - return (u32_t)hthread; -} - -static inline void H2K_runlist_remove(H2K_thread_context *thread) -{ - u32_t hthread = thread->hthread; - H2K_gp->runlist[hthread] = NULL; - H2K_gp->runlist_prios[hthread] = -1; -} - -static inline void H2K_runlist_set_thread_prio(H2K_thread_context *thread, u32_t new_prio) -{ - thread->prio = (u8_t)new_prio; - H2K_gp->runlist_prios[thread->hthread] = (s16_t)new_prio; -} - -void H2K_runlist_init(void) IN_SECTION(".text.init.runlist"); - -#endif - diff --git a/kernel/data/runlist/runlist.ref.c b/kernel/data/runlist/runlist.ref.c deleted file mode 100644 index d402d3fd5..000000000 --- a/kernel/data/runlist/runlist.ref.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include - -void H2K_runlist_init(void) -{ - u32_t i; - for (i = 0; i < sizeof(H2K_gp->runlist_prios)/sizeof(H2K_gp->runlist_prios[0]); i++) { -#ifdef TESTING - if (i < H2K_gp->hthreads) { - H2K_gp->runlist[i] = NULL; - } -#endif - H2K_gp->runlist_prios[i] = -1; - } -} diff --git a/kernel/data/runlist/runlist.spec b/kernel/data/runlist/runlist.spec deleted file mode 100644 index b89f6444a..000000000 --- a/kernel/data/runlist/runlist.spec +++ /dev/null @@ -1,168 +0,0 @@ - -:mod:`runlist` -- managing the currently-running threads -======================================================== - -.. module:: runlist - -runlist and runlist_prios --------------------------- - -The ready list contains the threads that are currently running - -The requirements for the run list are: - -* O(1) insertions of any priority -* O(1) removals of the lowest priority -* Very fast detection of the lowest priority running thread - -We acheive this by using an array of linked lists of threads running at a given -priority, and a bitmask that has a bit set for each non-empty linked list. - -We insert a thread into the run list by adding the thread to the list at the -priority corresponding to the thread, and setting the corresponding bit. - -We find the lowest priority running thread by using the CL0 instruction to find -the lowest priority that has a running thread. We then can remove the thread in -the corresponding list. - -TBD: This datastructure is scalable to any number of hardware threads. It may -be preferable to have an array of the currently running thread on each hardware -thread, and find the minimum by inspecting each value. - - -H2K_runlist_init ----------------- - -.. c:function:: void H2K_runlist_init() - -Description -~~~~~~~~~~~ - -Initializes the :c:data:`H2K_kg.runlist` and :c:data:`H2K_kg.runlist_prios` -structures. - -Functionality -~~~~~~~~~~~~~ - -Set all elements of :c:data:`H2K_kg.runlist` to NULL, set all elements of -:c:data:`H2K_kg.runlist_prios` to -1. - - -H2K_runlist_push ----------------- - -.. c:function:: static inline void H2K_runlist_push(H2K_thread_context *newthread) - - :param newthread: Thread to add to the runlist - -Description -~~~~~~~~~~~ - -Inserts a thread into the runlist. - -Functionality -~~~~~~~~~~~~~ - -Set newthread's status to running, add newthread to the runlist, and add newthread's -priority to runlist_prios. - - -H2K_runlist_worst_prio ----------------------- - -.. c:function:: static inline u32_t H2K_runlist_worst_prio() - - :returns: the priority of the worst priority running thread. Returns - MAX_PRIOS or higher if no threads are in the runlist. - -Description -~~~~~~~~~~~ - -Returns the priority corresponding to the running thread with the worst priority. -Returns MAX_PRIOS or higher if no threads are in the runlist. - -Functionality -~~~~~~~~~~~~~ - -We iterate through the hardware threads to find the one with the worst priority -and return its priority. - - -H2K_runlist_worst_prio_hthread ------------------------------- - -.. c:function:: static inline u32_t H2K_runlist_worst_prio_hthread() - - :returns: the hardware thread number of the worst priority running thread. - Returns -1 if no threads are in the runlist. - -Description -~~~~~~~~~~~ - -Returns the priority corresponding to the running thread with the worst priority. -Returns MAX_PRIOS or higher if no threads are in the runlist. - -Functionality -~~~~~~~~~~~~~ - -We iterate through the hardware threads to find the one with the worst priority -and return its priority. - - -H2K_runlist_remove ------------------- - -.. c:function:: static inline void H2K_runlist_remove(H2K_thread_context *thread) - - :param thread: the thread to remove from the runlist - -Description -~~~~~~~~~~~ - -Removes ``thread`` from the runlist. By calling this function, you guarantee -that the thread is in the runlist. - -Functionality -~~~~~~~~~~~~~ - -We set runlist to NULL and runlist_prios to -1 for thread's hthread. - - - - - -Testing -------- - -Samples -~~~~~~~ - -* Input: H2K_kg.runlist array -* Input: H2K_kg.runlist_prios array -* Thread to push/remove -* Output: H2K_runlist_worst_prio: Priority of worst running thread -* Output: H2K_ready_array / H2K_ready_valids for remove/push - - -Important Cases -~~~~~~~~~~~~~~~ - -* H2K_runlist_worst_prio and H2K_runlist_worst_prio_hthread when the runlist is empty -* H2K_runlist_worst_prio and H2K_runlist_worst_prio_hthread when the runlist has - different threads in it - -* H2K_runlist_push should set H2K_kg.runlist and H2K_kg.runlist_prios appropriately. - -* H2K_runlist_remove should set H2K_kg.runlist to NULL and H2K_kg.runlist_prios to an - invalid priority. - -* Check H2K_runlist_init clears out randomized values. - -Harness -~~~~~~~ - -The runlist module is reasonably self-contained, so the test harness will only -use the header file and object file. - - - diff --git a/kernel/data/runlist/test/Makefile b/kernel/data/runlist/test/Makefile deleted file mode 100644 index 0e061956f..000000000 --- a/kernel/data/runlist/test/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -STANDALONE=1 - -OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist -RECOMPILE_SRCS_PREFS += runlist - -EXTRA_CFLAGS += -DTESTING -EXTRA_ASFLAGS += -DTESTING - -EXEC=test.elf - -include Makefile.inc -OSLIB= diff --git a/kernel/data/runlist/test/Makefile.inc b/kernel/data/runlist/test/Makefile.inc deleted file mode 100644 index 9d275c989..000000000 --- a/kernel/data/runlist/test/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# Need to define how to get back to the main H2 dir -H2DIR=${UPDIR}../../../.. - -# Everything else defined here -include ${H2DIR}/scripts/Makefile.inc.test - diff --git a/kernel/data/runlist/test/test.c b/kernel/data/runlist/test/test.c deleted file mode 100644 index 20dfdcac4..000000000 --- a/kernel/data/runlist/test/test.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -void FAIL(const char *str) -{ - puts("FAIL"); - puts(str); - exit(1); -} - -static H2K_thread_context a,b,c; -static u32_t hthread_mask; - -/* Create real versions of inlined functions */ - -s32_t H2K_runlist_worst_prio_TB() -{ - return H2K_runlist_worst_prio(); -} - -s32_t H2K_runlist_worst_prio_hthread_TB() -{ - return H2K_runlist_worst_prio_hthread(); -} - -void H2K_runlist_push_TB(H2K_thread_context *thread) -{ - H2K_runlist_push(thread); - hthread_mask |= (0x1 << thread->hthread); -} - -void H2K_runlist_remove_TB(H2K_thread_context *thread) -{ - H2K_runlist_remove(thread); - hthread_mask &= ~(0x1 << thread->hthread); -} - -void H2K_runlist_set_thread_prio_TB(H2K_thread_context *thread, u32_t new_prio) -{ - H2K_runlist_set_thread_prio(thread, new_prio); -} - -u32_t H2K_runlist_worst_prio_hthread_OK() -{ - s32_t hthread = H2K_runlist_worst_prio_hthread_TB(); - s32_t prio = H2K_runlist_worst_prio_TB(); - if (prio < 0 || prio > MAX_PRIO) { - return hthread < 0 || hthread > H2K_gp->hthreads; - } - return H2K_gp->runlist[hthread] != NULL && H2K_gp->runlist[hthread]->prio == prio; -} - -int main() -{ - __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - hthread_mask = 0; - H2K_gp->hthreads = 0; - if (H2K_runlist_worst_prio_TB() <= MAX_PRIO) FAIL("hthreads-off runlist worst prio in [0,MAX_PRIO]"); - H2K_gp->runlist[0] = &a; - H2K_gp->hthreads = get_hthreads(); - H2K_runlist_init(); - if (H2K_gp->runlist[0] != 0) FAIL("runlist_init failed to clear array"); - if (0 <= H2K_gp->runlist_prios[1] && H2K_gp->runlist_prios[1] <= MAX_PRIO) FAIL("runlist_init failed to clear prios"); - if (H2K_runlist_worst_prio_TB() <= MAX_PRIO) FAIL("cleared runlist worst prio in [0,MAX_PRIO]"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("cleared runlist worst prio hthread in [0,H2K_gp->hthreads)"); - - b.prio = a.prio = 2; - c.prio = 3; - a.hthread = 0; - b.hthread = 1; - c.hthread = 2; - - H2K_runlist_push_TB(&c); - H2K_runlist_remove_TB(&c); - u32_t hthreads_none = hthread_mask; - if (hthreads_none != 0) FAIL("runlist push-remove combo failed"); - - H2K_runlist_push_TB(&a); - if (H2K_gp->runlist[0] != &a) FAIL("runlist_push failed (0)"); - if (H2K_gp->runlist_prios[0] != 2) FAIL("runlist_push failed (1)"); - if (H2K_runlist_worst_prio_TB() != 2) FAIL("runlist_worst_prio failed (3)"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("runlist_worst_prio_hthread failed (30)"); - - H2K_runlist_push_TB(&b); - if (H2K_gp->runlist[1] != &b) FAIL("runlist_push failed (4)"); - if (H2K_gp->runlist_prios[1] != 2) FAIL("runlist_push failed (5)"); - if (H2K_runlist_worst_prio_TB() != 2) FAIL("runlist_worst_prio failed (7)"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("runlist_worst_prio_hthread failed (31)"); - - H2K_runlist_push_TB(&c); - if (H2K_runlist_worst_prio_TB() != 3) FAIL("runlist_worst_prio (8)"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("runlist_worst_prio_hthread failed (32)"); - - H2K_runlist_set_thread_prio_TB(&a, 5); - if (a.prio != 5) FAIL("runlist_set_thread_prio failed (40)"); - if (H2K_gp->runlist_prios[0] != 5) FAIL("runlist_set_thread_prio failed (41)"); - if (H2K_runlist_worst_prio_TB() != 5) FAIL("runlist_set_thread_prio worst_prio (42)"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("runlist_set_thread_prio_hthread (43)"); - - H2K_runlist_set_thread_prio_TB(&a, 2); - if (a.prio != 2) FAIL("runlist_set_thread_prio failed (44)"); - if (H2K_gp->runlist_prios[0] != 2) FAIL("runlist_set_thread_prio failed (45)"); - if (H2K_runlist_worst_prio_TB() != 3) FAIL("runlist_set_thread_prio worst_prio (46)"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("runlist_set_thread_prio_hthread (47)"); - - H2K_runlist_remove_TB(&a); - H2K_runlist_remove_TB(&c); - if (H2K_gp->runlist[0] != NULL) FAIL("runlist_remove failed (9)"); - if (H2K_gp->runlist[1] != &b) FAIL("runlist_remove failed (10)"); - if (H2K_gp->runlist[2] != NULL) FAIL("runlist_remove failed (11)"); - if (H2K_gp->runlist_prios[1] != 2) FAIL("runlist_remove failed (12)"); - if (0 <= H2K_gp->runlist_prios[2] && H2K_gp->runlist_prios[2] <= MAX_PRIO) FAIL("runlist_remove failed (13)"); - if (H2K_runlist_worst_prio_TB() != 2) FAIL("runlist_worst_prio (17)"); - if (!H2K_runlist_worst_prio_hthread_OK()) FAIL("runlist_worst_prio_hthread failed (33)"); - - H2K_runlist_remove_TB(&b); - if (H2K_gp->runlist[1] != NULL) FAIL("runlist_remove failed (18)"); - if (0 <= H2K_gp->runlist_prios[1] && H2K_gp->runlist_prios[1] <= MAX_PRIO) FAIL("runlist_remove failed (19)"); - if (H2K_runlist_worst_prio_TB() <= MAX_PRIO) FAIL("runlist_worst_prio (21)"); - - puts("TEST PASSED\n"); - return 0; -} - diff --git a/kernel/error/fatal/test/test.c b/kernel/error/fatal/test/test.c index 300960712..ef8680f0e 100644 --- a/kernel/error/fatal/test/test.c +++ b/kernel/error/fatal/test/test.c @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/kernel/event/intpool/intpool.ref.c b/kernel/event/intpool/intpool.ref.c index 15826fe27..fbd2fb161 100644 --- a/kernel/event/intpool/intpool.ref.c +++ b/kernel/event/intpool/intpool.ref.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -35,14 +34,13 @@ void H2K_intpool_int(u32_t intnum, H2K_thread_context *me, u32_t hwtnum, H2K_vmb H2K_ring_remove(&vmblock->intpool,woken); woken->r00 = intnum; if (me != NULL) { - H2K_runlist_remove(me); - H2K_ready_append(me); + H2K_ready_append_arm(me); } else { +#if CLUSTER_SCHED H2K_gp->wait_mask = (u32_t)Q6_R_clrbit_RR(H2K_gp->wait_mask,hwtnum); +#endif } - H2K_gp->priomask = (u32_t)Q6_R_clrbit_RR(H2K_gp->priomask,hwtnum); - highprio_imask(hwtnum); - H2K_runlist_push(woken); + woken->status = H2K_STATUS_RUNNING; H2K_switch(me,woken); } @@ -88,7 +86,6 @@ int H2K_intpool_wait(u32_t int_ack_num, H2K_thread_context *me) } } /* FIXME: check pending intpool interrupts */ - H2K_runlist_remove(me); H2K_ring_append(&vmblock->intpool,me); me->status = H2K_STATUS_INTBLOCKED; /* OR INTPOOL_BLOCKED? */ me->r00 = (u32_t)-1; diff --git a/kernel/event/intpool/intpool.spec b/kernel/event/intpool/intpool.spec index e6dc955fe..0e20f6400 100644 --- a/kernel/event/intpool/intpool.spec +++ b/kernel/event/intpool/intpool.spec @@ -34,12 +34,6 @@ If we soft pend the interrupt, we are done. If a thread was interrupted, we unschedule it and put it in the ready queue. Otherwise, the thread was idle, and so we mark ourselves as no longer idle. -We clear the low-priority status of the current thread, change our IMASK -appropriately, and place the woken thread directly into the runlist and switch -to it. This is speculative; the woken thread may not be higher priority than -the interrupted thread. However we expect this to be likely, and if it is incorrect -it will be remedied by :c:func:`H2K_check_sanity()`. - Note that we do not re-enable the interrupt at this time. The interrupt is only re-enabled when a thread explicitly calls to enable the interrupt, or waits with the int_ack field set to a valid interrupt. By keeping the interrupt disabled, diff --git a/kernel/event/intpool/test/Makefile b/kernel/event/intpool/test/Makefile index d5b84e2a9..c993ab28b 100644 --- a/kernel/event/intpool/test/Makefile +++ b/kernel/event/intpool/test/Makefile @@ -1,12 +1,8 @@ STANDALONE=1 OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio EXTRA_CFLAGS += -DTESTING EXTRA_ASFLAGS += -DTESTING diff --git a/kernel/event/intpool/test/test.c b/kernel/event/intpool/test/test.c index a58c1f700..209d315ff 100644 --- a/kernel/event/intpool/test/test.c +++ b/kernel/event/intpool/test/test.c @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include #include @@ -15,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -129,10 +126,7 @@ int TH_call_intpool_wait(int i, H2K_thread_context *current) */ void TH_check_waiting(int i, H2K_thread_context *thread) { - //if (H2K_gp->inthandlers[i].handler != H2K_intpool_int) FAIL("Wrong handler"); - //if (H2K_gp->inthandlers[i].param != thread) FAIL("Wrong thread"); if (thread->status != H2K_STATUS_INTBLOCKED) FAIL("Wrong status"); - if (H2K_gp->runlist[thread->hthread] == thread) FAIL("Thread still scheduled"); } /* @@ -140,14 +134,9 @@ void TH_check_waiting(int i, H2K_thread_context *thread) */ void TH_check_running(int i, H2K_thread_context *thread) { -#if 0 - printf("Checking i=%d thread=%p inthandlers[i].handler=%p inthandlers[i].param=%p\n", - i,thread,H2K_gp->inthandlers[i].handler,H2K_gp->inthandlers[i].param); -#endif if (H2K_gp->inthandlers[i].handler != NULL) FAIL("Handler set"); if (H2K_gp->inthandlers[i].param == thread) FAIL("Handler thread set"); if (thread->status != H2K_STATUS_RUNNING) FAIL("Wrong status"); - if (H2K_gp->runlist[thread->hthread] != thread) FAIL("Thread not scheduled"); } void TH_check_old(H2K_thread_context *thread) @@ -184,26 +173,19 @@ void TH_intpool_int(int i, H2K_thread_context *interrupted, int hthread, H2K_vmb void TH_set_idle(int hthread) { H2K_gp->wait_mask = 1<priomask = 1<wait_mask &= ~(1<priomask &= ~(1<wait_mask) FAIL("wait_mask still set"); - if ((1<<(hthread)) & H2K_gp->priomask) FAIL("priomask still set"); - if ((get_imask(thread->hthread)) == 0) { + if ((get_imask(thread->hthread)) != 0) { printf("ht=%x tht=%x imask=%x\n",hthread, thread->hthread, get_imask(thread->hthread)); - FAIL("IMASK clear for hthread"); + FAIL("IMASK set for hthread"); } } @@ -255,8 +237,6 @@ int main() H2K_gp->l2_ack_base = fakeint+(0x200/sizeof(u32_t)); #endif H2K_readylist_init(); - H2K_runlist_init(); - H2K_lowprio_init(); a.prio = b.prio = c.prio = MAX_PRIOS - 30; a.vmblock = b.vmblock = c.vmblock = vmblock; @@ -283,19 +263,16 @@ int main() #if ARCHV >= 4 if (i == 31) continue; #endif - H2K_runlist_push(&a); TH_clear_intpool(); if (TH_call_intpool_wait(i,&a) != 0) { FAIL("Couldn't wait"); } TH_check_waiting(i,&a); - H2K_runlist_push(&b); if (TH_call_intpool_wait(i,&b) != 0) { FAIL("Couldn't set second thread"); } TH_clear_intpool(); //TH_check_running(i,&b); - //H2K_runlist_remove(&b); } /* @@ -368,7 +345,6 @@ int main() } /* Case B: VMWORK alone -- gate must fire and return -1 without INTBLOCKED */ - H2K_runlist_push(&a); a.status = H2K_STATUS_RUNNING; a.vmstatus = H2K_VMSTATUS_VMWORK; TH_saw_do_work = 0; @@ -376,10 +352,8 @@ int main() if (!TH_saw_do_work) FAIL("B: VMWORK alone must call vm_do_work"); if (a.status == H2K_STATUS_INTBLOCKED) FAIL("B: must not set INTBLOCKED"); a.vmstatus = 0; - H2K_runlist_remove(&a); /* Case C: VMWORK|KILL -- killed thread racing into intpool_wait */ - H2K_runlist_push(&a); a.status = H2K_STATUS_RUNNING; a.vmstatus = H2K_VMSTATUS_VMWORK | H2K_VMSTATUS_KILL; TH_saw_do_work = 0; @@ -387,7 +361,6 @@ int main() if (!TH_saw_do_work) FAIL("C: VMWORK|KILL must call vm_do_work"); if (a.status == H2K_STATUS_INTBLOCKED) FAIL("C: must not set INTBLOCKED"); a.vmstatus = 0; - H2K_runlist_remove(&a); puts("TEST PASSED\n"); return 0; diff --git a/kernel/event/passthru/test/test.c b/kernel/event/passthru/test/test.c index 69559dbf7..79bd8c4c8 100644 --- a/kernel/event/passthru/test/test.c +++ b/kernel/event/passthru/test/test.c @@ -6,15 +6,12 @@ #include #include #include -#include -#include #include #include #include #include #include #include -#include #include #include #include diff --git a/kernel/event/popup/popup.ref.c b/kernel/event/popup/popup.ref.c index a7a2e74e6..ea1d6b23e 100644 --- a/kernel/event/popup/popup.ref.c +++ b/kernel/event/popup/popup.ref.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -27,18 +26,13 @@ void H2K_popup_int(u32_t intnum, H2K_thread_context *me, u32_t hwtnum, H2K_threa return; } if (me != NULL) { - H2K_runlist_remove(me); - H2K_ready_append(me); + H2K_ready_append_arm(me); } else { +#if CLUSTER_SCHED H2K_gp->wait_mask = (u32_t)Q6_R_clrbit_RR(H2K_gp->wait_mask,hwtnum); +#endif } - /* Assume woken is better than interrupted thread. - * If not, check_sanity will detect. - * Let check_sanity find the new lowprio thread also... - */ - H2K_gp->priomask = (u32_t)Q6_R_clrbit_RR(H2K_gp->priomask,hwtnum); - highprio_imask(hwtnum); - H2K_runlist_push(woken); + woken->status = H2K_STATUS_RUNNING; H2K_switch(me,woken); } @@ -62,7 +56,6 @@ int H2K_popup_wait(u32_t intnum, H2K_thread_context *me) } H2K_gp->inthandlers[intnum].param = me; H2K_gp->inthandlers[intnum].handler = H2K_popup_int; - H2K_runlist_remove(me); me->status = H2K_STATUS_INTBLOCKED; me->r0100 = intnum; H2K_intcontrol_enable(intnum); diff --git a/kernel/event/popup/popup.spec b/kernel/event/popup/popup.spec index ecf63077b..b9405bf40 100644 --- a/kernel/event/popup/popup.spec +++ b/kernel/event/popup/popup.spec @@ -31,12 +31,6 @@ If the popup thread is NULL, we merely unlock and return. If a thread was interrupted, we unschedule it and put it in the ready queue. Otherwise, the thread was idle, and so we mark ourselves as no longer idle. -We clear the low-priority status of the current thread, change our IMASK -appropriately, and place the woken thread directly into the runlist and switch -to it. This is speculative; the woken thread may not be higher priority than -the interrupted thread. However we expect this to be likely, and if it is incorrect -it will be remedied by :c:func:`H2K_check_sanity()`. - Note that we do not re-enable the interrupt at this time. The interrupt is only re-enabled when the thread blocks waiting for another interrupt. By keeping the interrupt disabled, we allow it to pend while the popup thread executes. @@ -73,7 +67,7 @@ return error. Set the interrupt handler to popup_int, and the extra interrupt argument to the thread context. -Do the work of blocking: take the thread out of the runlist, mark it as BLOCKED, and +Do the work of blocking: mark thread's state as BLOCKED, and set the return value to a successful return of the interrupt. Finally, enable the interrupt and select a new thread to schedule. diff --git a/kernel/event/popup/test/Makefile b/kernel/event/popup/test/Makefile index 32407b341..d27ac4f24 100644 --- a/kernel/event/popup/test/Makefile +++ b/kernel/event/popup/test/Makefile @@ -1,12 +1,8 @@ STANDALONE=1 OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio EXTRA_CFLAGS += -DTESTING EXTRA_ASFLAGS += -DTESTING diff --git a/kernel/event/popup/test/test.c b/kernel/event/popup/test/test.c index 50f079e7d..4453acd7b 100644 --- a/kernel/event/popup/test/test.c +++ b/kernel/event/popup/test/test.c @@ -6,15 +6,12 @@ #include #include #include -#include -#include #include #include #include #include #include #include -#include #include #include #include @@ -130,7 +127,6 @@ void TH_check_waiting(int i, H2K_thread_context *thread) if (H2K_gp->inthandlers[i].handler != H2K_popup_int) FAIL("Wrong handler"); if (H2K_gp->inthandlers[i].param != thread) FAIL("Wrong thread"); if (thread->status != H2K_STATUS_INTBLOCKED) FAIL("Wrong status"); - if (H2K_gp->runlist[thread->hthread] == thread) FAIL("Thread still scheduled"); } /* @@ -145,7 +141,6 @@ void TH_check_running(int i, H2K_thread_context *thread) if (H2K_gp->inthandlers[i].handler != NULL) FAIL("Handler set"); if (H2K_gp->inthandlers[i].param == thread) FAIL("Handler thread set"); if (thread->status != H2K_STATUS_RUNNING) FAIL("Wrong status"); - if (H2K_gp->runlist[thread->hthread] != thread) FAIL("Thread not scheduled"); } void TH_check_old(H2K_thread_context *thread) @@ -189,10 +184,9 @@ void TH_popup_int(int i, H2K_thread_context *interrupted, int hthread, H2K_threa */ void TH_set_idle(int hthread) { +#if CLUSTER_SCHED H2K_gp->wait_mask = 1<priomask = 1<wait_mask &= ~(1<priomask &= ~(1<wait_mask) FAIL("wait_mask still set"); - if ((1<<(hthread)) & H2K_gp->priomask) FAIL("priomask still set"); - if ((get_imask(thread->hthread)) == 0) FAIL("IMASK clear for hthread"); +#endif + if ((get_imask(thread->hthread)) != 0) FAIL("IMASK set for hthread"); } /* @@ -262,8 +256,6 @@ int main() H2K_gp->l2_ack_base = fakeint+(0x200/sizeof(u32_t)); #endif H2K_readylist_init(); - H2K_runlist_init(); - H2K_lowprio_init(); a.prio = b.prio = c.prio = MAX_PRIOS - 30; /* First, test wait */ @@ -282,19 +274,16 @@ int main() #if ARCHV >= 4 if (L2_CORE_INTERRUPT == i) continue; #endif - H2K_runlist_push(&a); TH_clear_popups(); if (TH_call_popup_wait(i,&a) != 0) { FAIL("Couldn't wait"); } TH_check_waiting(i,&a); - H2K_runlist_push(&b); if (TH_call_popup_wait(i,&b) == 0) { FAIL("Set popup for int twice"); } TH_clear_popups(); TH_check_running(i,&b); - H2K_runlist_remove(&b); } for (i = 0; i < MAX_INTERRUPTS; i++) { @@ -322,7 +311,6 @@ int main() TH_clear_ready(&a); } /* Case B: VMWORK alone -- gate must fire and return -1 without INTBLOCKED */ - H2K_runlist_push(&a); a.status = H2K_STATUS_RUNNING; a.vmstatus = H2K_VMSTATUS_VMWORK; TH_saw_do_work = 0; @@ -330,10 +318,8 @@ int main() if (!TH_saw_do_work) FAIL("B: VMWORK alone must call vm_do_work"); if (a.status == H2K_STATUS_INTBLOCKED) FAIL("B: must not set INTBLOCKED"); a.vmstatus = 0; - H2K_runlist_remove(&a); /* Case C: VMWORK|KILL -- killed thread racing into popup_wait */ - H2K_runlist_push(&a); a.status = H2K_STATUS_RUNNING; a.vmstatus = H2K_VMSTATUS_VMWORK | H2K_VMSTATUS_KILL; TH_saw_do_work = 0; @@ -341,7 +327,6 @@ int main() if (!TH_saw_do_work) FAIL("C: VMWORK|KILL must call vm_do_work"); if (a.status == H2K_STATUS_INTBLOCKED) FAIL("C: must not set INTBLOCKED"); a.vmstatus = 0; - H2K_runlist_remove(&a); /* popup_cancel: thread was waiting on interrupt i; cancel must clear the * handler slot and reset r00 to -1. */ @@ -352,7 +337,6 @@ int main() if (i == L2_CORE_INTERRUPT) continue; #endif TH_clear_popups(); - H2K_runlist_push(&a); /* Simulate the state popup_wait leaves: INTBLOCKED, r00=intnum, handler set */ a.status = H2K_STATUS_INTBLOCKED; a.r0100 = i; @@ -365,7 +349,6 @@ int main() if (H2K_gp->inthandlers[i].raw != 0) FAIL("cancel: handler not cleared"); if (a.r00 != (u32_t)-1) FAIL("cancel: r00 not reset"); - H2K_runlist_remove(&a); } } diff --git a/kernel/futex/futex/test/tests/pi/test.c b/kernel/futex/futex/test/tests/pi/test.c index 96ac4a0f1..6c7a5ebc2 100644 --- a/kernel/futex/futex/test/tests/pi/test.c +++ b/kernel/futex/futex/test/tests/pi/test.c @@ -56,6 +56,26 @@ volatile int TH_shutdown_now = 0; volatile int TH_done = 0; volatile int TH_caller_woke = 0; +typedef struct { + u64_t start; + u64_t end; +} cycle_timer_t; + +static void timer_start(cycle_timer_t *t) +{ + t->start = h2_get_core_pcycles(); +} + +static void timer_end(cycle_timer_t *t) +{ + t->end = h2_get_core_pcycles(); +} + +static u64_t timer_elapsed(cycle_timer_t *t) +{ + return t->end - t->start; +} + #define info(...) { h2_printf("INFO: "); h2_printf(__VA_ARGS__);} #define warn(...) { h2_printf("WARNING: "); h2_printf(__VA_ARGS__);} #define debug(...) { h2_printf("DEBUG: "); h2_printf(__VA_ARGS__);} @@ -173,6 +193,7 @@ void spawn_pi_caller(int tnum, int prio, int *futex_addr) int main(int argc, char **argv) { + cycle_timer_t total_timer, phase_timer; h2_handle_errors(0); futex1 = futex0 = h2_thread_myid(); @@ -183,7 +204,10 @@ int main(int argc, char **argv) h2_sem_init_val(&blocker2.sem,0); info("main() starting\n"); + timer_start(&total_timer); + /* Start up two low priority spinner threads */ + timer_start(&phase_timer); spawn_spinner(0,31); spawn_spinner(1,30); /* Start up a blocking spinner */ @@ -191,6 +215,8 @@ int main(int argc, char **argv) spawn_blocker(2,29,&blocker); blocker2.threadid = 3; spawn_blocker(3,28,&blocker2); + timer_end(&phase_timer); + info("Phase: Initial thread spawn - %llu cycles\n", timer_elapsed(&phase_timer)); /* Check spin status */ if (!still_spinning(&spinner_arr[0])) FAIL("t0 not spinning"); @@ -199,15 +225,18 @@ int main(int argc, char **argv) if (still_spinning(&spinner_arr[3])) FAIL("t3 spinning"); /* Priority inherit blocked thread */ + timer_start(&phase_timer); futex0 = thread_ids[2]; spawn_pi_caller(4,4,&futex0); /* Priority inherit running thread */ futex1 = thread_ids[1]; spawn_pi_caller(5,5,&futex1); + timer_end(&phase_timer); + info("Phase: Priority inherit setup - %llu cycles\n", timer_elapsed(&phase_timer)); /* Generate middlish spinners */ - + timer_start(&phase_timer); spawn_spinner(8,16); spawn_spinner(9,16); spawn_spinner(10,16); @@ -240,11 +269,13 @@ int main(int argc, char **argv) spawn_spinner(37,16); spawn_spinner(38,16); spawn_spinner(39,16); + timer_end(&phase_timer); + info("Phase: Middle spinners spawn - %llu cycles\n", timer_elapsed(&phase_timer)); info("Middle Spinners Launched\n"); /* Check that previous priority inheritance worked */ - + timer_start(&phase_timer); if (still_spinning(&spinner_arr[0])) FAIL("t0 spinning"); if (!still_spinning(&spinner_arr[1])) FAIL("t1 not spinning"); if (still_spinning(&spinner_arr[2])) FAIL("t2 spinning"); @@ -260,7 +291,7 @@ int main(int argc, char **argv) wait(1000); if (!still_spinning(&spinner_arr[2])) FAIL("t2 not spinning"); if (still_spinning(&spinner_arr[3])) FAIL("t3 spinning"); - + info("Blocked thread inherited OK, shutting down that test thread\n"); /* EJP: Add extra test case: additional blocked thread in same bin */ @@ -277,11 +308,14 @@ int main(int argc, char **argv) if (!still_spinning(&spinner_arr[0])) FAIL("t0 not spinning"); info("Waiting thread inherited OK, going to next step (handoff)\n"); + timer_end(&phase_timer); + info("Phase: Priority inheritance tests - %llu cycles\n", timer_elapsed(&phase_timer)); TH_shutdown_now = 0; TH_expected_futex_wakeup_thread = thread_ids[4]; TH_expected_futex_wakeup_val = FUTEX_PASS; + timer_start(&phase_timer); TH_nextstep_id = thread_ids[0]; while (TH_nextstep_id != 0) /* SPIN */; @@ -314,6 +348,11 @@ int main(int argc, char **argv) h2_sem_up(&blocker2.sem); TH_shutdown_now = 1; TH_done = 1; + timer_end(&phase_timer); + info("Phase: Futex unlock/handoff - %llu cycles\n", timer_elapsed(&phase_timer)); + + timer_end(&total_timer); + info("TOTAL TEST TIME: %llu cycles\n", timer_elapsed(&total_timer)); puts("TEST PASSED"); exit(0); } diff --git a/kernel/futex/futex_classic/futex_classic.ref.c b/kernel/futex/futex_classic/futex_classic.ref.c index 2be881dac..e34fa4f2f 100644 --- a/kernel/futex/futex_classic/futex_classic.ref.c +++ b/kernel/futex/futex_classic/futex_classic.ref.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -15,7 +14,6 @@ #include #include #include -#include #include #include @@ -42,7 +40,6 @@ s32_t H2K_futex_wait(u32_t *lock, u32_t val, H2K_thread_context *me) return -1; } me->futex_ptr = pa; - H2K_runlist_remove(me); me->r0100 = 0; me->status = H2K_STATUS_BLOCKED; H2K_futex_hash_add_ring(&H2K_gp->futexhash[FUTEX_HASHVAL(pa)],me); @@ -87,6 +84,8 @@ s32_t H2K_futex_resume(u32_t *lock, u32_t n_to_wake, H2K_thread_context *me) break; } } while (n_woken < n_to_wake); - return (s32_t)H2K_check_sanity_unlock(n_woken); + + BKL_UNLOCK(); + return (s32_t)n_woken; } diff --git a/kernel/futex/futex_classic/futex_classic.spec b/kernel/futex/futex_classic/futex_classic.spec index eeb54433d..b56074886 100644 --- a/kernel/futex/futex_classic/futex_classic.spec +++ b/kernel/futex/futex_classic/futex_classic.spec @@ -102,7 +102,3 @@ Matching threads, up to n_to_wake, are removed from the futex hash bucket and added to the ready queue. Threads have their `status` field modified to be `H2K_STATUS_READY`. -Finally, we sibcall to :c:func:`H2K_check_sanity_unlock()`, asking it to return -the number of woken threads. - - diff --git a/kernel/futex/futex_common/futex_common.ref.c b/kernel/futex/futex_common/futex_common.ref.c index d1898bef6..7f5d53831 100644 --- a/kernel/futex/futex_common/futex_common.ref.c +++ b/kernel/futex/futex_common/futex_common.ref.c @@ -57,7 +57,7 @@ H2K_thread_context *H2K_futex_hash_remove_one(u32_t locklo, H2K_thread_context * if (cur->futex_ptr_lo == locklo) { tmp = cur->next; H2K_ring_remove(ring,cur); - H2K_ready_append(cur); + H2K_ready_append_arm(cur); *pos = tmp; return cur; } else { diff --git a/kernel/futex/futex_pi/futex_pi.ref.c b/kernel/futex/futex_pi/futex_pi.ref.c index ae7aa0ed7..66375b234 100644 --- a/kernel/futex/futex_pi/futex_pi.ref.c +++ b/kernel/futex/futex_pi/futex_pi.ref.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -15,7 +14,6 @@ #include #include #include -#include #include #include @@ -41,10 +39,8 @@ static inline void H2K_futex_pi_raise(u32_t prio, H2K_id_t destid) dest->prio = (u8_t)prio; H2K_ready_insert(dest); } else if (dest->status == H2K_STATUS_RUNNING) { - H2K_runlist_set_thread_prio(dest, prio); - if (H2K_gp->priomask & (1<hthread)) { - H2K_raise_lowprio(); - } + dest->prio = (u8_t)prio; + set_thread_stid_prio(dest->hthread, prio); /* Need to update lowprio */ } else if (dest->status == H2K_STATUS_INTBLOCKED) { /* Waiting on interrupt, but we want it to have high priority when it starts up */ @@ -92,7 +88,6 @@ s32_t H2K_futex_lock_pi(u32_t *lock, H2K_thread_context *me) } H2K_futex_pi_raise(me->prio,x.dest); me->futex_ptr = pa; - H2K_runlist_remove(me); me->r0100 = 0; me->status = H2K_STATUS_BLOCKED; H2K_futex_hash_add_ring(&H2K_gp->futexhash[FUTEX_HASHVAL(pa)],me); @@ -120,6 +115,8 @@ s32_t H2K_futex_unlock_pi(u32_t *lock, H2K_thread_context *me) hashval = FUTEX_HASHVAL(pa); ring = &H2K_gp->futexhash[hashval]; pos = *ring; + me->prio = me->base_prio; + set_thread_stid_prio(me->hthread, me->base_prio); /* FIXME: pass full PA when supported */ ret = H2K_futex_hash_remove_one((u32_t)pa,ring,&pos); if (ret == NULL) { @@ -130,8 +127,6 @@ s32_t H2K_futex_unlock_pi(u32_t *lock, H2K_thread_context *me) H2K_atomic_swap(lock,H2K_id_from_context(ret).raw+1); } H2K_safemem_unlock(); - /* Restore my priority */ - H2K_runlist_set_thread_prio(me, me->base_prio); - return (s32_t)H2K_check_sanity_unlock(0); + BKL_UNLOCK(); + return 0; } - diff --git a/kernel/init/boot/boot.ref.S b/kernel/init/boot/boot.ref.S index 2ed83d785..db07f165d 100644 --- a/kernel/init/boot/boot.ref.S +++ b/kernel/init/boot/boot.ref.S @@ -348,10 +348,10 @@ boot_continuation: SETCONST(H2K_GP,H2K_kg) /* Set up rising edge triggered */ - TMP = #-1 - /* Set imask to -1, since we are not lowest priority at boot */ - /* (other idle threads) */ + /* Set imask to 0, enabling hardware interrupt steering */ + TMP = #0 imask = TMP + TMP = #-1 #if ARCHV < 65 iel = TMP iahl = TMP diff --git a/kernel/init/setup/setup.ref.c b/kernel/init/setup/setup.ref.c index 17abac72f..6ce261d37 100644 --- a/kernel/init/setup/setup.ref.c +++ b/kernel/init/setup/setup.ref.c @@ -5,12 +5,10 @@ #include #include -#include #include #include #include #include -#include #include #include #include @@ -92,11 +90,13 @@ IN_SECTION(".text.init.setup") static H2K_vmblock_t *H2K_init_setup(u32_t multic H2K_l2cache_init(); H2K_tcm_copy(last_tlb_index); H2K_trace_init(); - H2K_runlist_init(); H2K_readylist_init(); - H2K_lowprio_init(); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif H2K_futex_init(); H2K_intconfig_init(ssbase); + H2K_set_schedcfg(SCHEDCFG_EN | SCHEDCFG_INTNO(RESCHED_INT)); H2K_thread_init(); H2K_asid_table_init(); @@ -223,10 +223,10 @@ IN_SECTION(".text.init.boot") void H2K_thread_boot(u32_t multicore_shift, u32_t #endif -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED H2K_cluster_config(); #endif - H2K_runlist_push(boot); + boot->status = H2K_STATUS_RUNNING; H2K_mutex_unlock_tlb(); H2K_switch(NULL,boot); } diff --git a/kernel/init/setup/setup.spec b/kernel/init/setup/setup.spec index 4804809c2..680b88cd3 100644 --- a/kernel/init/setup/setup.spec +++ b/kernel/init/setup/setup.spec @@ -22,7 +22,6 @@ The :c:func:`H2K_init_setup()` function initializes kernel state at boot time. This function calls other initialization functions: * :c:func:`H2K_ready_init()` -* :c:func:`H2K_runlist_init()` * :c:func:`H2K_lowprio_init()` * :c:func:`H2K_futex_init()` * :c:func:`H2K_intconfig_init()` @@ -47,9 +46,8 @@ Next, we set up the boot thread context. Specifically: * Continuation should point to :c:func:`H2K_interrupt_restore()` * Trapmask should be initialized to all 1's. -Once we have set up the boot thread context and placed it into the runlist, we -switch to the thread. This will cause the kernel to go to the continuation -function, and will end up at qdsp6_pre_main, in crt0. +Once we have set up the boot thread context, we switch to the thread. +This will cause the kernel to go to the continuation function, and will end up at qdsp6_pre_main, in crt0. Testing ------- diff --git a/kernel/init/setup/test/test.c b/kernel/init/setup/test/test.c index 57d213337..2106c671c 100644 --- a/kernel/init/setup/test/test.c +++ b/kernel/init/setup/test/test.c @@ -7,9 +7,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -30,9 +28,7 @@ u32_t TH_init_seen; u32_t TH_switch_seen; enum { - runlist_init = 0, - readylist_init, - lowprio_init, + readylist_init = 0, futex_init, intconfig_init, kg_init, @@ -89,9 +85,9 @@ u32_t H2K_trap_config(u32_t configtype, void *ptr, u32_t val2, u32_t val3, u32_t #define HELPER_FUNC(X) void H2K_##X() { TH_init_seen |= 1<< X; } -HELPER_FUNC(runlist_init) + HELPER_FUNC(readylist_init) -HELPER_FUNC(lowprio_init) + HELPER_FUNC(futex_init) //HELPER_FUNC(intconfig_init) void H2K_intconfig_init(u32_t ssbase) { TH_init_seen |= 1<< intconfig_init; } @@ -144,16 +140,12 @@ void H2K_thread_boot(); int main() { u32_t i; - u32_t found_thread; __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); H2K_gp->logbuf_enable = 0; H2K_gp->hthreads = get_hthreads(); - for (i = 0; i < H2K_gp->hthreads; i++) { - H2K_gp->runlist[i] = 0; - } TH_init_seen = 0; TH_switch_seen = 0; if (setjmp(env) == 0) { @@ -166,14 +158,6 @@ int main() } if (boot->continuation != (H2K_interrupt_restore)) FAIL("Incorrect continuation"); if (boot->trapmask != 0xffffffffU) FAIL("boot thread trapmask"); - found_thread = 0; - for (i = 0; i < H2K_gp->hthreads; i++) { - if (H2K_gp->runlist[i] == boot) { - if (H2K_gp->runlist_prios[i] != 0) FAIL("Didn't push into runlist (0)"); - found_thread = 1; - } - } - if (!found_thread) FAIL("Didn't push into runlist (1)"); puts("TEST PASSED\n"); exit(0); } diff --git a/kernel/sched/check_sanity/check_sanity.ref.c b/kernel/sched/check_sanity/check_sanity.ref.c deleted file mode 100644 index 5690a2968..000000000 --- a/kernel/sched/check_sanity/check_sanity.ref.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -u64_t H2K_check_sanity(const u64_t retval) -{ - if (H2K_gp->priomask == 0) { - H2K_lowprio_notify(); - } - if (H2K_runlist_worst_prio() IS_WORSE_THAN H2K_ready_best_prio()) { - resched_int(); - } else if (H2K_gp->wait_mask && H2K_ready_any_valid()) { - resched_int(); - } - return(retval); -} - -u64_t H2K_check_sanity_unlock(const u64_t retval) -{ - call(H2K_check_sanity,retval); - BKL_UNLOCK(); - return(retval); -} diff --git a/kernel/sched/check_sanity/check_sanity.spec b/kernel/sched/check_sanity/check_sanity.spec index 439e4c2de..3e9727524 100644 --- a/kernel/sched/check_sanity/check_sanity.spec +++ b/kernel/sched/check_sanity/check_sanity.spec @@ -104,7 +104,6 @@ Samples * input MAX_PRIOS number of priority levels available (default 256) * input MAX_HTHREADS number of hardware threads available (default 6) * input H2K_kg.ready_valids priorities with ready jobs -* input H2K_kg.runlist_prios priorities of currently running threads * input H2K_kg.waitmask indicates hardware threads which are in wait * output ipend shows interrupts pending (see H2K_resched_int()) * i/o H2K_kg.priomask indicates lowest priority mask (see H2K_lowprio_notify) @@ -117,10 +116,6 @@ Important cases * H2K_kg.waitmask == 0 * H2K_kg.waitmask != 0 -* MAX(H2K_kg.runlist_prios) > CL0(H2K_kg.ready_valids) -* MAX(H2K_kg.runlist_prios) <= CL0(H2K_kg.ready_valids) -* H2K_kg.priomask == 0 -* H2K_kg.priomask != 0 Harness diff --git a/kernel/sched/check_sanity/test/Makefile b/kernel/sched/check_sanity/test/Makefile deleted file mode 100644 index 370f48df7..000000000 --- a/kernel/sched/check_sanity/test/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - - -SUBDIRS+=tests - -include Makefile.inc diff --git a/kernel/sched/check_sanity/test/Makefile.inc b/kernel/sched/check_sanity/test/Makefile.inc deleted file mode 100644 index 9d275c989..000000000 --- a/kernel/sched/check_sanity/test/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# Need to define how to get back to the main H2 dir -H2DIR=${UPDIR}../../../.. - -# Everything else defined here -include ${H2DIR}/scripts/Makefile.inc.test - diff --git a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/Makefile b/kernel/sched/check_sanity/test/tests/H2K_check_sanity/Makefile deleted file mode 100644 index 12882e607..000000000 --- a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/Makefile +++ /dev/null @@ -1,6 +0,0 @@ - - -SUBDIRS += scenarios - -include Makefile.inc - diff --git a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/Makefile b/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/Makefile deleted file mode 100644 index adff44fc9..000000000 --- a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -STANDALONE=1 - -OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist -RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist -RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio - -EXTRA_CFLAGS += -DTESTING -EXTRA_ASFLAGS += -DTESTING - -EXEC=test.elf -PYTHON_GENERATOR_SCRIPT=scenarios.py -PYTHON_GENERATED_FILES=scenarios.h - -# Include the include makefile. -include Makefile.inc -CC += -I../../../include -ffixed-r28 - -# Empty out the OSLIB variable. -OSLIB= diff --git a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/Makefile.inc b/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/Makefile.inc deleted file mode 100644 index 5e50a109a..000000000 --- a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# Need to define how to get back to the main H2 dir -H2DIR=${UPDIR}../../../../../../.. - -# Everything else defined here -include ${H2DIR}/scripts/Makefile.inc.test - diff --git a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/scenarios.py b/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/scenarios.py deleted file mode 100644 index d8961a235..000000000 --- a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/scenarios.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. -# SPDX-License-Identifier: BSD-3-Clause-Clear - -import sys -import random - -NUM_SCENARIOS = 10000 -NUM_THREADS_IN_SCENARIOS = 12 # must match the C code -MAX_PRIOS = 256 # must match max.h - -# This script generates scenarios for H2K_check_sanity. The scenarios are in -# the form of an initializer for a C array of structs. The initializer is -# included in test.c. test.c uses the information in the struct to set up the -# state before entering H2K_check_sanity, and to check the results of -# H2K_check_sanity. -# -# For each scenario, we generate a list of threads, each with three properties, -# status (RUNNING, READY, or BLOCKED), hthread, and prio. There may be at most -# MAX_HTHREADS RUNNING threads, and each RUNNING thread must have a valid -# hthread. No two RUNNING threads may have the same hthread. -# -# In addition to thread states, we generate a priomask and a wait_mask to be set -# before entering H2K_check_sanity. -# -# We also generate an expected output priomask and whether the resched interrupt -# should be raised. The output priomask does not have to exactly match the -# expected output priomask. If the input priomask is zero, then at least one -# bit of the output priomask should be set that is also set in the expected -# output priomask. - -with open('scenarios.h', 'w') as outfile: - random.seed(0) - MAX_HTHREADS_possibilities = (2, 3, 4, 6, 8) - - print('#if MAX_HTHREADS < %d' % min(MAX_HTHREADS_possibilities), file=outfile) - print('#error MAX_HTHREADS must be at least %d for this test.' % min(MAX_HTHREADS_possibilities), file=outfile) - print('#endif', file=outfile) - for MAX_HTHREADS in MAX_HTHREADS_possibilities: - print('#if MAX_HTHREADS >= ' + str(MAX_HTHREADS), file=outfile) - for i in range(NUM_SCENARIOS): - print('\t // status, hthread, prio', file=outfile) - # First we decide how many threads are RUNNING, READY, and BLOCKED. - num_running_threads = random.randrange(1, MAX_HTHREADS + 1) - num_ready_threads = random.randrange(NUM_THREADS_IN_SCENARIOS - num_running_threads + 1) - num_blocked_threads = NUM_THREADS_IN_SCENARIOS - num_running_threads - num_ready_threads - # Then we determine the hthread and prio of each RUNNING thread. - available_threads = list(range(MAX_HTHREADS)) - running_hthreads = [] - running_prios = [] - for thread_id in range(num_running_threads): - # For each RUNNING thread, we choose its hthread from the list of available hthreads. - hthread = random.choice(available_threads) - # Then we remove that hthread from the list of available hthreads so that no two - # RUNNING threads get assigned the same hthread. - available_threads.remove(hthread) - prio = random.randrange(MAX_PRIOS) - # We record the hthread and prio of each RUNNING thread in order to later compute - # the worst RUNNING prio and a valid priomask. - running_hthreads.append(hthread) - running_prios.append(prio) - # We then print out the state of the RUNNING thread. - if thread_id == 0: - outfile.write('\t{{') - else: - outfile.write('\t ') - print('{ RUNNING, %2d, %8d },' % (hthread, prio), file=outfile) - # Next we determine the hthread and prio of each READY thread. We record the ready_valids - # and best READY prio in order to later compute whether the resched interrupt should be raised. - ready_valids = 0 - best_ready_prio = MAX_PRIOS - for thread_id in range(num_ready_threads): - hthread = random.randrange(-5, 20) - prio = random.randrange(MAX_PRIOS) - ready_valids |= 1 << prio - if prio < best_ready_prio: - best_ready_prio = prio - # We then print out the state of the READY thread. - print('\t { READY, %2d, %8d },' % (hthread, prio), file=outfile) - # Next we determine the hthread and prio of each BLOCKED thread. - for thread_id in range(num_blocked_threads): - hthread = random.randrange(-5, 20) - prio = random.randrange(MAX_PRIOS) - # We then print out the state of the BLOCKED thread. - print('\t { BLOCKED, %2d, %8d },' % (hthread, prio), file=outfile) - print('\t },', file=outfile) - # Next we compute the list of RUNNING threads with the worst prio and the list of non-RUNNING hthreads. - worst_running_prio = max(running_prios) - worst_prio_running_threads = [] - non_running_threads = list(range(MAX_HTHREADS)) - for j in range(num_running_threads): - if running_prios[j] == worst_running_prio: - worst_prio_running_threads.append(running_hthreads[j]) - non_running_threads.remove(running_hthreads[j]) - # Then we compute a possible valid input priomask and the expected output priomask. - priomask = 0 - expected_priomask = 0 - for worst_prio_running_thread in worst_prio_running_threads: - if random.choice((True, False)): - priomask |= 1 << worst_prio_running_thread - expected_priomask |= 1 << worst_prio_running_thread - # Then we compute a possible valid wait_mask. - wait_mask = 0 - for non_running_thread in non_running_threads: - if random.choice((True, False)): - wait_mask |= 1 << non_running_thread - # We then compute whether the resched interrupt should be raised. - should_resched = (worst_running_prio > best_ready_prio or (wait_mask != 0 and ready_valids != 0)) - # Finally, we print out the remaining input and output state. - print('\t 0x%x, // priomask' % priomask, file=outfile) - print('\t 0x%x, // wait_mask' % wait_mask, file=outfile) - print('\t 0x%x, // expected_priomask' % expected_priomask, file=outfile) - print('\t %d, // should_resched' % should_resched, file=outfile) - print('\t %d, // hthreads' % MAX_HTHREADS, file=outfile) - print('\t},', file=outfile) - print('#endif', file=outfile) - # We print one last scenario to terminate the array. - print(""" // status, hthread, prio - {{{ RUNNING, 0, 0 },""", file=outfile) - for i in range(1, NUM_THREADS_IN_SCENARIOS): - print('\t { BLOCKED, %2d, %8d },' % (i, i), file=outfile) - print(""" }, - 0x0, // priomask - 0x0, // wait_mask - 0x1, // expected_priomask - 0, // should_resched - }""", file=outfile) diff --git a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/test.c b/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/test.c deleted file mode 100644 index d0a292b2b..000000000 --- a/kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios/test.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM_THREADS_IN_SCENARIOS 12 // must match the Python script - -enum status { - BLOCKED, - READY, - RUNNING -}; - -struct thread_state { - enum status status; - int hthread; - int prio; -}; - -struct scenario { - struct thread_state thread[NUM_THREADS_IN_SCENARIOS]; - int priomask; - int wait_mask; - int expected_priomask; - int should_resched; - int hthreads; -}; - -static char *status_string[] = { - "BLOCKED", - "READY", - "RUNNING" -}; - -static int test_status_to_H2_status[] = { - H2K_STATUS_BLOCKED, - H2K_STATUS_READY, - H2K_STATUS_RUNNING -}; - -static H2K_thread_context threads[NUM_THREADS_IN_SCENARIOS]; - -/* Get the scenarios from scenarios.h. */ -static struct scenario scenarios[] = { -#include "scenarios.h" -}; - -/* Prints a scenario. */ -static void print_scenario(struct scenario *scenario) -{ - int num_threads = sizeof(threads) / sizeof(threads[0]); - int status; - int hthread; - int prio; - int i; - puts("Thread Status hthread prio"); - for (i = 0; i < num_threads; i++) { - status = scenario->thread[i].status; - hthread = scenario->thread[i].hthread; - prio = scenario->thread[i].prio; - printf("t%-5d %s %-7d %d\n", i, status_string[status], hthread, prio); - } - printf("priomask = 0x%x\n", scenario->priomask); - printf("wait_mask = 0x%x\n", scenario->wait_mask); - printf("expected_priomask = 0x%x\n", scenario->expected_priomask); - printf("should_resched = %d\n", scenario->should_resched); -} - -/* Indicates a failure. Prints the scenario that failed. */ -static void FAIL(const char *str, struct scenario *scenario) -{ - puts("FAIL"); - puts(str); - print_scenario(scenario); - exit(1); -} - -/* Checks if the resched interrupt was raised. */ -static int resched_requested(void) -{ - return (H2K_get_ipend() & RESCHED_INT_INTMASK) != 0; -} - -/* Sets up the state described by the scenario. */ -static void setup(struct scenario *scenario) -{ - int num_threads = sizeof(threads) / sizeof(threads[0]); - int status; - int hthread; - int prio; - int i; - - H2K_clear_ipend(0xffffffff); - H2K_readylist_init(); - H2K_runlist_init(); - H2K_lowprio_init(); - for (i = 0; i < num_threads; i++) { - status = scenario->thread[i].status; - hthread = scenario->thread[i].hthread; - prio = scenario->thread[i].prio; - threads[i].status = test_status_to_H2_status[status]; - threads[i].hthread = hthread; - threads[i].prio = prio; - if (status == RUNNING) { - H2K_runlist_push(&threads[i]); - } else if (status == READY) { - H2K_ready_append(&threads[i]); - } - } - H2K_kg.priomask = scenario->priomask; - H2K_kg.wait_mask = scenario->wait_mask; -} - -/* Checks to see that H2K_check_sanity did its job, given the scenario. */ -static void check(struct scenario *scenario) -{ - int i; - if (scenario->priomask == 0) { - if ((H2K_kg.priomask & scenario->expected_priomask) == 0) { - FAIL("priomask not set for worst priority thread", scenario); - } - for (i = 0; i < H2K_kg.hthreads; i++) { - if (H2K_kg.priomask & 1 << i && get_imask(i) != 0) { - FAIL("failed to clear imask", scenario); - } - } - } else { - if (H2K_kg.priomask != scenario->priomask) { - FAIL("mucked with non-zero priomask", scenario); - } - } - if (scenario->should_resched && !resched_requested()) { - FAIL("failed to raise resched interrupt", scenario); - } - if (!scenario->should_resched && resched_requested()) { - FAIL("raised resched interrupt unnecessarily", scenario); - } -} - -static inline u64_t do_H2K_check_sanity(u64_t input) -{ - __asm__ __volatile__ (GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - return H2K_check_sanity(input); -} - -static inline u64_t do_H2K_check_sanity_unlock(u64_t input) -{ - __asm__ __volatile__ (GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - return H2K_check_sanity_unlock(input); -} - -/* Runs through the scenarios, setting them up and knocking them down. */ -int main() -{ - int num_scenarios = sizeof(scenarios) / sizeof(scenarios[0]); - int i; - - __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - - H2K_gp->hthreads = get_hthreads(); - - H2K_clear_gie(); - for (i = 0; i < num_scenarios && scenarios[i].hthreads <= H2K_gp->hthreads; i++) { - setup(&scenarios[i]); - BKL_LOCK(); - call(do_H2K_check_sanity, rand()); - BKL_UNLOCK(); - check(&scenarios[i]); - - setup(&scenarios[i]); - BKL_LOCK(); - call(do_H2K_check_sanity_unlock, rand()); - check(&scenarios[i]); - } - puts("TEST PASSED\n"); - return 0; -} diff --git a/kernel/sched/check_sanity/test/tests/Makefile b/kernel/sched/check_sanity/test/tests/Makefile deleted file mode 100644 index e962c4afe..000000000 --- a/kernel/sched/check_sanity/test/tests/Makefile +++ /dev/null @@ -1,4 +0,0 @@ - -SUBDIRS+=H2K_check_sanity - -include Makefile.inc diff --git a/kernel/sched/check_sanity/test/tests/Makefile.inc b/kernel/sched/check_sanity/test/tests/Makefile.inc deleted file mode 100644 index 148f7df95..000000000 --- a/kernel/sched/check_sanity/test/tests/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -UPDIR := ../${UPDIR} -include ${UPDIR}/Makefile.inc diff --git a/kernel/sched/dosched/dosched.ref.c b/kernel/sched/dosched/dosched.ref.c index 92562c7c4..381d535b1 100644 --- a/kernel/sched/dosched/dosched.ref.c +++ b/kernel/sched/dosched/dosched.ref.c @@ -5,9 +5,7 @@ #include #include -#include #include -#include #include #include #include @@ -19,7 +17,6 @@ void H2K_dosched(H2K_thread_context *me,u32_t hthread) new = H2K_ready_getbest(hthread); if (new == NULL) { /* GO TO SLEEP */ - H2K_raise_lowprio(); /* FIXME: temporary ugly hack for broken 8.7+ compiler -- investigate * whether this is still needed and if a proper direct call can be * restored */ @@ -27,27 +24,12 @@ void H2K_dosched(H2K_thread_context *me,u32_t hthread) "r1 = #0\n" "call H2K_switch\n" : : "r"(me)); - // H2K_switch(me,NULL); + // H2K_switch(me,NULL); /* EJP: should never get here! */ } - if ((H2K_gp->wait_mask == 0) && (new->prio IS_WORSE_THAN H2K_runlist_worst_prio())) { - /* If no threads are waiting and this new priority is worse than everyone else... */ - if ((H2K_gp->priomask & (1<priomask |= 1<priomask & (1<priomask = Q6_R_clrbit_RR(H2K_gp->priomask,hthread); - highprio_imask(hthread); - } - } new->hthread = (u8_t)hthread; - H2K_runlist_push(new); //if (new->vmstatus & H2K_VMSTATUS_VMWORK) H2K_vm_do_work(new); + new->status = H2K_STATUS_RUNNING; H2K_switch(me,new); /* EJP: should never get here! */ } diff --git a/kernel/sched/dosched/dosched.spec b/kernel/sched/dosched/dosched.spec index 55a63eab1..b01014089 100644 --- a/kernel/sched/dosched/dosched.spec +++ b/kernel/sched/dosched/dosched.spec @@ -34,32 +34,9 @@ The currently running thread must have already been removed from the list of running threads. First, we remove the best ready thread. If no ready thread is available, we -go to sleep: +go to sleep by switching from me to NULL - 0. If a running hthread is marked as lowest priority, it should be made non-lowprio - 1. We switch from me to NULL. - -Otherwise, if the waitmask is zero, and the priority of the new thread is worse than all the -other running threads, and the current hthread is not already marked as the lowprio thread, -we make ourselves the lowest priority thread: - - 0. Make the current lowprio thread non-lowprio - 1. The bit corresponding to the current hthread should be set in the priomask - 2. Our IMASK should change to be appropriate for the lowprio hthread. - -Otherwise, if the waitmask is nonzero, or the priority of the new thread is -better than all the other running threads, we check to see if we were marked as the -lowprio thread. If we were also marked as the lowprio hthread, we make ourselves non-lowprio: - - 0. Our IMASK should change to be appropriate for the non-lowprio thread. - 1. If the waitmask is zero, we should "notify" the new lowprio hthread. - -It is essential that we make ourselves non-lowprio here if appropriate, however it is NOT -essential that we find a lowprio hthread at this point. :c:func:`H2K_check_sanity()` will find a lowprio -hthread if priomask is zero. - -Finally, we set the new thread's hthread and add the new thread to the runlist -via :c:func:`H2K_runlist_push()`, and then switch to the thread by jumping to +Otherwise, we set the new thread's hthread, switch to the thread by jumping to :c:func:`H2K_switch()`, which does not return. Testing @@ -71,9 +48,6 @@ Samples * Input: me, which may or may not have a valid thread * Input: correct ready queue, which may or may not have ready threads -* I/O: runlist, which is updated if there is a new thread to schedule -* I/O: priomask, modified if new is NULL or the newly selected thread - is lowest priority (XXX: or if newly selected thread is non-lowprio?) * I/O: waitmask, modified if new is NULL Important cases @@ -85,10 +59,6 @@ Important cases * me is NULL * me is a valid thread -* We are the new lowest priority thread -* We are no longer the lowest priority thread -* We remain the lowest priority thread - * Other waiting threads * No other waiting threads diff --git a/kernel/sched/dosched/test/test/Makefile b/kernel/sched/dosched/test/test/Makefile index 8207cccd3..0fd1eeb2e 100644 --- a/kernel/sched/dosched/test/test/Makefile +++ b/kernel/sched/dosched/test/test/Makefile @@ -6,12 +6,8 @@ STANDALONE=1 # Hrm... check_sanity assertion stuff causing problems. Fix later. OBJS += harness.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio EXTRA_CFLAGS += -DTESTING EXTRA_ASFLAGS += -DTESTING diff --git a/kernel/sched/dosched/test/test/harness.c b/kernel/sched/dosched/test/test/harness.c index cc1094e2b..28d8052c8 100644 --- a/kernel/sched/dosched/test/test/harness.c +++ b/kernel/sched/dosched/test/test/harness.c @@ -6,13 +6,10 @@ #include #include #include -#include #include #include -#include #include #include -#include #include #include @@ -55,9 +52,10 @@ typedef void (* testsetup_t)(phase_t phase); void TB_reset() { TB_saw_switch = 0; - H2K_runlist_init(); H2K_readylist_init(); - H2K_lowprio_init(); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif } void TB_setup_common() @@ -70,7 +68,6 @@ void TB_check_common() { if (TB_saw_switch == 0) FAIL("No switch?"); checker_ready(); - checker_runlist(); } /* Do call to dosched, longjmp can bring us back */ @@ -91,92 +88,50 @@ void TB_do_call() void TB_fiddle_prio_low_to_low(phase_t phase) { if (phase == SETUP) { - /* Setup for call */ - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = H2K_gp->wait_mask; - } else { - H2K_gp->priomask = 0x1; - } - H2K_runlist_push(&h); H2K_ready_append(&m); TB_me = &l; } else { /* Check expected values */ if (TB_to != &m) FAIL("Unexpected thread scheduled"); - if (H2K_gp->wait_mask == 0) { - if ((H2K_gp->priomask & 1) == 0) FAIL("low_to_low did not switch to lowprio"); - } } } void TB_fiddle_prio_low_to_high(phase_t phase) { if (phase == SETUP) { - /* Setup for call */ - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = H2K_gp->wait_mask; - } else { - H2K_gp->priomask = 0x1; - } - H2K_runlist_push(&m); H2K_ready_append(&h); TB_me = &l; } else { /* Check expected values */ if (TB_to != &h) FAIL("Unexpected thread scheduled"); - if ((H2K_gp->priomask & 1) == 1) FAIL("low_to_high did not switch from lowprio"); } } void TB_fiddle_prio_high_to_low(phase_t phase) { if (phase == SETUP) { - /* Setup for call */ - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = H2K_gp->wait_mask; - } else { - H2K_gp->priomask = 0x2; - } - H2K_runlist_push(&m); H2K_ready_append(&l); TB_me = &h; } else { /* Check expected values */ if (TB_to != &l) FAIL("Unexpected thread scheduled"); - if (H2K_gp->wait_mask == 0) { - if ((H2K_gp->priomask & 1) == 0) FAIL("high_to_low did not switch to lowprio"); - } } } void TB_fiddle_prio_high_to_high(phase_t phase) { if (phase == SETUP) { - /* Setup for call */ - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = H2K_gp->wait_mask; - } else { - H2K_gp->priomask = 0x2; - } - H2K_runlist_push(&l); H2K_ready_append(&m); H2K_ready_append(&h); TB_me = &h; } else { if (TB_to != &h) FAIL("Unexpected thread scheduled"); - if ((H2K_gp->priomask & 1) != 0) FAIL( " Unexpected switch to lowprio"); } } void TB_fiddle_prio_high_to_wait(phase_t phase) { if (phase == SETUP) { - /* Setup for call */ - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = H2K_gp->wait_mask; - } else { - H2K_gp->priomask = 0x2; - } TB_me = &h; } else { /* Check expected values */ @@ -187,12 +142,6 @@ void TB_fiddle_prio_high_to_wait(phase_t phase) void TB_fiddle_prio_low_to_wait(phase_t phase) { if (phase == SETUP) { - /* Setup for call */ - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = H2K_gp->wait_mask; - } else { - H2K_gp->priomask = 0x1; - } TB_me = &l; } else { /* Check expected values */ @@ -205,22 +154,10 @@ void TB_fiddle_prio_wait_to_high(phase_t phase) if (phase == SETUP) { /* Setup for call */ TB_me = NULL; - H2K_runlist_push(&l); H2K_ready_append(&h); - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = 0; - H2K_lowprio_notify(); - } else { - H2K_gp->priomask = H2K_gp->wait_mask; - } } else { /* Check expected values */ if (H2K_ready_any_valid()) FAIL("didn't find ready thread"); - if (H2K_gp->runlist[h.hthread] != &h) FAIL("Didn't insert h thread"); - if (H2K_gp->runlist_prios[h.hthread] != h.prio) FAIL("Didn't insert h thread"); - if (H2K_gp->wait_mask == 0) { - if (H2K_gp->priomask == 0x1) FAIL("set myself to lowprio?"); - } } } @@ -230,22 +167,10 @@ void TB_fiddle_prio_wait_to_low(phase_t phase) if (phase == SETUP) { /* Setup for call */ TB_me = NULL; - H2K_runlist_push(&h); H2K_ready_append(&l); - if (H2K_gp->wait_mask == 0) { - H2K_gp->priomask = 0; - H2K_lowprio_notify(); - } else { - H2K_gp->priomask = H2K_gp->wait_mask; - } } else { /* Check expected values */ if (H2K_ready_any_valid()) FAIL("didn't find ready thread"); - if (H2K_gp->runlist[l.hthread] != &l) FAIL("Didn't insert l thread"); - if (H2K_gp->runlist_prios[l.hthread] != l.prio) FAIL("Didn't insert l thread"); - if (H2K_gp->wait_mask == 0) { - if (H2K_gp->priomask != 0x1) FAIL("Didn't set myself to lowprio"); - } } } @@ -275,6 +200,7 @@ testsetup_t TB_fiddle_prio[] = { }; /* Set up or check wait mask */ +#if CLUSTER_SCHED void TB_fiddle_wait_mask_zero(phase_t phase) { if (phase == SETUP) { @@ -303,6 +229,7 @@ testsetup_t TB_fiddle_wait_mask[] = { TB_fiddle_wait_mask_nonzero, NULL }; +#endif H2K_kg_t H2K_kg; @@ -328,6 +255,7 @@ int main() h2.prio = 2; h2.hthread = 0; +#if CLUSTER_SCHED /* For each wait mask type... */ for (i = 0; TB_fiddle_wait_mask[i] != NULL; i++) { /* For each change type... */ @@ -350,6 +278,7 @@ int main() TB_fiddle_prio[j](CHECK); } } +#endif puts("TEST PASSED\n"); return 0; } diff --git a/kernel/sched/lowprio/lowprio.h b/kernel/sched/lowprio/lowprio.h deleted file mode 100644 index a0629f459..000000000 --- a/kernel/sched/lowprio/lowprio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#ifndef LOWPRIO_H -#define LOWPRIO_H 1 - -#include -#include -#include -#include - -/* Notify a low priority thread that it is the new lowest priority if necessary */ -/* H2K_gp->priomask should be non-zero */ -static inline void H2K_lowprio_notify() -{ - u32_t hthread; - hthread = H2K_runlist_worst_prio_hthread(); - H2K_gp->priomask |= 1<priomask; - if (H2K_gp->wait_mask) return; // just a sanity check... should be an error - H2K_gp->priomask = 0; - change_imask((u32_t)Q6_R_ct0_R(mask),(u32_t)-1); -} - -void H2K_lowprio_init() IN_SECTION(".text.init.lowprio"); - -#endif - diff --git a/kernel/sched/lowprio/lowprio.ref.c b/kernel/sched/lowprio/lowprio.ref.c deleted file mode 100644 index fce38ae75..000000000 --- a/kernel/sched/lowprio/lowprio.ref.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include - -void H2K_lowprio_init() -{ -#ifdef TESTING - H2K_gp->priomask = H2K_gp->wait_mask = 0; -#endif -} - diff --git a/kernel/sched/lowprio/lowprio.spec b/kernel/sched/lowprio/lowprio.spec deleted file mode 100644 index e3def878a..000000000 --- a/kernel/sched/lowprio/lowprio.spec +++ /dev/null @@ -1,106 +0,0 @@ - -:mod:`lowprio` -- managing the lowest priority thread -===================================================== - -.. module:: lowprio - -H2K_kg.wait_mask and H2K_kg.priomask ------------------------------------- - -These words describe the hardware threads that are waiting for an interrupt, -and the hardware thread or threads that are the lowest priority. - -H2K_lowprio_notify ------------------- - -.. c:function:: static inline void H2K_lowprio_notify() - -Description -~~~~~~~~~~~ - -:c:func:`H2K_lowprio_notify()` identifies a new thread to be the lowest-priority thread -for receiving interrupts, and takes action to make that thread be receptive to -interrupts. - -Functionality -~~~~~~~~~~~~~ - -We get the hardware thread number the worst priority running thread and use that to set -the :c:data:`H2K_kg.priomask` bit corresponding to the hardware thread and to call -change_imask(). - - -H2K_lowprio_raise ------------------ - -.. c:function:: static inline void H2K_lowprio_raise() - -Description -~~~~~~~~~~~ - -:c:func:`H2K_lowprio_raise()` takes the thread currently marked as lowest priority, and -modifies the state to indicate it is no longer lowest priority. - -Functionality -~~~~~~~~~~~~~ - -If :c:data:`H2K_kg.wait_mask` is nonzero, we return, as we should never mask interrupts on -a waiting thread. Otherwise, count the trailing zeros of :c:data:`H2K_kg.priomask`, which -yields the hardware thread that should no longer be the low priority thread. -We clear that bit from the :c:data:`H2K_kg.priomask` and call :c:func:`H2K_prio_change_high()` for -the hardware thread. - - -H2K_lowprio_raise ------------------ - -.. c:function:: static inline void H2K_lowprio_init() - -Description -~~~~~~~~~~~ - -:c:func:`H2K_lowprio_init()` initializes the data structures used by the lowprio facility. - -Functionality -~~~~~~~~~~~~~ - -Set :c:data:`H2K_kg.wait_mask` and :c:data:`H2K_kg.priomask` to zero. - - - -Testing -------- - - -Samples -~~~~~~~ - -* Input: runlist -* Input: :c:data:`H2K_kg.wait_mask` -* I/O: :c:data:`H2K_kg.priomask` -* Output: IMASK values - -Important Cases -~~~~~~~~~~~~~~~ - -* :c:data:`H2K_kg.wait_mask` == 0: H2K_lowprio_raise should have no effect - -Harness -~~~~~~~ - -H2 lib kernel will be built. - -Various threads at various priorities should be added to runlist. -The lowest priority thread in the runlist should be marked as lowprio. -H2K_lowprio_raise will be called, and the formerly lowest priority -hardware thread should have a modified IMASK and the :c:data:`H2K_kg.priomask` bit -should be configured to be non-receptive to most interrutps. - -H2K_lowprio_notify should then be called. If :c:data:`H2K_kg.wait_mask` is nonzero, the -lowest priority thread in the runlist should be selected, the corresponding bit -should be added to :c:data:`H2K_kg.priomask`, and the IMASK on the corresponding hardware -thread should be receptive to most interrupts. - -Also, check that H2K_lowprio_init initializes :c:data:`H2K_kg.wait_mask` and :c:data:`H2K_kg.priomask`. - - diff --git a/kernel/sched/lowprio/make.inc b/kernel/sched/lowprio/make.inc deleted file mode 100644 index d00f59119..000000000 --- a/kernel/sched/lowprio/make.inc +++ /dev/null @@ -1 +0,0 @@ -include $(MAKE_INC_DEFAULT) diff --git a/kernel/sched/lowprio/test/Makefile b/kernel/sched/lowprio/test/Makefile deleted file mode 100644 index 9a09b17be..000000000 --- a/kernel/sched/lowprio/test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -INC_KERNEL=1 - -OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += lowprio - -EXTRA_CFLAGS += -DTESTING -EXTRA_ASFLAGS += -DTESTING - -EXEC=test.elf - -include Makefile.inc - -CFLAGS+= -ffixed-r28 -O0 diff --git a/kernel/sched/lowprio/test/test.c b/kernel/sched/lowprio/test/test.c deleted file mode 100644 index 00dd52f64..000000000 --- a/kernel/sched/lowprio/test/test.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void FAIL(const char *x) -{ - puts("FAIL"); - puts(x); - exit(1); -} - -void h2_init(); - -H2K_thread_context a,b; - -void H2K_lowprio_notify_TB() -{ - return H2K_lowprio_notify(); -} - -void H2K_raise_lowprio_TB() -{ - return H2K_raise_lowprio(); -} - -typedef void (*TB_func)(); - -TB_func notify = H2K_lowprio_notify_TB; -TB_func raise = H2K_raise_lowprio_TB; - -int main() -{ - int i; - __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - for (i = 0; i < 1000; i++) { - h2_init(); - } - - a.prio = b.prio = 2; - a.hthread = b.hthread = 1; - if ((get_imask(1) & 1) != 0) FAIL("T1 should be idle at boot"); - - H2K_runlist_push(&a); - raise(); - if ((get_imask(1) & 1) != 0) FAIL("should not have raised if idle"); - H2K_gp->wait_mask = 0; - H2K_gp->priomask = 0x2; - raise(); - if ((get_imask(1) & 1) == 0) FAIL("should have raised T1"); - H2K_gp->priomask = 0; - H2K_gp->hthreads = 2; // so that H2K_runlist_worst_prio_hthread() will find t1 - notify(); - if ((get_imask(1) & 1) != 0) FAIL("should have notified T1"); - puts("TEST PASSED\n"); - return 0; -} - diff --git a/kernel/sched/resched/resched.ref.c b/kernel/sched/resched/resched.ref.c index 9043433c7..9932bfd12 100644 --- a/kernel/sched/resched/resched.ref.c +++ b/kernel/sched/resched/resched.ref.c @@ -6,21 +6,20 @@ #include #include #include -#include #include #include -#include #include #include #include static inline void resched(u32_t unused, H2K_thread_context *me, u32_t hwtnum) { if (me != NULL) { - H2K_runlist_remove(me); - H2K_ready_append(me); + H2K_ready_append_arm(me); } else { /* Interrupted WAIT mode */ +#if CLUSTER_SCHED H2K_gp->wait_mask = Q6_R_clrbit_RR(H2K_gp->wait_mask,hwtnum); +#endif } H2K_dosched(me, hwtnum); } diff --git a/kernel/sched/resched/resched.spec b/kernel/sched/resched/resched.spec index 2cdc48cb1..9f21add85 100644 --- a/kernel/sched/resched/resched.spec +++ b/kernel/sched/resched/resched.spec @@ -40,7 +40,6 @@ Samples * input: Pointer to the current thread (or NULL) * input: Hardware Thread number -* input: If me != NULL, Runlist structure including me thread in the correct location * output: if me == NULL, clear the H2K_kg.wait_mask bit corresponding to the hardware thread number * i/o: if me != NULL, readylist structure will have me appended to it * Must call H2K_dosched when finished @@ -50,7 +49,7 @@ Important Cases * me == NULL, bit set in H2K_kg.wait_mask (bit must be cleared) * me == NULL, bit not set in H2K_kg.wait_mask (bit must stay cleared) -* me != NULL, thread must be removed from runlist and added to readylist +* me != NULL, thread must be added to readylist * All: must call H2K_dosched at end of routine Check to make sure continuation is set? @@ -63,8 +62,8 @@ H2 lib kernel will be built, and linked with the test harness. The test harness will define our own H2K_dosched(), to replace the function in the H2 kernel. It will set a flag indicating that it was called. -For each test, we initialize and set up the appropriate structures (runlist, -readylist, wait_mask, etc), and then call H2K_resched(). We check to make +For each test, we initialize and set up the appropriate structures +(readylist, wait_mask, etc), and then call H2K_resched(). We check to make sure that our version of H2K_dosched() was called, and check to make sure other appropraite actions were taken. diff --git a/kernel/sched/resched/test/Makefile b/kernel/sched/resched/test/Makefile index 32407b341..d0f09c55c 100644 --- a/kernel/sched/resched/test/Makefile +++ b/kernel/sched/resched/test/Makefile @@ -1,12 +1,9 @@ STANDALONE=1 OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio EXTRA_CFLAGS += -DTESTING EXTRA_ASFLAGS += -DTESTING diff --git a/kernel/sched/resched/test/test.c b/kernel/sched/resched/test/test.c index db6d86982..bca355120 100644 --- a/kernel/sched/resched/test/test.c +++ b/kernel/sched/resched/test/test.c @@ -6,15 +6,12 @@ #include #include #include -#include -#include #include #include #include #include #include #include -#include #include #include #include @@ -36,11 +33,12 @@ void H2K_dosched(H2K_thread_context *in, int hthread) { if (in != TB_in) FAIL("Unexpected thread passed to dosched"); if (TB_in && hthread != TB_in->hthread) FAIL("Unexpected hardware thread"); +#if CLUSTER_SCHED if (H2K_gp->wait_mask != 0) FAIL("Set bit in wait_mask"); +#endif TB_saw_dosched ++; checker_kernel_locked(); BKL_UNLOCK(); - checker_runlist(); checker_ready(); longjmp(env,1); } @@ -64,12 +62,13 @@ void TH_resched_cluster(u32_t unused, H2K_thread_context *me, u32_t hwtnum) int main() { __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED H2K_gp->cluster_sched = 1; #endif H2K_readylist_init(); - H2K_runlist_init(); - H2K_lowprio_init(); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif a.prio = b.prio = c.prio = MAX_PRIOS - 30; a.hthread = 0; b.hthread = 1; @@ -78,32 +77,35 @@ int main() TH_resched(0,TB_in,0); if (TB_saw_dosched == 0) FAIL("did not do a resched"); TB_saw_dosched = 0; +#if CLUSTER_SCHED H2K_gp->wait_mask = 1; +#endif TH_resched(0,TB_in,0); if (TB_saw_dosched == 0) FAIL("Did not do a resched"); +#if CLUSTER_SCHED H2K_gp->wait_mask = 0; +#endif TB_saw_dosched = 0; TB_in = &a; - H2K_runlist_push(&a); - H2K_runlist_push(&c); TH_resched(0,TB_in,0); if (TB_saw_dosched == 0) FAIL("Did not do a resched"); - if (H2K_gp->runlist[c.hthread] != &c) FAIL("Unexpected thread in runlist"); if (H2K_gp->ready[MAX_PRIOS - 30] != &a) FAIL("Unexpected thread in readylist"); +#if CLUSTER_SCHED H2K_gp->wait_mask = 0; +#endif TB_saw_dosched = 0; TB_in = &c; TH_resched(0,TB_in,2); if (TB_saw_dosched == 0) FAIL("Did not do a resched"); if (H2K_gp->ready[MAX_PRIOS - 30] != &a) FAIL("Unexpected thread in readylist"); if (H2K_gp->ready[MAX_PRIOS - 30]->next != &c) FAIL("Unexpected thread in readylist"); +#if CLUSTER_SCHED H2K_gp->wait_mask = 0; +#endif TB_saw_dosched = 0; TB_in = &b; - H2K_runlist_push(&b); TH_resched_cluster(0,TB_in,1); if (TB_saw_dosched == 0) FAIL("Did not do a resched"); - if (H2K_gp->runlist[b.hthread] == &b) FAIL("Unexpected thread in runlist"); if (H2K_gp->ready[MAX_PRIOS - 30]->next->next != &b) FAIL("Unexpected thread in readylist"); puts("TEST PASSED\n"); return 0; diff --git a/kernel/sched/switch/switch.ref.S b/kernel/sched/switch/switch.ref.S index b1f06acf4..c8762751d 100644 --- a/kernel/sched/switch/switch.ref.S +++ b/kernel/sched/switch/switch.ref.S @@ -16,7 +16,7 @@ * We don't care about any registers * Handle any tracing and profiling * If switching to NULL, go to sleep - * Otherwise, load continuation into LR and jump to check_sanity_unlock + * Otherwise, load continuation into LR */ FUNC_START H2K_switch .text.core.switch .p2align 5 @@ -279,6 +279,7 @@ FUNC_START H2K_switch .text.core.switch .p2align 5 #else stid = r4 #endif + isync r17 = r1 r0 = r17 @@ -286,7 +287,8 @@ FUNC_START H2K_switch .text.core.switch .p2align 5 r1:0 = memd(r17+#CONTEXT_r0100) r31 = memw(r17+#CONTEXT_continuation) r31 = and(r31,#-4) // ignore LSBs - jump H2K_check_sanity_unlock + k0unlock + jumpr r31 .Lto_sleep: memd(r9) = r19:18 @@ -313,20 +315,14 @@ FUNC_START H2K_switch .text.core.switch .p2align 5 //ASM_INLINE_TRACE(r14,r27:26,r27,r26,r25:24,r25,r24,p0,r21,r20,r31,,) r9 = memw(H2K_GP+#KG_wait_mask) - r8 = memw(H2K_GP+#KG_priomask) r9 = setbit(r9,r5) - r8 = setbit(r8,r5) memw(H2K_GP+#KG_wait_mask) = r9 - memw(H2K_GP+#KG_priomask) = r8 - k0unlock + // set SGP to NULL sgp0 = r1 - // set IMASK to receive most interrupts - r0 = imask - r1.h = #HI(0) - r1.l = #LO(0) - r0 = and(r0,r1) + // set IMASK to receive all interrupts + r0 = #0 imask = r0 // set TID to special value (-1) @@ -336,6 +332,8 @@ FUNC_START H2K_switch .text.core.switch .p2align 5 #else stid = r1 #endif + isync + k0unlock // set SSR to enable interrupts // NOTE: should be the last thing before going to WAIT mode, we may get an interrupt diff --git a/kernel/sched/switch/switch.spec b/kernel/sched/switch/switch.spec index 8628fceea..5971afcf9 100644 --- a/kernel/sched/switch/switch.spec +++ b/kernel/sched/switch/switch.spec @@ -50,13 +50,6 @@ register, load the saved r1:0 (which contain a return value from the blocking function), and set or clear the PMU bit for the current hardware thread, depending on whether it is enabled for the software thread. -Finally, we jump to :c:func:`H2K_check_sanity_unlock()`. -:c:func:`H2K_check_sanity_unlock()` will return to the continuation. - - - - - Testing ------- @@ -67,12 +60,10 @@ Samples * Input: from, which may be NULL * Input: to, which may be NULL -* Flow: If to is non-NULL, we should arrive at :c:func:`H2K_check_sanity_unlock()` with the return address - set to the continuation value in "to" +* Flow: If to is non-NULL, we should return the address set to the continuation value in "to" * Ouptut: If to is NULL, we should unlock the kernel lock, * Flow: if to is NULL, we should jump to H2K_wait_forever * I/O: H2K_wait_mask bit set for our hardware thread only if to is NULL -* I/O: H2K_priomask bit set for our hardware thread only if to is NULL * Output: if to is NULL, we should additionally have the machine configured to be in WAIT mode: * The kernel is unlocked * SGP for our hardware thread is set to NULL diff --git a/kernel/sched/yield/test/Makefile b/kernel/sched/yield/test/Makefile index 32407b341..d27ac4f24 100644 --- a/kernel/sched/yield/test/Makefile +++ b/kernel/sched/yield/test/Makefile @@ -1,12 +1,8 @@ STANDALONE=1 OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio EXTRA_CFLAGS += -DTESTING EXTRA_ASFLAGS += -DTESTING diff --git a/kernel/sched/yield/test/test.c b/kernel/sched/yield/test/test.c index dcfc79eaa..8c09d73cf 100644 --- a/kernel/sched/yield/test/test.c +++ b/kernel/sched/yield/test/test.c @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include #include @@ -50,16 +48,15 @@ int main() { __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); H2K_readylist_init(); - H2K_runlist_init(); - H2K_lowprio_init(); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif a.prio = b.prio = c.prio = d.prio = 2; a.hthread = 0; b.hthread = 2; c.hthread = 1; d.hthread = 2; TB_in = &a; - H2K_runlist_push(&a); - H2K_runlist_push(&c); TH_sched_yield(TB_in); if (TB_saw_dosched != 0) FAIL("Did a resched"); H2K_ready_append(&b); @@ -72,11 +69,9 @@ int main() if (TB_saw_dosched == 0) FAIL("Did not do a resched"); BKL_UNLOCK(); H2K_readylist_init(); - H2K_runlist_init(); - H2K_lowprio_init(); - H2K_runlist_push(&a); - H2K_runlist_push(&c); - H2K_runlist_push(&d); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif H2K_ready_append(&b); TB_in = &a; TH_sched_yield(TB_in); diff --git a/kernel/sched/yield/yield.ref.c b/kernel/sched/yield/yield.ref.c index c12f2d7fb..92da034e6 100644 --- a/kernel/sched/yield/yield.ref.c +++ b/kernel/sched/yield/yield.ref.c @@ -4,7 +4,6 @@ */ #include -#include #include #include #include @@ -22,8 +21,6 @@ void H2K_sched_yield(H2K_thread_context *me) BKL_UNLOCK(&H2K_bkl); return; } - H2K_runlist_remove(me); H2K_ready_append(me); H2K_dosched(me,me->hthread); } - diff --git a/kernel/sched/yield/yield.spec b/kernel/sched/yield/yield.spec index 4757aa4ab..58822ff89 100644 --- a/kernel/sched/yield/yield.spec +++ b/kernel/sched/yield/yield.spec @@ -26,14 +26,12 @@ return immediately after releasing the BKL. (EJP: can we do this outside the BK Another thread might be inserting itself into the ready list. Can we spec the function so that it does a best effort?) -Next, the :c:func:`H2K_sched_yield()` function removes the current thread from the runlist, and -appends it on the end of the ready list. +Next, the :c:func:`H2K_sched_yield()` function appends the thread to the end of the ready list. We can then call :c:func:`H2K_dosched()` to pick a new thread to run. As an optimization, we can instead remove the thread at the head of the -readylist at the same priority, and insert it into the runlist. We switch to -the thread inserted into the runlist. +readylist at the same priority and switch to it. @@ -47,14 +45,13 @@ Samples * Input: me, which may or may not have a valid thread * Input: correct ready queue, which may or may not have ready threads -* I/O: runlist, which is updated if there is a new thread to schedule * I/O: waitmask, modified if new is NULL Important cases ~~~~~~~~~~~~~~~ -* Runlist has no valid threads at current thread's priority -* Runlist has valid threads at current thread's priority +* No valid threads at current thread's priority +* There are valid threads at current thread's priority Harness ~~~~~~~ @@ -62,8 +59,8 @@ Harness Link with H2 kernel library. If valid threads exist at the current priority, :c:func:`H2K_sched_yield()` should lock -the kernel, remove the current thread from the runlist, append the current -thread to the ring at the current thread priority, and call :c:func:`H2K_dosched()`. +the kernel, append the current thread to the ring at the current thread priority, +and call :c:func:`H2K_dosched()`. If no valid threads exist at the current priority, :c:func:`H2K_sched_yield()` may return immediately. Since this optimization may be important for performance diff --git a/kernel/thread/create/create.ref.c b/kernel/thread/create/create.ref.c index fa716d75b..ee50bec15 100644 --- a/kernel/thread/create/create.ref.c +++ b/kernel/thread/create/create.ref.c @@ -19,6 +19,7 @@ #include #include #include +#include void H2K_interrupt_restore(); @@ -106,8 +107,9 @@ IN_SECTION(".text.misc.create") s32_t H2K_thread_create_no_squash(u32_t pc, u32_ vmblock->num_cpus++; tmp->vmblock = vmblock; - H2K_ready_append(tmp); - return (s32_t)H2K_check_sanity_unlock(H2K_id_from_context(tmp).raw); + H2K_ready_append_arm(tmp); + BKL_UNLOCK(); + return (s32_t)H2K_id_from_context(tmp).raw; } IN_SECTION(".text.misc.create") s32_t H2K_thread_create(u32_t pc, u32_t sp, u32_t arg1, u32_t prio, H2K_vmblock_t *vmblock, H2K_thread_context *me) diff --git a/kernel/thread/create/create.spec b/kernel/thread/create/create.spec index 7ab4bfd65..a0c01613c 100644 --- a/kernel/thread/create/create.spec +++ b/kernel/thread/create/create.spec @@ -72,8 +72,7 @@ If vmblock is non-NULL, these actions are added: * The vmblock pointer of the new thread is inherited from the caller. -We then add the new thread to the readylist, and call :c:func:`H2K_check_sanity_unlock()` -before returning. +We then add the new thread to the readylist. For security, we need to assure that no values are in registers incorrectly. We accomplish this by clearing the thread context during initialization and @@ -113,8 +112,6 @@ Harness We link directly with the create object file, and also the readylist object file. -We define :c:func:`H2K_check_sanity_unlock()` to set a flag indicating that the function was called. - The test harness will call :c:func:`H2K_thread_create()` with various inputs and check to make sure that the appropriate action was taken: diff --git a/kernel/thread/create/test/Makefile b/kernel/thread/create/test/Makefile index c6bf76489..a368c29a7 100644 --- a/kernel/thread/create/test/Makefile +++ b/kernel/thread/create/test/Makefile @@ -1,13 +1,9 @@ STANDALONE=1 OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio RECOMPILE_DIRS += $(H2DIR)/kernel/mem/asid -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio RECOMPILE_SRCS_PREFS += asid EXTRA_CFLAGS += -DTESTING diff --git a/kernel/thread/create/test/test.c b/kernel/thread/create/test/test.c index 528d4a881..054fa4e9b 100644 --- a/kernel/thread/create/test/test.c +++ b/kernel/thread/create/test/test.c @@ -6,9 +6,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -66,24 +64,8 @@ void TH_vm_init() H2K_kg.vmblocks[2] = &TH_vm.vm; } -u32_t TH_saw_check_sanity = 0; H2K_thread_context *TH_me = NULL; -u64_t H2K_check_sanity_unlock(u64_t x) -{ - TH_saw_check_sanity++; - checker_kernel_locked(); - BKL_UNLOCK(); - return x; -} - -u64_t H2K_check_sanity(u64_t x) -{ - TH_saw_check_sanity++; - checker_kernel_locked(); - return x; -} - u64_t H2K_check_sched_mask(u64_t x) { FAIL("Saw sched mask check"); @@ -106,9 +88,10 @@ int main() u32_t asid; H2K_vmblock_t *vmblock = &TH_vm.vm; __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - H2K_runlist_init(); H2K_readylist_init(); - H2K_lowprio_init(); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif H2K_thread_init(); H2K_asid_table_init(); TH_vm_init(); @@ -144,11 +127,8 @@ int main() if (H2K_thread_create(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,902,vmblock,a) != 0xffffffff) FAIL("Created thread w/ bad prio"); - if (TH_saw_check_sanity != 0) FAIL("Called check_sanity on failure"); - if (gpcall_H2K_thread_create(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,2,vmblock,a) != (b->id.raw)) FAIL("Failed to create expected thread"); - if (TH_saw_check_sanity == 0) FAIL("Did not call check_sanity"); if (H2K_gp->ready[2] != b) FAIL("Thread inserted incorrectly into ready list"); if (b->prio != 2) FAIL("thread priority set wrong"); if (b->status == H2K_STATUS_DEAD) FAIL("status field incorrect"); @@ -159,62 +139,11 @@ int main() if (b->gp != a->gp) FAIL("Incorrect inheritance of GP"); if (b->vmblock != vmblock) FAIL("vmblock is non-NULL"); - TH_saw_check_sanity = 0; vmblock->pmap = 0x12345678; if (H2K_thread_create(((u32_t)test_thread), (u32_t)&stack,0xdeadbeef,2,vmblock,a) != (c->id.raw)) FAIL("Failed to create expected thread"); if (c->ssr_asid != a->ssr_asid) FAIL("wrong asid"); -#if 0 - vm.max_cpus = 2; - vm.num_cpus = 2; // initially full - vm.bestprio = 5; - vm.trapmask = 0xfa1a1a1a; - vm.cpu_contexts = vmcontext; - vm.pmap = 0xb1ab1ab1; - vm.pmap_type = H2K_ASID_TRANS_TYPE_TABLE; - - /* so we can check if properly decremented */ - asid = H2K_asid_table_inc(vm.pmap, H2K_ASID_TRANS_TYPE_TABLE, H2K_ASID_TLB_INVALIDATE_FALSE, 0, vmblock); - - ret = H2K_thread_create_no_squash(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,6,&vm,&a); - /* asid count should have gone to 2 and then back to 1 */ - if (H2K_mem_asid_table[asid].fields.count != 1) FAIL("Bad asid count"); - if (ret != -1) FAIL("Exceeded max_cpus"); - - vm.num_cpus = 1; -#warning Need to reenable this test and fix when audio becomes unbroken - //ret = H2K_thread_create_no_squash(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,4,&vm,&a); - //if (ret != -1) FAIL("Exceeded vm bestprio"); - - /* should succeed */ - ret = H2K_thread_create_no_squash(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,6,&vm,&a); - if (ret == -1) FAIL("Unexpected error"); - - if (c->trapmask != 0xfa1a1a1a) FAIL("Bad vm trapmask"); - /* asid should be that of the calling thread, because we're starting an additional vcpu */ - if (c->ssr_asid != a->ssr_asid) FAIL("Bad vm asid 1"); - if (vm.num_cpus != 2) FAIL("Bad vm num_cpus"); - //if (c->vmcpu != 1) FAIL("Bad vmcpu"); /* EJP: now cpuidx field in id */ - if (vmcontext[1] != &c) FAIL("Bad vm context"); - if (c->vmblock != &vm) FAIL("Bad vmblock"); - - vm.num_cpus = 0; - /* should succeed */ - ret = H2K_thread_create_no_squash(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,6,&vm,&a); - if (ret == -1) FAIL("Unexpected error"); - - /* asid should come from vmblock->pmap when num_cpus == 0 */ - if (d.ssr_asid != asid) FAIL("Bad vm asid 2"); - - TH_saw_check_sanity = 0; - if (H2K_thread_create(((u32_t)test_thread),((u32_t)(&stack)),0xdeadbeef,2,0x0,&a) - != (u32_t)(&e)) FAIL("Failed to create expected thread"); - if (TH_saw_check_sanity == 0) FAIL("Did not call check_sanity"); - - if (H2K_thread_create((u32_t)test_thread,((u32_t)(&stack)),0xdeadbeef,2,0x0,&a) - != 0xffffffff) FAIL("Created thread w/o storage"); -#endif puts("TEST PASSED\n"); return 0; } diff --git a/kernel/thread/stop/stop.ref.c b/kernel/thread/stop/stop.ref.c index e77bfc2a4..e94bfa822 100644 --- a/kernel/thread/stop/stop.ref.c +++ b/kernel/thread/stop/stop.ref.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -30,7 +29,6 @@ void H2K_thread_stop_withlock(s32_t status, H2K_thread_context *me) H2K_vmblock_t *parent_vmblock; H2K_timer_cancel_withlock(me); - H2K_runlist_remove(me); H2K_asid_table_dec(me->ssr_asid); H2K_thread_context_clear(me); me->next = vmblock->free_threads; diff --git a/kernel/thread/stop/stop.spec b/kernel/thread/stop/stop.spec index 08cda9389..e85ff7378 100644 --- a/kernel/thread/stop/stop.spec +++ b/kernel/thread/stop/stop.spec @@ -59,14 +59,12 @@ is not ``H2K_STATUS_DEAD``. Else, when the vcpu count is 0, calls :c:func:`H2K_mem_alloc_release()` to mark the vmblock as freeable (will not be freed until we relinquish BKL). -Cancels associated timers and removes the current thread from the runlist. -Clears the thread context (which sets the valid field to DEAD), then -inserts the thread into the H2K_kg.free_threads list. +Cancels associated timers, clears the thread context (which sets the valid field to DEAD), +then inserts the thread into the H2K_kg.free_threads list. Finally, calls :c:func:`H2K_dosched()` to pick a new thread. The current thread is specified as NULL, rather than as the now-dead thread context -pointer. ``H2K_dosched()`` consumes the BKL (released by -``H2K_check_sanity_unlock`` at the tail of ``H2K_switch``). +pointer. ``H2K_dosched()`` consumes the BKL (released at the tail of ``H2K_switch``). @@ -90,10 +88,10 @@ Important cases Harness ~~~~~~~ -We link directly with the stop object file, and also the runlist object file. +We link directly with the stop object file. The test harness defines :c:func:`H2K_dosched()` to set a flag indicating that the dosched -routine was called. It also adds test threads correctly into the runlist. +routine was called. The test harness calls :c:func:`H2K_thread_stop()` with a thread context pointer. We check to make sure :c:func:`H2K_dosched()` was called, and that the thread was added to the diff --git a/kernel/thread/stop/test/Makefile b/kernel/thread/stop/test/Makefile index b9941862f..bd27facc5 100644 --- a/kernel/thread/stop/test/Makefile +++ b/kernel/thread/stop/test/Makefile @@ -1,12 +1,8 @@ STANDALONE=1 OBJS+=test.o -RECOMPILE_DIRS += $(H2DIR)/kernel/data/runlist RECOMPILE_DIRS += $(H2DIR)/kernel/data/readylist -RECOMPILE_DIRS += $(H2DIR)/kernel/sched/lowprio -RECOMPILE_SRCS_PREFS += runlist RECOMPILE_SRCS_PREFS += readylist -RECOMPILE_SRCS_PREFS += lowprio EXTRA_CFLAGS += -DTESTING EXTRA_ASFLAGS += -DTESTING diff --git a/kernel/thread/stop/test/test.c b/kernel/thread/stop/test/test.c index e1561ce53..f5a27172a 100644 --- a/kernel/thread/stop/test/test.c +++ b/kernel/thread/stop/test/test.c @@ -6,9 +6,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -75,9 +73,10 @@ int main() H2K_vmblock_t myblock; H2K_vmblock_t *vmblock = &myblock; __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - H2K_runlist_init(); H2K_readylist_init(); - H2K_lowprio_init(); +#if CLUSTER_SCHED + H2K_gp->wait_mask = 0; +#endif H2K_thread_init(); a.prio = 2; @@ -92,10 +91,6 @@ int main() //puts("C"); vmblock->free_threads = NULL; if (vmblock->free_threads != NULL) FAIL("free threads not clear"); - H2K_runlist_push(&a); - if (H2K_gp->runlist[a.hthread] != &a) FAIL("Thread not in expected place in runlist (0)"); - H2K_runlist_push(&b); - if (H2K_gp->runlist[b.hthread] != &b) FAIL("Thread not in expected place in runlist (1)"); TH_me = &a; a.prev = &a; TH_saw_dosched = 0; @@ -111,7 +106,6 @@ int main() //puts("h"); if (a.next != 0) FAIL("Free thread list incorrect"); //puts("i"); - if (H2K_gp->runlist[a.hthread] == &a) FAIL("Thread not removed from runlist"); //puts("B"); TH_saw_dosched = 0; TH_me = &b; @@ -121,12 +115,7 @@ int main() if (b.prev != 0) FAIL("thread not cleared"); if (vmblock->free_threads != &b) FAIL("free thread list incorrect"); if (b.next != &a) FAIL("Free thread list incorrect"); - if (H2K_gp->runlist[b.hthread] == &b) FAIL("Thread not removed from runlist"); - if (H2K_gp->runlist[a.hthread] != NULL) FAIL("Unexpected runlist"); - if (H2K_gp->runlist[b.hthread] != NULL) FAIL("Unexpected runlist"); puts("A"); - H2K_runlist_init(); - H2K_lowprio_init(); H2K_readylist_init(); H2K_thread_init(); a.prio = 2; @@ -134,12 +123,6 @@ int main() c.prio = 2; vmblock->free_threads = NULL; if (vmblock->free_threads != NULL) FAIL("free threads not clear"); - H2K_runlist_push(&a); - if (H2K_gp->runlist[a.hthread] != &a) FAIL("Thread not in expected place in runlist (2)"); - H2K_runlist_push(&b); - if (H2K_gp->runlist[b.hthread] != &b) FAIL("Thread not in expected place in runlist (3)"); - H2K_runlist_push(&c); - if (H2K_gp->runlist[c.hthread] != &c) FAIL("Thread not in expected place in runlist (4)"); TH_me = &a; a.prev = &a; TH_saw_dosched = 0; @@ -149,9 +132,7 @@ int main() if (a.prev != 0) FAIL("thread not cleared"); if (vmblock->free_threads != &a) FAIL("free thread list incorrect"); if (a.next != 0) FAIL("Free thread list incorrect"); - if (H2K_gp->runlist[a.hthread] == &a) FAIL("Thread not removed from runlist"); puts("TEST PASSED\n"); return 0; } - diff --git a/kernel/todo b/kernel/todo index c6a0a4293..5e8d7a6c4 100644 --- a/kernel/todo +++ b/kernel/todo @@ -136,9 +136,6 @@ Inside the Monitor: TBD: * How do we make "in_ready_queue(owner_context)" fast? - * How can we change prio and have thread still take itself out of - runlist efficiently? - * Change runlist? Caveats: * Futex_resume may not be right place to always change back prio diff --git a/kernel/traps/config/config.h b/kernel/traps/config/config.h index 3970f60d6..2c6d520b9 100644 --- a/kernel/traps/config/config.h +++ b/kernel/traps/config/config.h @@ -78,7 +78,7 @@ u32_t H2K_trap_config(config_type_t configtype, u32_t val1, u32_t val2, u32_t va u32_t H2K_trap_config_vmblock_init(u32_t unused, u32_t vm, u32_t op, u32_t arg1, u32_t arg2, H2K_thread_context *me) IN_SECTION(".text.config.config"); u32_t H2K_trap_config_stlb_alloc(u32_t unused, u32_t sets, u32_t unused2, u32_t unused3, u32_t unused4, H2K_thread_context *me) IN_SECTION(".text.config.config"); u32_t H2K_trap_config_fatal_hook(u32_t unused, u32_t funcaddr, u32_t arg, u32_t unused3, u32_t unused4, H2K_thread_context *me) IN_SECTION(".text.config.config"); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED u32_t H2K_trap_config_cluster_sched(u32_t unused, u32_t enable, u32_t unused2, u32_t unused3, u32_t unused4, H2K_thread_context *me) IN_SECTION(".text.config.config"); #endif u32_t H2K_trap_config_noc(u32_t unused, u32_t master, u32_t slave, u32_t unused3, u32_t unused4, H2K_thread_context *me) IN_SECTION(".text.config.config"); diff --git a/kernel/traps/config/config.ref.c b/kernel/traps/config/config.ref.c index 34157434f..96437fa28 100644 --- a/kernel/traps/config/config.ref.c +++ b/kernel/traps/config/config.ref.c @@ -31,7 +31,7 @@ static const configptr_t H2K_configtab[CONFIG_MAX] IN_SECTION(".data.config.conf H2K_trap_config_vmblock_init, H2K_trap_config_stlb_alloc, H2K_trap_config_fatal_hook, -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED H2K_trap_config_cluster_sched, #endif H2K_trap_config_noc @@ -305,7 +305,7 @@ u32_t H2K_trap_config_stlb_alloc(u32_t unused, u32_t sets, u32_t unused2, u32_t return H2K_mem_stlb_alloc(); } -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED u32_t H2K_trap_config_cluster_sched(u32_t unused, u32_t enable, u32_t unused2, u32_t unused3, u32_t unused4, H2K_thread_context *me) { H2K_gp->cluster_sched = enable; diff --git a/kernel/traps/hwconfig/hwconfig.ref.c b/kernel/traps/hwconfig/hwconfig.ref.c index 665dd8d5a..984b2e6fc 100644 --- a/kernel/traps/hwconfig/hwconfig.ref.c +++ b/kernel/traps/hwconfig/hwconfig.ref.c @@ -23,9 +23,8 @@ #include #include -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED #include -#include #include #endif @@ -268,7 +267,7 @@ u32_t H2K_trap_hwconfig_coproc_bits(u32_t unused, void *unusedp, u32_t coproc, u32_t H2K_trap_hwconfig_hlxbits(u32_t unused, void *unusedp, u32_t xa3, u32_t xe3, H2K_thread_context *me) { #if (ARCHV >= 81 && defined(HMX_HLX_SUPPORT)) if (0 < H2K_gp->hlx_contexts) { // exists -# ifdef CLUSTER_SCHED +# if CLUSTER_SCHED if (H2K_gp->cluster_sched) { BKL_LOCK(); if (xe3 && !(me->ccr & CCR_XE3_BIT_MASK)) { // turning xe3 on @@ -277,7 +276,6 @@ u32_t H2K_trap_hwconfig_hlxbits(u32_t unused, void *unusedp, u32_t xa3, u32_t x me->ccr = Q6_R_insert_RII(me->ccr, xa3, CCR_XA3_NBITS, CCR_XA3_BITS); me->ccr = Q6_R_insert_RII(me->ccr, xe3, 1, CCR_XE3_BIT); me->r00 = 0; - H2K_runlist_remove(me); H2K_ready_append(me); H2K_dosched(me, me->hthread); } @@ -304,7 +302,7 @@ u32_t H2K_trap_hwconfig_hlxbits(u32_t unused, void *unusedp, u32_t xa3, u32_t x u32_t H2K_trap_hwconfig_hmxbits(u32_t unused, void *unusedp, u32_t xe2, u32_t unused3, H2K_thread_context *me) { #if (ARCHV >= 68 && defined(HMX_HLX_SUPPORT)) if (0 < H2K_gp->hmx_units) { // exists -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED if (H2K_gp->cluster_sched) { BKL_LOCK(); if (xe2 && !(me->ssr & SSR_XE2_BIT_MASK)) { // turning xe2 on @@ -313,7 +311,6 @@ u32_t H2K_trap_hwconfig_hmxbits(u32_t unused, void *unusedp, u32_t xe2, u32_t un // me->ccr = Q6_R_insert_RII(me->ccr, xa2, CCR_XA2_NBITS, CCR_XA2_BITS); me->ssr = Q6_R_insert_RII(me->ssr, xe2, 1, SSR_XE2_BIT); me->r00 = 0; - H2K_runlist_remove(me); H2K_ready_append(me); H2K_dosched(me, me->hthread); } @@ -341,7 +338,7 @@ u32_t H2K_trap_hwconfig_extbits(u32_t unused, void *unusedp, u32_t xa, u32_t xe, /* FIXME: should check for allowed XA values here (maybe?) */ /* EJP: Always allow XE/XA to be set if only for silver tests working also */ -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED if (H2K_gp->cluster_sched) { BKL_LOCK(); if (xe && !(me->ssr & SSR_XE_BIT_MASK)) { // turning xe on @@ -359,7 +356,6 @@ u32_t H2K_trap_hwconfig_extbits(u32_t unused, void *unusedp, u32_t xa, u32_t xe, } /* else (when in hvx range and do_ext) kernel is managing xa/xe, so do nothing here */ me->r00 = 0; - H2K_runlist_remove(me); H2K_ready_append(me); H2K_dosched(me, me->hthread); } @@ -564,7 +560,7 @@ u32_t H2K_trap_hwconfig_hwthreads_mask(u32_t unused, void *unusedp, u32_t mask, H2K_gp->hthreads_mask &= MODECTL_E_MASK; H2K_gp->hthreads = Q6_R_popcount_P(H2K_gp->hthreads_mask); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED H2K_cluster_config(); #endif return H2K_gp->hthreads_mask; @@ -603,7 +599,7 @@ u32_t H2K_trap_hwconfig_hwthreads_num(u32_t unused, void *unusedp, u32_t num, u3 H2K_gp->hthreads_mask &= MODECTL_E_MASK; H2K_gp->hthreads = Q6_R_popcount_P(H2K_gp->hthreads_mask); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED H2K_cluster_config(); #endif return H2K_gp->hthreads; diff --git a/kernel/traps/info/info.ref.c b/kernel/traps/info/info.ref.c index a8bd4492c..5780fe5b8 100644 --- a/kernel/traps/info/info.ref.c +++ b/kernel/traps/info/info.ref.c @@ -147,7 +147,7 @@ u32_t H2K_trap_info(info_type op, u32_t unit, h2_cfg_unit_entry entry, H2K_threa return 0; } case INFO_MAX_CLUSTER_COPROC: -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED return H2K_gp->coproc_max; #else return H2K_gp->coproc_contexts; diff --git a/kernel/traps/prio/prio.ref.c b/kernel/traps/prio/prio.ref.c index 47d65df3a..e5fd791a9 100644 --- a/kernel/traps/prio/prio.ref.c +++ b/kernel/traps/prio/prio.ref.c @@ -4,27 +4,10 @@ */ #include -#include #include #include -#if 0 -s32_t H2K_prio_set(H2K_thread_context *dest, u32_t prio, H2K_thread_context *me) -{ - s32_t ret; - if (prio > MAX_PRIO) prio = MAX_PRIO; - if (dest == me) { - H2K_runlist_remove(me); - ret = me->prio; - me->prio = prio; - H2K_runlist_push(me); - } else { - /* UNIMPLEMENTED */ - ret = -1; - } - return ret; -} -#else + s32_t H2K_prio_set(H2K_thread_context *dest, u32_t prio, H2K_thread_context *me) { s32_t ret = me->base_prio; @@ -33,7 +16,6 @@ s32_t H2K_prio_set(H2K_thread_context *dest, u32_t prio, H2K_thread_context *me) me->base_prio = (u8_t)prio; return ret; } -#endif u32_t H2K_prio_get(unsigned int threadid_in, H2K_thread_context *me) { diff --git a/kernel/traps/prio/test/test.c b/kernel/traps/prio/test/test.c index 5c6ccb506..d2a9dddc4 100644 --- a/kernel/traps/prio/test/test.c +++ b/kernel/traps/prio/test/test.c @@ -24,7 +24,7 @@ int main() { u32_t i; __asm__ __volatile(GLOBAL_REG_STR " = %0 " : : "r"(&H2K_kg)); - for (i = 0; i < MAX_PRIOS; i++) { + for (i = 0; i <= MAX_PRIO; i++) { a.base_prio = i; if (H2K_prio_get(0,&a) != i) FAIL("prio_get"); } @@ -32,12 +32,14 @@ int main() H2K_prio_set(&a,0,&a); if (a.base_prio != 0) FAIL("prio_set_null"); a.vmblock = &vmblock; - for (i = 0; i < MAX_PRIOS-1; i++) { - a.vmblock->bestprio = i+1; + for (i = 0; i <= MAX_PRIO; i++) { + a.vmblock->bestprio = i; H2K_prio_set(&a,a.vmblock->bestprio,&a); if (a.base_prio != a.vmblock->bestprio) FAIL("prio_set_mid"); } - if (H2K_prio_set(&a,MAX_PRIOS,&a) != -1) FAIL("prio_set_limit"); + for (i = MAX_PRIO + 1; i <= MAX_PRIOS; i++) { + if(H2K_prio_set(&a,i,&a) != -1) FAIL("prio_set_limit"); + } puts("TEST PASSED\n"); return 0; } diff --git a/kernel/util/hw/hw.h b/kernel/util/hw/hw.h index bdcc6b5cb..61c875b8d 100644 --- a/kernel/util/hw/hw.h +++ b/kernel/util/hw/hw.h @@ -56,6 +56,11 @@ static inline u32_t get_imask(u32_t thread) return imask; } +static inline void set_thread_stid_prio(u32_t thread, u32_t prio) +{ + asm volatile (" p0 = %0\n setprio(p0,%1); isync;" : : "r"(thread),"r"(prio):"p0"); +} + static inline void iassignw(u32_t intno, u32_t threadmask) { asm(" iassignw(%0)" : : "r"(Q6_R_combine_RlRl(intno,threadmask))); @@ -95,29 +100,6 @@ static inline void cluster_resched_int() asm(" swi(%0) // cluster resched" : : "r"(CLUSTER_RESCHED_INT_INTMASK)); } -#if (ARCHV <= 2) -static inline void highprio_imask(u32_t hthread) -{ - asm(" imask = %0 // set to high priority " : : "r"((-1)-(HW_TH_0_INTMASK << (hthread)))); -} - -static inline void lowprio_imask(u32_t hthread) -{ - asm(" imask = %0 // set to low priority " : : "r"(HW_TH_ALL_INTMASK ^ (HW_TH_0_INTMASK << (hthread)))); -} -#elif (ARCHV >= 3) -static inline void highprio_imask(u32_t hthread) -{ - asm(" imask = %0 // set to high priority " : : "r"(-1)); -} - -static inline void lowprio_imask(u32_t hthread) -{ - asm(" imask = %0 // set to low priority " : : "r"(0)); -} - -#endif - static inline u32_t H2K_get_ssr() { u32_t ret; @@ -501,6 +483,30 @@ static inline void H2K_dmcfgwr(u32_t index, u32_t data) { asm volatile ("dmcfgwr(%0, %1);" : : "r" (index), "r" (data)); } + +static inline u32_t H2K_get_bestwait() +{ + u32_t ret; + asm volatile ("%0 = bestwait; \n" : "=r" (ret)); + return(ret); +} + +static inline void H2K_set_bestwait(u32_t priority_mask) +{ + asm volatile (" bestwait = %0; \n" : : "r" (priority_mask)); +} + +static inline u32_t H2K_get_schedcfg() +{ + u32_t ret; + asm volatile ("%0 = schedcfg; \n" : "=r" (ret)); + return(ret); +} + +static inline void H2K_set_schedcfg(u32_t val) +{ + asm volatile (" schedcfg = %0; \n" : : "r" (val)); +} #endif void H2K_start_threads(unsigned int mask); diff --git a/kernel/util/hw/hw.spec b/kernel/util/hw/hw.spec index 60920d84f..a3c4ef84d 100644 --- a/kernel/util/hw/hw.spec +++ b/kernel/util/hw/hw.spec @@ -248,4 +248,63 @@ Description This function retrieves clears the contents of the IPEND status register. +H2K_get_bestwait +---------------- + +.. c:function:: static inline u32_t H2K_get_bestwait() + +Description +~~~~~~~~~~~ + +This function retrieves the contents of the BESTWAIT register. The hardware +resets BESTWAIT to 0x1FF after it raises the reschedule interrupt, so reading it +back indicates whether the hardware has already fired since it was last +programmed. See the hardware reschedule interrupt. + + +H2K_set_bestwait +---------------- + +.. c:function:: static inline void H2K_set_bestwait(u32_t priority_mask) + + :param priority_mask: Priority value to program into BESTWAIT + +Description +~~~~~~~~~~~ + +This function programs the BESTWAIT register with the priority of the highest +priority task waiting to run. The hardware raises the reschedule interrupt when +any hardware thread's effective STID.PRIO is worse than this value. See the +hardware reschedule interrupt in conjunction with the SCHEDCFG register. + + +H2K_get_schedcfg +---------------- + +.. c:function:: static inline u32_t H2K_get_schedcfg() + +Description +~~~~~~~~~~~ + +This function retrieves the contents of the SCHEDCFG register, which configures +the hardware reschedule interrupt feature (SCHEDCFG.EN enables it, SCHEDCFG.INTNO +selects the interrupt raised). + + +H2K_set_schedcfg +---------------- + +.. c:function:: static inline void H2K_set_schedcfg(u32_t val) + + :param val: Value to write to the SCHEDCFG register + +Description +~~~~~~~~~~~ + +This function writes the SCHEDCFG register, used to enable the hardware +reschedule interrupt feature and select which interrupt it raises. See the +hardware reschedule interrupt in conjunction with the BESTWAIT register. + + + diff --git a/kernel/util/max/max.h b/kernel/util/max/max.h index 3a27fab04..e09f5ced9 100644 --- a/kernel/util/max/max.h +++ b/kernel/util/max/max.h @@ -76,9 +76,15 @@ #endif #define MAX_PRIOS 256 -#define MAX_PRIO ((MAX_PRIOS) - 1) +#define WAITING_PRIO ((MAX_PRIOS) - 1) +#define MAX_PRIO ((MAX_PRIOS) - 2) #define BEST_PRIO 0 +#define BESTWAIT_MASK 0x1ff + +#define SCHEDCFG_EN (1u << 8) +#define SCHEDCFG_INTNO(n) ((n) & 0xf) + #if ARCHV <= 3 #define ASID_BITS 5 #else diff --git a/kernel/util/stmode/test/test.c b/kernel/util/stmode/test/test.c index cd4160e9f..900a47acf 100644 --- a/kernel/util/stmode/test/test.c +++ b/kernel/util/stmode/test/test.c @@ -109,8 +109,9 @@ IN_SECTION(".text.misc.create") s32_t H2K_thread_create_no_squash(u32_t pc, u32_ vmblock->num_cpus++; tmp->vmblock = vmblock; - H2K_ready_append(tmp); - return (s32_t)H2K_check_sanity_unlock(H2K_id_from_context(tmp).raw); + H2K_ready_append_arm(tmp); + BKL_UNLOCK(); + return (s32_t)H2K_id_from_context(tmp).raw; } void FAIL(const char *str) diff --git a/kernel/vm/vmcache/vmcache.ref.c b/kernel/vm/vmcache/vmcache.ref.c index ba37816fd..e777332c2 100644 --- a/kernel/vm/vmcache/vmcache.ref.c +++ b/kernel/vm/vmcache/vmcache.ref.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/kernel/vm/vmfuncs/test/test.c b/kernel/vm/vmfuncs/test/test.c index bd0bae517..df16b1a87 100644 --- a/kernel/vm/vmfuncs/test/test.c +++ b/kernel/vm/vmfuncs/test/test.c @@ -248,8 +248,6 @@ int main() a.vmblock = &av; av.waiting_cpus = 0; a.id.cpuidx = 5; - H2K_kg.runlist[0] = &a; - H2K_kg.runlist_prios[0] = 4; a.status = 0; TH_expected_dosched = 1; if (setjmp(env) == 0) H2K_vmtrap_wait(&a); @@ -257,8 +255,6 @@ int main() if (a.r00 != -1) FAIL("r00 clobbered"); if (av.waiting_cpus != (1<<5)) FAIL("wrong waiting cpus"); if (a.status != H2K_STATUS_VMWAIT) FAIL("wrong status"); - if (H2K_kg.runlist[0] != NULL) FAIL("runlist"); - if (H2K_kg.runlist_prios[0] != -1) FAIL("runlist_prios"); /* RETURN */ diff --git a/kernel/vm/vmfuncs/vmfuncs.ref.c b/kernel/vm/vmfuncs/vmfuncs.ref.c index 520017f1d..56d6f76e0 100644 --- a/kernel/vm/vmfuncs/vmfuncs.ref.c +++ b/kernel/vm/vmfuncs/vmfuncs.ref.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -122,7 +121,6 @@ void H2K_vmtrap_wait(H2K_thread_context *me) if (me->id.cpuidx < sizeof(long_bitmask_t) * 8) { me->vmblock->waiting_cpus |= (0x1 << me->id.cpuidx); } - H2K_runlist_remove(me); H2K_dosched(me,me->hthread); } else { /* Interrupt pending; either it was taken or interrupts are disabled. In diff --git a/kernel/vm/vmint/test/test.c b/kernel/vm/vmint/test/test.c index 134c6897d..68e49ad82 100644 --- a/kernel/vm/vmint/test/test.c +++ b/kernel/vm/vmint/test/test.c @@ -119,24 +119,6 @@ void H2K_vm_event(u32_t x, u32_t cause, u32_t offset, H2K_thread_context *me) TH_saw_event = 1; } -u32_t TH_expected_sanity = 0; -u32_t TH_saw_sanity = 0; - -u64_t H2K_check_sanity_unlock(u64_t ret) -{ - if (TH_expected_sanity == 0) FAIL("Didn't expect sanity"); - TH_saw_sanity = 1; - BKL_UNLOCK(); - return ret; -} - -u64_t H2K_check_sanity(u64_t ret) -{ - if (TH_expected_sanity == 0) FAIL("Didn't expect sanity"); - TH_saw_sanity = 1; - return ret; -} - u32_t TH_expected_popup_cancel = 0; u32_t TH_saw_popup_cancel = 0; void H2K_popup_cancel(H2K_thread_context *me) @@ -324,14 +306,10 @@ int main() puts("B"); t0->vmstatus = 0; t0->status = H2K_STATUS_VMWAIT; - TH_expected_sanity = 1; ret = H2K_vm_int_deliver(&TH_vmblock,t0,0); if (ret != 0) FAIL("error code"); if (t0->status != H2K_STATUS_READY) FAIL("status"); if (t0->vmstatus != 0) FAIL("vmstatus"); - if (TH_saw_sanity != 1) FAIL("no sanity check"); - TH_saw_sanity = 0; - TH_expected_sanity = 0; puts("C"); @@ -373,7 +351,6 @@ int main() t0->vmstatus = H2K_VMSTATUS_IE; t0->status = H2K_STATUS_INTBLOCKED; TH_expected_popup_cancel = 1; - TH_expected_sanity = 1; ret = H2K_vm_int_deliver(&TH_vmblock,t0,0); if (ret != 0) FAIL("error code"); if (t0->status != H2K_STATUS_READY) FAIL("status"); @@ -381,10 +358,6 @@ int main() if (TH_saw_popup_cancel != 1) FAIL("Didn't see popup cancel"); TH_expected_popup_cancel = 0; TH_saw_popup_cancel = 0; - if (TH_saw_sanity != 1) FAIL("no sanity check"); - TH_saw_sanity = 0; - TH_expected_sanity = 0; - puts("G"); t0->vmstatus = 0; @@ -403,7 +376,6 @@ int main() t0->vmstatus = H2K_VMSTATUS_IE; t0->status = H2K_STATUS_BLOCKED; TH_expected_futex_cancel = 1; - TH_expected_sanity = 1; ret = H2K_vm_int_deliver(&TH_vmblock,t0,0); if (ret != 0) FAIL("error code"); if (t0->status != H2K_STATUS_READY) FAIL("status"); @@ -411,9 +383,6 @@ int main() if (TH_saw_futex_cancel != 1) FAIL("Didn't see popup cancel"); TH_expected_futex_cancel = 0; TH_saw_futex_cancel = 0; - if (TH_saw_sanity != 1) FAIL("no sanity check"); - TH_saw_sanity = 0; - TH_expected_sanity = 0; puts("I"); diff --git a/kernel/vm/vmint/vmint.ref.c b/kernel/vm/vmint/vmint.ref.c index 8728c7c5e..583401f40 100644 --- a/kernel/vm/vmint/vmint.ref.c +++ b/kernel/vm/vmint/vmint.ref.c @@ -34,8 +34,7 @@ s32_t H2K_vm_int_deliver_locked(H2K_vmblock_t *vmblock, H2K_thread_context *thre } thread->r00 = intno; enqueue: - H2K_ready_append(thread); - H2K_check_sanity(0); + H2K_ready_append_arm(thread); return 0; case H2K_STATUS_RUNNING: if (thread->atomic_status_word & H2K_VMSTATUS_IE) { diff --git a/kernel/vm/vmmap/vmmap.ref.c b/kernel/vm/vmmap/vmmap.ref.c index 5705172d1..a34c78572 100644 --- a/kernel/vm/vmmap/vmmap.ref.c +++ b/kernel/vm/vmmap/vmmap.ref.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/kernel/vm/vmop/test/test.c b/kernel/vm/vmop/test/test.c index a5fef8d9a..402310291 100644 --- a/kernel/vm/vmop/test/test.c +++ b/kernel/vm/vmop/test/test.c @@ -66,9 +66,6 @@ void H2K_futex_cancel(H2K_thread_context *t) TH_saw_futex_cancel = 1; } -u64_t H2K_check_sanity(u64_t r) { return r; } -u64_t H2K_check_sanity_unlock(u64_t r) { return r; } - static void TH_init_block(H2K_vmblock_t *blk, u32_t vmidx, u32_t parent_vmidx, H2K_thread_context *ctx) { diff --git a/kernel/vm/vmop/vmop.ref.c b/kernel/vm/vmop/vmop.ref.c index 3da9bff2d..20b924bf1 100644 --- a/kernel/vm/vmop/vmop.ref.c +++ b/kernel/vm/vmop/vmop.ref.c @@ -117,18 +117,18 @@ static void kill_thread_locked(H2K_vmblock_t *vmblock, H2K_thread_context *targe if (target->id.cpuidx < bits(long_bitmask_t)) { vmblock->waiting_cpus &= ~(0x1ULL << target->id.cpuidx); } - H2K_ready_append(target); + H2K_ready_append_arm(target); break; case H2K_STATUS_RUNNING: H2K_vm_ipi_send_withlock(target); break; case H2K_STATUS_INTBLOCKED: H2K_popup_cancel(target); - H2K_ready_append(target); + H2K_ready_append_arm(target); break; case H2K_STATUS_BLOCKED: H2K_futex_cancel(target); - H2K_ready_append(target); + H2K_ready_append_arm(target); break; case H2K_STATUS_READY: break; diff --git a/kernel/vm/vmwork/vmwork.spec b/kernel/vm/vmwork/vmwork.spec index a5dc8aa07..d840ad1c9 100644 --- a/kernel/vm/vmwork/vmwork.spec +++ b/kernel/vm/vmwork/vmwork.spec @@ -18,8 +18,8 @@ Description Handles deferred VM work for the current thread. The BKL must be held by the caller. Notable callers include the deferred-work hook in -``H2K_switch`` (between :c:func:`H2K_dosched()` and -``H2K_check_sanity_unlock``), :c:func:`H2K_vmtrap_vmwait()`, and +``H2K_switch`` (between :c:func:`H2K_dosched()` and BKL_UNLOCK()), +:c:func:`H2K_vmtrap_vmwait()`, and :c:func:`H2K_vm_ipi_do()`. INPUT_ASSERT(kernel_locked) diff --git a/libs/h2/common/h2_common_config.h b/libs/h2/common/h2_common_config.h index fc7f21589..5dc719219 100644 --- a/libs/h2/common/h2_common_config.h +++ b/libs/h2/common/h2_common_config.h @@ -14,7 +14,7 @@ typedef enum { CONFIG_VMBLOCK_INIT, CONFIG_STLB_ALLOC, CONFIG_FATAL_HOOK, -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED CONFIG_CLUSTER_SCHED, #endif CONFIG_NOC, // FIXME: hack for setting noc table addresses diff --git a/libs/h2/config/h2_config.h b/libs/h2/config/h2_config.h index 23975f0ac..ce1226a9b 100644 --- a/libs/h2/config/h2_config.h +++ b/libs/h2/config/h2_config.h @@ -54,7 +54,7 @@ int h2_config_stlb_alloc(void); int h2_config_fatal_hook(unsigned int funcaddr, unsigned int arg); -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED int h2_config_cluster_sched(unsigned int enable); #endif diff --git a/libs/h2/config/h2_config_imp.ref.c b/libs/h2/config/h2_config_imp.ref.c index 31eebf92d..2700352c5 100644 --- a/libs/h2/config/h2_config_imp.ref.c +++ b/libs/h2/config/h2_config_imp.ref.c @@ -23,7 +23,7 @@ int h2_config_fatal_hook(unsigned int funcaddr, unsigned int arg) return h2_config_trap(CONFIG_FATAL_HOOK,funcaddr,arg,0,0); } -#ifdef CLUSTER_SCHED +#if CLUSTER_SCHED int h2_config_cluster_sched(unsigned int enable) { return h2_config_trap(CONFIG_CLUSTER_SCHED, enable, 0, 0, 0); diff --git a/scripts/testlist.v4 b/scripts/testlist.v4 index ef7e7e6ba..03c39927e 100644 --- a/scripts/testlist.v4 +++ b/scripts/testlist.v4 @@ -1,7 +1,6 @@ ./kernel/data/intconfig/test ./kernel/data/context/test ./kernel/data/readylist/test -./kernel/data/runlist/test ./kernel/data/thread/test ./kernel/error/fatal/test ./kernel/event/error/test diff --git a/scripts/testlist.v61 b/scripts/testlist.v61 index b489fe7cf..6df3a07b4 100644 --- a/scripts/testlist.v61 +++ b/scripts/testlist.v61 @@ -1,7 +1,5 @@ ./kernel/data/intconfig/test ./kernel/data/context/test -./kernel/data/readylist/test -./kernel/data/runlist/test ./kernel/data/thread/test ./kernel/error/fatal/test ./kernel/event/error/test @@ -33,7 +31,6 @@ ./kernel/power/apcr/test_multi ./kernel/power/hvx/test ./kernel/power/apcr/simple_test -./kernel/sched/check_sanity/test/tests/H2K_check_sanity/scenarios ./kernel/sched/dosched/test/test ./kernel/futex/futex/test/tests/badaccess ./kernel/futex/futex/test/tests/find_match @@ -41,7 +38,8 @@ ./kernel/futex/futex/test/tests/multi_wake ./kernel/futex/futex/test/tests/pi ./kernel/futex/futex/test/tests/simple_lock_unlock -./kernel/sched/lowprio/test +./kernel/data/readylist/tests/H2K_bestwait +./kernel/data/readylist/tests/readylist ./kernel/sched/resched/test ./kernel/sched/switch/test ./kernel/sched/yield/test @@ -138,4 +136,4 @@ ./perf/myid ./perf/pingpong ./perf/mutex -./perf/mutex2 +./perf/mutex2 \ No newline at end of file