1 /* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7 #include <api/failures.h> 8 #include <model/preemption.h> 9 #include <model/statedata.h> 10 #include <plat/machine/hardware.h> 11 #include <config.h> 12 13 /* 14 * Possibly preempt the current thread to allow an interrupt to be handled. 15 */ preemptionPoint(void)16exception_t preemptionPoint(void) 17 { 18 /* Record that we have performed some work. */ 19 ksWorkUnitsCompleted++; 20 21 /* 22 * If we have performed a non-trivial amount of work since last time we 23 * checked for preemption, and there is an interrupt pending, handle the 24 * interrupt. 25 * 26 * We avoid checking for pending IRQs every call, as our callers tend to 27 * call us in a tight loop and checking for pending IRQs can be quite slow. 28 */ 29 if (ksWorkUnitsCompleted >= CONFIG_MAX_NUM_WORK_UNITS_PER_PREEMPTION) { 30 ksWorkUnitsCompleted = 0; 31 #ifdef CONFIG_KERNEL_MCS 32 updateTimestamp(); 33 if (!(sc_active(NODE_STATE(ksCurSC)) && refill_sufficient(NODE_STATE(ksCurSC), NODE_STATE(ksConsumed))) 34 || isCurDomainExpired() || isIRQPending()) { 35 #else 36 if (isIRQPending()) { 37 #endif 38 return EXCEPTION_PREEMPTED; 39 } 40 } 41 42 return EXCEPTION_NONE; 43 } 44 45