diff --git a/core/include/clist.h b/core/include/clist.h index 128ec9555..7b88192d4 100644 --- a/core/include/clist.h +++ b/core/include/clist.h @@ -19,13 +19,29 @@ #ifndef __CLIST_H #define __CLIST_H +#include "kernel_macros.h" + +/** + * @def clist_get_container(NODE, TYPE, MEMBER) + * @brief Returns the container of the circular list + * @details For a struct `TYPE` with a member `MEMBER`, which is a `clist_node_t`, + * given a pointer `NODE` to `TYPE::MEMBER` this function returns a pointer + * to the instance of `TYPE`. + * @details E.g. for `struct my_struct_t { ...; clist_node_t n; ... } my_struct;`, + * `&my_struct == clist_get_container(&my_struct.n, struct my_struct_t, n)`. + * @param[in] NODE pointer to a member + * @param[in] TYPE a type name (a struct or union), container of NODE + * @param[in] MEMBER name of the member of TYPE which NODE points to + * @return Pointer to the container of NODE. + */ +#define clist_get_container(NODE, TYPE, MEMBER) container_of(NODE, TYPE, MEMBER) + /** * @brief Structure representing a node in the clist. */ typedef struct clist_node_t { struct clist_node_t *next; /**< pointer to next node */ struct clist_node_t *prev; /**< pointer to the previous node */ - unsigned int data; /**< holding data for this node */ } clist_node_t; /** diff --git a/core/include/kernel_macros.h b/core/include/kernel_macros.h new file mode 100644 index 000000000..54b6728e2 --- /dev/null +++ b/core/include/kernel_macros.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @addtogroup core_util + * @{ + * + * @file kernel_macros.h + * @brief common macros + * + * @author René Kijewski + */ + +#include + +/** + * @def container_of(PTR, TYPE, MEMBER) + * @brief Returns the container of a pointer to a member. + * @details For a struct `TYPE` with a member `MEMBER`, + * given a pointer `PTR` to `TYPE::MEMBER` this function returns a pointer + * to the instance of `TYPE`. + * @details E.g. for `struct my_struct_t { ...; something_t n; ... } my_struct;`, + * `&my_struct == container_of(&my_struct.n, struct my_struct_t, n)`. + * @param[in] PTR pointer to a member + * @param[in] TYPE a type name (a struct or union), container of PTR + * @param[in] MEMBER name of the member of TYPE which PTR points to + * @return Pointer to the container of PTR. + */ +#if __STDC_VERSION__ >= 201112L +# define container_of(PTR, TYPE, MEMBER) \ + (_Generic((PTR), \ + const __typeof__ (((TYPE *) 0)->MEMBER) *: \ + ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))), \ + __typeof__ (((TYPE *) 0)->MEMBER) *: \ + ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))) \ + )) +#elif defined __GNUC__ +# define container_of(PTR, TYPE, MEMBER) \ + (__extension__ ({ \ + __extension__ const __typeof__ (((TYPE *) 0)->MEMBER) *__m____ = (PTR); \ + ((TYPE *) ((char *) __m____ - offsetof(TYPE, MEMBER))); \ + })) +#else +# define container_of(PTR, TYPE, MEMBER) \ + ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))) +#endif + +/** + * @} + */ diff --git a/core/sched.c b/core/sched.c index 08d55a2b4..204619619 100644 --- a/core/sched.c +++ b/core/sched.c @@ -87,10 +87,10 @@ void sched_run(void) * since the threading should not be started before at least the idle thread was started. */ int nextrq = bitarithm_lsb(runqueue_bitcache); - clist_node_t next = *(sched_runqueues[nextrq]); - DEBUG("scheduler: first in queue: %s\n", ((tcb_t *)next.data)->name); + my_active_thread = clist_get_container(sched_runqueues[nextrq], tcb_t, rq_entry); clist_advance(&(sched_runqueues[nextrq])); - my_active_thread = (tcb_t *)next.data; + DEBUG("scheduler: first in queue: %s\n", my_active_thread->name); + sched_active_pid = (volatile int) my_active_thread->pid; kernel_pid_t my_next_pid = my_active_thread->pid; diff --git a/core/thread.c b/core/thread.c index 53617104a..74852222c 100644 --- a/core/thread.c +++ b/core/thread.c @@ -185,7 +185,6 @@ kernel_pid_t thread_create(char *stack, int stacksize, char priority, int flags, cb->priority = priority; cb->status = 0; - cb->rq_entry.data = (unsigned int) cb; cb->rq_entry.next = NULL; cb->rq_entry.prev = NULL;