Global variables consolidation.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6116 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2013-08-10 08:07:43 +00:00
parent 16712a7883
commit c3dc5598c3
10 changed files with 205 additions and 133 deletions

View File

@ -100,9 +100,9 @@
#endif
/** @} */
/* Forward declaration of the thread structure, it is used in most
modules.*/
/* Forward declarations.*/
typedef struct thread thread_t;
typedef struct virtual_timer virtual_timer_t;
/* Inclusion of all the kernel sub-headers.*/
#include "chconf.h"
@ -111,6 +111,7 @@ typedef struct thread thread_t;
#include "chcore.h"
#include "chtm.h"
#include "chstats.h"
#include "chglobal.h"
#include "chsys.h"
#include "chvt.h"
#include "chthreads.h"

View File

@ -0,0 +1,143 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012,2013 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file chglobal.h
* @brief Data structures with global scope header.
*
* @addtogroup global
*/
#ifndef _CHGLOBAL_H_
#define _CHGLOBAL_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief Generic threads single link list, it works like a stack.
*/
typedef struct {
thread_t *p_next; /**< @brief Next in the list/queue. */
} threads_list_t;
/**
* @extends threads_list_t
*
* @brief Generic threads bidirectional linked list header and element.
*/
typedef struct {
thread_t *p_next; /**< @brief Next in the list/queue. */
thread_t *p_prev; /**< @brief Previous in the queue. */
} threads_queue_t;
/**
* @extends threads_queue_t
*
* @brief Ready list header.
*/
typedef struct {
threads_queue_t r_queue; /**< @brief Threads queue. */
tprio_t r_prio; /**< @brief This field must be
initialized to zero. */
struct context r_ctx; /**< @brief Not used, present because
offsets. */
#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__)
thread_t *r_newer; /**< @brief Newer registry element. */
thread_t *r_older; /**< @brief Older registry element. */
#endif
/* End of the fields shared with the thread_t structure.*/
thread_t *r_current; /**< @brief The currently running
thread. */
} ready_list_t;
/**
* @brief Virtual timers list header.
* @note The timers list is implemented as a double link bidirectional list
* in order to make the unlink time constant, the reset of a virtual
* timer is often used in the code.
*/
typedef struct {
virtual_timer_t *vt_next; /**< @brief Next timer in the delta
list. */
virtual_timer_t *vt_prev; /**< @brief Last timer in the delta
list. */
systime_t vt_delta; /**< @brief Must be initialized to -1. */
#if CH_CFG_TIMEDELTA == 0 || defined(__DOXYGEN__)
volatile systime_t vt_systime; /**< @brief System Time counter. */
#endif
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
/**
* @brief System time of the last tick event.
*/
systime_t vt_lasttime;/**< @brief System time of the last
tick event. */
#endif
} virtual_timers_list_t;
/**
* @brief System data structure.
* @note This structure contain all the data areas used by the OS except
* stacks.
*/
typedef struct ch_system {
/**
* @brief Ready list header.
*/
ready_list_t rlist;
/**
* @brief Virtual timers delta list header.
*/
virtual_timers_list_t vtlist;
} ch_system_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
extern ch_system_t ch;
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
#endif /* _CHGLOBAL_H_ */
/** @} */

View File

@ -95,9 +95,9 @@ typedef struct {
* @param[in] tp thread to add to the registry
*/
#define REG_INSERT(tp) { \
(tp)->p_newer = (thread_t *)&rlist; \
(tp)->p_older = rlist.r_older; \
(tp)->p_older->p_newer = rlist.r_older = (tp); \
(tp)->p_newer = (thread_t *)&ch.rlist; \
(tp)->p_older = ch.rlist.r_older; \
(tp)->p_older->p_newer = ch.rlist.r_older = (tp); \
}
/*===========================================================================*/

View File

