QP/C
qk_sched.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Product: QK/C
00003 * Last Updated for Version: 4.4.00
00004 * Date of the Last Update:  Jan 04, 2012
00005 *
00006 *                    Q u a n t u m     L e a P s
00007 *                    ---------------------------
00008 *                    innovating embedded systems
00009 *
00010 * Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
00011 *
00012 * This software may be distributed and modified under the terms of the GNU
00013 * General Public License version 2 (GPL) as published by the Free Software
00014 * Foundation and appearing in the file GPL.TXT included in the packaging of
00015 * this file. Please note that GPL Section 2[b] requires that all works based
00016 * on this software must also be made publicly available under the terms of
00017 * the GPL ("Copyleft").
00018 *
00019 * Alternatively, this software may be distributed and modified under the
00020 * terms of Quantum Leaps commercial licenses, which expressly supersede
00021 * the GPL and are specifically designed for licensees interested in
00022 * retaining the proprietary status of their code.
00023 *
00024 * Contact information:
00025 * Quantum Leaps Web site:  http://www.quantum-leaps.com
00026 * e-mail:                  info@quantum-leaps.com
00027 *****************************************************************************/
00028 #include "qk_pkg.h"
00029 /*#include "qassert.h"*/
00030 
00031 /*Q_DEFINE_THIS_MODULE("qk_sched")*/
00032 
00039 /*..........................................................................*/
00040 /* NOTE: the QK scheduler is entered and exited with interrupts LOCKED      */
00041 void QK_sched_(uint8_t p) {
00042     uint8_t pin = QK_currPrio_;                /* save the initial priority */
00043     QActive *a;
00044 #ifdef QK_TLS                                 /* thread-local storage used? */
00045     uint8_t pprev = pin;
00046 #endif
00047     do {
00048         QEvent const *e;
00049         a = QF_active_[p];                  /* obtain the pointer to the AO */
00050 
00051         QK_currPrio_ = p;         /* this becomes the current task priority */
00052 
00053 #ifdef QK_TLS                                 /* thread-local storage used? */
00054         if (p != pprev) {                       /* are we changing threads? */
00055             QK_TLS(a);                   /* switch new thread-local storage */
00056             pprev = p;
00057         }
00058 #endif
00059         QS_BEGIN_NOCRIT_(QS_QK_SCHEDULE, QS_aoObj_, a)
00060             QS_TIME_();                                        /* timestamp */
00061             QS_U8_(p);                            /* the priority of the AO */
00062             QS_U8_(pin);                          /* the preempted priority */
00063         QS_END_NOCRIT_()
00064 
00065         QF_INT_ENABLE();               /* unconditionally enable interrupts */
00066 
00067         e = QActive_get_(a);              /* get the next event for this AO */
00068         QF_ACTIVE_DISPATCH_(&a->super, e);            /* dispatch to the AO */
00069         QF_gc(e);                /* garbage collect the event, if necessary */
00070 
00071         QF_INT_DISABLE();                             /* disable interrupts */
00072 
00073 #if (QF_MAX_ACTIVE <= 8)  /* determine the highest-priority AO ready to run */
00074         QPSet8_findMax(&QK_readySet_, p);
00075 #else
00076         QPSet64_findMax(&QK_readySet_, p);
00077 #endif
00078 
00079 #ifdef QK_NO_MUTEX
00080     } while (p > pin);          /* is the new priority higher than initial? */
00081 #else                                /* QK priority-ceiling mutexes allowed */
00082     } while ((p > pin) && (p > QK_ceilingPrio_));
00083 #endif
00084 
00085     QK_currPrio_ = pin;                     /* restore the initial priority */
00086 
00087 #ifdef QK_TLS                                 /* thread-local storage used? */
00088     if (pin != (uint8_t)0) {       /* no extended context for the idle loop */
00089         a = QF_active_[pin];             /* the pointer to the preempted AO */
00090         QK_TLS(a);                              /* restore the original TLS */
00091     }
00092 #endif
00093 }