1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * This software may be distributed and modified according to the terms of
5 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
6 * See "LICENSE_GPLv2.txt" for details.
7 *
8 * @TAG(GD_GPL)
9 */
10
11#include <api/failures.h>
12#include <model/preemption.h>
13#include <model/statedata.h>
14#include <plat/machine/hardware.h>
15#include <config.h>
16
17/*
18 * Possibly preempt the current thread to allow an interrupt to be handled.
19 */
20exception_t
21preemptionPoint(void)
22{
23    /* Record that we have performed some work. */
24    ksWorkUnitsCompleted++;
25
26    /*
27     * If we have performed a non-trivial amount of work since last time we
28     * checked for preemption, and there is an interrupt pending, handle the
29     * interrupt.
30     *
31     * We avoid checking for pending IRQs every call, as our callers tend to
32     * call us in a tight loop and checking for pending IRQs can be quite slow.
33     */
34    if (ksWorkUnitsCompleted >= CONFIG_MAX_NUM_WORK_UNITS_PER_PREEMPTION) {
35        ksWorkUnitsCompleted = 0;
36        if (isIRQPending()) {
37            return EXCEPTION_PREEMPTED;
38        }
39    }
40
41    return EXCEPTION_NONE;
42}
43
44