@ -87,26 +87,6 @@
/* Module data structures and types. */
/*===========================================================================*/
/**
* @extends threads_queue_t
*
* @brief Ready list header.
*/
typedef struct {
threads_queue_t r_queue; /**< @brief Threads queue. */
tprio_t r_prio; /**< @brief This field must be
initialized to zero. */
struct context r_ctx; /**< @brief Not used, present because
offsets. */
#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__)
thread_t *r_newer; /**< @brief Newer registry element. */
thread_t *r_older; /**< @brief Older registry element. */
#endif
/* End of the fields shared with the thread_t structure.*/
thread_t *r_current; /**< @brief The currently running
thread. */
} ready_list_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
@ -125,7 +105,7 @@ typedef struct {
* @note It is forbidden to use this macro in order to change the pointer
* (currp = something), use @p setcurrp() instead.
*/
#define currp rlist.r_current
#define currp ch.rlist.r_current
/**
* @brief Current thread pointer change macro.
@ -140,10 +120,6 @@ typedef struct {
/* External declarations. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
extern ready_list_t rlist;
#endif
/*
* Scheduler APIs.
*/
@ -179,7 +155,7 @@ static inline bool chSchIsRescRequiredI(void) {
chDbgCheckClassI();
return firstprio(&rlist.r_queue) > currp->p_prio;
return firstprio(&ch.rlist.r_queue) > currp->p_prio;
}
/**
@ -193,7 +169,7 @@ static inline bool chSchCanYieldS(void) {
chDbgCheckClassI();
return firstprio(&rlist.r_queue) >= currp->p_prio;
return firstprio(&ch.rlist.r_queue) >= currp->p_prio;
}
/**
@ -219,7 +195,7 @@ static inline void chSchDoYieldS(void) {
* @special
*/
static inline void chSchPreemption(void) {
tprio_t p1 = firstprio(&rlist.r_queue);
tprio_t p1 = firstprio(&ch.rlist.r_queue);
tprio_t p2 = currp->p_prio;
#if CH_CFG_TIME_QUANTUM > 0

View File

@ -98,24 +98,6 @@
typedef struct mutex mutex_t;
#endif
/**
* @brief Generic threads single link list, it works like a stack.
*/
typedef struct {
thread_t *p_next; /**< @brief Next in the list/queue. */
} threads_list_t;
/**
* @extends threads_list_t
*
* @brief Generic threads bidirectional linked list header and element.
*/
typedef struct {
thread_t *p_next; /**< @brief Next in the list/queue. */
thread_t *p_prev; /**< @brief Previous in the queue. */
} threads_queue_t;
/**
* @extends threads_queue_t
*

View File

@ -58,39 +58,15 @@
/*===========================================================================*/
/**
* @brief Virtual Timer callback function.
* @brief Type of a Virtual Timer callback function.
*/
typedef void (*vtfunc_t)(void *);
/**
* @brief Virtual Timer structure type.
* @brief Type of a Virtual Timer structure.
*/
typedef struct virtual_timer virtual_timer_t;
/**
* @brief Virtual timers list header.
* @note The timers list is implemented as a double link bidirectional list
* in order to make the unlink time constant, the reset of a virtual
* timer is often used in the code.
*/
typedef struct {
virtual_timer_t *vt_next; /**< @brief Next timer in the delta
list. */
virtual_timer_t *vt_prev; /**< @brief Last timer in the delta
list. */
systime_t vt_delta; /**< @brief Must be initialized to -1. */
#if CH_CFG_TIMEDELTA == 0 || defined(__DOXYGEN__)
volatile systime_t vt_systime; /**< @brief System Time counter. */
#endif
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
/**
* @brief System time of the last tick event.
*/
systime_t vt_lasttime;/**< @brief System time of the last
tick event. */
#endif
} virtual_timers_list_t;
/**
* @extends virtual_timers_list_t
*
@ -160,8 +136,6 @@ struct virtual_timer {
/* External declarations. */
/*===========================================================================*/
extern virtual_timers_list_t vtlist;
/*
* Virtual Timers APIs.
*/
@ -213,7 +187,7 @@ static inline void chVTObjectInit(virtual_timer_t *vtp) {
static inline systime_t chVTGetSystemTimeX(void) {
#if CH_CFG_TIMEDELTA == 0
return vtlist.vt_systime;
return ch.vtlist.vt_systime;
#else /* CH_CFG_TIMEDELTA > 0 */
return port_timer_get_time();
#endif /* CH_CFG_TIMEDELTA > 0 */
@ -381,16 +355,16 @@ static inline void chVTDoTickI(void) {
chDbgCheckClassI();
#if CH_CFG_TIMEDELTA == 0
vtlist.vt_systime++;
if (&vtlist != (virtual_timers_list_t *)vtlist.vt_next) {
ch.vtlist.vt_systime++;
if (&ch.vtlist != (virtual_timers_list_t *)ch.vtlist.vt_next) {
virtual_timer_t *vtp;
--vtlist.vt_next->vt_delta;
while (!(vtp = vtlist.vt_next)->vt_delta) {
--ch.vtlist.vt_next->vt_delta;
while (!(vtp = ch.vtlist.vt_next)->vt_delta) {
vtfunc_t fn = vtp->vt_func;
vtp->vt_func = (vtfunc_t)NULL;
vtp->vt_next->vt_prev = (void *)&vtlist;
vtlist.vt_next = vtp->vt_next;
vtp->vt_next->vt_prev = (void *)&ch.vtlist;
ch.vtlist.vt_next = vtp->vt_next;
chSysUnlockFromISR();
fn(vtp->vt_par);
chSysLockFromISR();
@ -399,20 +373,20 @@ static inline void chVTDoTickI(void) {
#else /* CH_CFG_TIMEDELTA > 0 */
virtual_timer_t *vtp;
systime_t now = chVTGetSystemTimeX();
systime_t delta = now - vtlist.vt_lasttime;
systime_t delta = now - ch.vtlist.vt_lasttime;
while ((vtp = vtlist.vt_next)->vt_delta <= delta) {
while ((vtp = ch.vtlist.vt_next)->vt_delta <= delta) {
delta -= vtp->vt_delta;
vtlist.vt_lasttime += vtp->vt_delta;
ch.vtlist.vt_lasttime += vtp->vt_delta;
vtfunc_t fn = vtp->vt_func;
vtp->vt_func = (vtfunc_t)NULL;
vtp->vt_next->vt_prev = (void *)&vtlist;
vtlist.vt_next = vtp->vt_next;
vtp->vt_next->vt_prev = (void *)&ch.vtlist;
ch.vtlist.vt_next = vtp->vt_next;
chSysUnlockFromISR();
fn(vtp->vt_par);
chSysLockFromISR();
}
if (&vtlist == (virtual_timers_list_t *)vtlist.vt_next) {
if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
/* The list is empty, no tick event needed so the alarm timer
is stopped.*/
port_timer_stop_alarm();

View File

@ -42,8 +42,8 @@
* terminating threads can pulse an event source and an event handler
* can perform a scansion of the registry in order to recover the
* memory.
* @pre In order to use the threads registry the @p CH_CFG_USE_REGISTRY option
* must be enabled in @p chconf.h.
* @pre In order to use the threads registry the @p CH_CFG_USE_REGISTRY
* option must be enabled in @p chconf.h.
* @{
*/
#include "ch.h"
@ -66,7 +66,7 @@
/* Module local functions. */
/*===========================================================================*/
#define _offsetof(st, m) \
#define _offsetof(st, m) \
((size_t)((char *)&((st *)0)->m - (char *)0))
/*===========================================================================*/
@ -131,7 +131,7 @@ thread_t *chRegFirstThread(void) {
thread_t *tp;
chSysLock();
tp = rlist.r_newer;
tp = ch.rlist.r_newer;
#if CH_CFG_USE_DYNAMIC
tp->p_refs++;
#endif
@ -155,7 +155,7 @@ thread_t *chRegNextThread(thread_t *tp) {
chSysLock();
ntp = tp->p_newer;
if (ntp == (thread_t *)&rlist)
if (ntp == (thread_t *)&ch.rlist)
ntp = NULL;
#if CH_CFG_USE_DYNAMIC
else {

View File

@ -37,11 +37,6 @@
/* Module exported variables. */
/*===========================================================================*/
/**
* @brief Ready list header.
*/
ready_list_t rlist;
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
@ -65,10 +60,10 @@ ready_list_t rlist;
*/
void _scheduler_init(void) {
queue_init(&rlist.r_queue);
rlist.r_prio = NOPRIO;
queue_init(&ch.rlist.r_queue);
ch.rlist.r_prio = NOPRIO;
#if CH_CFG_USE_REGISTRY
rlist.r_newer = rlist.r_older = (thread_t *)&rlist;
ch.rlist.r_newer = ch.rlist.r_older = (thread_t *)&ch.rlist;
#endif
}
@ -100,7 +95,7 @@ thread_t *chSchReadyI(thread_t *tp) {
"invalid state");
tp->p_state = CH_STATE_READY;
cp = (thread_t *)&rlist.r_queue;
cp = (thread_t *)&ch.rlist.r_queue;
do {
cp = cp->p_next;
} while (cp->p_prio >= tp->p_prio);
@ -131,7 +126,7 @@ void chSchGoSleepS(tstate_t newstate) {
time quantum when it will wakeup.*/
otp->p_preempt = CH_CFG_TIME_QUANTUM;
#endif
setcurrp(queue_fifo_remove(&rlist.r_queue));
setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
currp->p_state = CH_STATE_CURRENT;
chSysSwitch(currp, otp);
}
@ -149,7 +144,7 @@ static void wakeup(void *p) {
another thread with higher priority.*/
chSysUnlockFromISR();
return;
#if CH_CFG_USE_SEMAPHORES || CH_CFG_USE_QUEUES || \
#if CH_CFG_USE_SEMAPHORES || CH_CFG_USE_QUEUES || \
(CH_CFG_USE_CONDVARS && CH_CFG_USE_CONDVARS_TIMEOUT)
#if CH_CFG_USE_SEMAPHORES
case CH_STATE_WTSEM:
@ -274,7 +269,7 @@ void chSchRescheduleS(void) {
* @special
*/
bool chSchIsPreemptionRequired(void) {
tprio_t p1 = firstprio(&rlist.r_queue);
tprio_t p1 = firstprio(&ch.rlist.r_queue);
tprio_t p2 = currp->p_prio;
#if CH_CFG_TIME_QUANTUM > 0
/* If the running thread has not reached its time quantum, reschedule only
@ -304,7 +299,7 @@ void chSchDoRescheduleBehind(void) {
otp = currp;
/* Picks the first thread from the ready queue and makes it current.*/
setcurrp(queue_fifo_remove(&rlist.r_queue));
setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
currp->p_state = CH_STATE_CURRENT;
#if CH_CFG_TIME_QUANTUM > 0
otp->p_preempt = CH_CFG_TIME_QUANTUM;
@ -327,11 +322,11 @@ void chSchDoRescheduleAhead(void) {
otp = currp;
/* Picks the first thread from the ready queue and makes it current.*/
setcurrp(queue_fifo_remove(&rlist.r_queue));
setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
currp->p_state = CH_STATE_CURRENT;
otp->p_state = CH_STATE_READY;
cp = (thread_t *)&rlist.r_queue;
cp = (thread_t *)&ch.rlist.r_queue;
do {
cp = cp->p_next;
} while (cp->p_prio > otp->p_prio);
@ -356,8 +351,8 @@ void chSchDoRescheduleAhead(void) {
void chSchDoReschedule(void) {
#if CH_CFG_TIME_QUANTUM > 0
/* If CH_CFG_TIME_QUANTUM is enabled then there are two different scenarios to
handle on preemption: time quantum elapsed or not.*/
/* If CH_CFG_TIME_QUANTUM is enabled then there are two different scenarios
to handle on preemption: time quantum elapsed or not.*/
if (currp->p_preempt == 0) {
/* The thread consumed its time quantum so it is enqueued behind threads
with same priority level, however, it acquires a new time quantum.*/

View File

@ -48,6 +48,11 @@
/* Module local variables. */
/*===========================================================================*/
/**
* @brief System data structures.
*/
ch_system_t ch;
#if !CH_CFG_NO_IDLE_THREAD || defined(__DOXYGEN__)
/**
* @brief Idle thread working area.

View File

@ -37,11 +37,6 @@
/* Module exported variables. */
/*===========================================================================*/
/**
* @brief Virtual timers delta list header.
*/
virtual_timers_list_t vtlist;
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
@ -66,12 +61,12 @@ virtual_timers_list_t vtlist;
*/
void _vt_init(void) {
vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist;
vtlist.vt_delta = (systime_t)-1;
ch.vtlist.vt_next = ch.vtlist.vt_prev = (void *)&ch.vtlist;
ch.vtlist.vt_delta = (systime_t)-1;
#if CH_CFG_TIMEDELTA == 0
vtlist.vt_systime = 0;
ch.vtlist.vt_systime = 0;
#else /* CH_CFG_TIMEDELTA > 0 */
vtlist.vt_lasttime = 0;
ch.vtlist.vt_lasttime = 0;
#endif /* CH_CFG_TIMEDELTA > 0 */
}
@ -128,7 +123,7 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
vtp->vt_par = par;
vtp->vt_func = vtfunc;
p = vtlist.vt_next;
p = ch.vtlist.vt_next;
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
{
@ -139,21 +134,21 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
if (delay < CH_CFG_TIMEDELTA)
delay = CH_CFG_TIMEDELTA;
if (&vtlist == (virtual_timers_list_t *)p) {
if (&ch.vtlist == (virtual_timers_list_t *)p) {
/* The delta list is empty, the current time becomes the new
delta list base time.*/
vtlist.vt_lasttime = now;
port_timer_start_alarm(vtlist.vt_lasttime + delay);
ch.vtlist.vt_lasttime = now;
port_timer_start_alarm(ch.vtlist.vt_lasttime + delay);
}
else {
/* Now the delay is calculated as delta from the last tick interrupt
time.*/
delay += now - vtlist.vt_lasttime;
delay += now - ch.vtlist.vt_lasttime;
/* If the specified delay is closer in time than the first element
in the delta list then it becomes the next alarm event in time.*/
if (delay < p->vt_delta)
port_timer_set_alarm(vtlist.vt_lasttime + delay);
port_timer_set_alarm(ch.vtlist.vt_lasttime + delay);
}
}
#endif /* CH_CFG_TIMEDELTA > 0 */
@ -172,7 +167,7 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
/* Special case when the timer is in last position in the list, the
value in the header must be restored.*/;
p->vt_delta -= delay;
vtlist.vt_delta = (systime_t)-1;
ch.vtlist.vt_delta = (systime_t)-1;
}
/**
@ -199,17 +194,18 @@ void chVTDoResetI(virtual_timer_t *vtp) {
/* The above code changes the value in the header when the removed element
is the last of the list, restoring it.*/
vtlist.vt_delta = (systime_t)-1;
ch.vtlist.vt_delta = (systime_t)-1;
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
{
if (&vtlist == (virtual_timers_list_t *)vtlist.vt_next) {
if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
/* Just removed the last element in the list, alarm timer stopped.*/
port_timer_stop_alarm();
}
else {
/* The alarm is set to the next element in the delta list.*/
port_timer_set_alarm(vtlist.vt_lasttime + vtlist.vt_next->vt_delta);
port_timer_set_alarm(ch.vtlist.vt_lasttime +
ch.vtlist.vt_next->vt_delta);
}
}
#endif /* CH_CFG_TIMEDELTA > 0 */