When using the stack fork type in the philosophers sample, there were a few pointer type mismatch since the k_stack_*() functions are using stack_data_t but the parameters are uint32_t. So cast them to void pointer to suppress compiler warnings. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
163 lines
4.2 KiB
C
163 lines
4.2 KiB
C
/*
|
|
* Copyright (c) 2016 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* Object type abstraction.
|
|
*
|
|
* Each object type that can be used as a "fork" provides:
|
|
*
|
|
* - a definition for fork_t (a reference to a fork) and fork_obj_t (an
|
|
* instance of the fork object)
|
|
* - a 'fork_init' function that initializes the object
|
|
* - a 'take' function that simulates taking the fork (eg. k_sem_take)
|
|
* - a 'drop' function that simulates dropping the fork (eg. k_mutex_unlock)
|
|
* - a 'fork_type_str' string defining the object type
|
|
*
|
|
* When using dynamic objects, the instances of the fork objects are placed
|
|
* automatically in the fork_objs[] array . References to these are in turn
|
|
* placed automatically in the forks[] array, the array of references to the
|
|
* forks.
|
|
*
|
|
* When using static objects, references to each object must be put by hand in
|
|
* the forks[] array.
|
|
*/
|
|
|
|
#ifndef phil_obj_abstract__h
|
|
#define phil_obj_abstract__h
|
|
|
|
#define MAGIC 0xa5a5ee11
|
|
|
|
#if (FORKS == FIFOS) || (FORKS == LIFOS)
|
|
struct packet {
|
|
void *next;
|
|
int data;
|
|
} orig_packet[NUM_PHIL];
|
|
#endif
|
|
|
|
#if FORKS == SEMAPHORES
|
|
#define fork_t struct k_sem *
|
|
#if STATIC_OBJS
|
|
K_SEM_DEFINE(fork0, 1, 1);
|
|
K_SEM_DEFINE(fork1, 1, 1);
|
|
K_SEM_DEFINE(fork2, 1, 1);
|
|
K_SEM_DEFINE(fork3, 1, 1);
|
|
K_SEM_DEFINE(fork4, 1, 1);
|
|
K_SEM_DEFINE(fork5, 1, 1);
|
|
#else
|
|
#define fork_obj_t struct k_sem
|
|
#define fork_init(x) k_sem_init(x, 1, 1)
|
|
#endif
|
|
#define take(x) k_sem_take(x, K_FOREVER)
|
|
#define drop(x) k_sem_give(x)
|
|
#define fork_type_str "semaphores"
|
|
#elif FORKS == MUTEXES
|
|
#define fork_t struct k_mutex *
|
|
#if STATIC_OBJS
|
|
K_MUTEX_DEFINE(fork0);
|
|
K_MUTEX_DEFINE(fork1);
|
|
K_MUTEX_DEFINE(fork2);
|
|
K_MUTEX_DEFINE(fork3);
|
|
K_MUTEX_DEFINE(fork4);
|
|
K_MUTEX_DEFINE(fork5);
|
|
#else
|
|
#define fork_obj_t struct k_mutex
|
|
#define fork_init(x) k_mutex_init(x)
|
|
#endif
|
|
#define take(x) k_mutex_lock(x, K_FOREVER)
|
|
#define drop(x) k_mutex_unlock(x)
|
|
#define fork_type_str "mutexes"
|
|
#elif FORKS == STACKS
|
|
#define fork_t struct k_stack *
|
|
#if STATIC_OBJS
|
|
#error "not implemented yet."
|
|
#else
|
|
typedef struct {
|
|
struct k_stack stack;
|
|
uint32_t stack_mem[1];
|
|
} fork_obj_t;
|
|
#define fork_init(x) do { \
|
|
k_stack_init(x, (void *)((x) + 1), 1); \
|
|
k_stack_push(x, MAGIC); \
|
|
} while ((0))
|
|
#endif
|
|
#define take(x) do { \
|
|
uint32_t data; k_stack_pop(x, (void *)&data, K_FOREVER); \
|
|
__ASSERT(data == MAGIC, "data was %x\n", data); \
|
|
} while ((0))
|
|
#define drop(x) k_stack_push(x, MAGIC)
|
|
#define fork_type_str "stacks"
|
|
#elif FORKS == FIFOS
|
|
#define fork_t struct k_fifo *
|
|
#if STATIC_OBJS
|
|
#error "not implemented yet."
|
|
#else
|
|
typedef struct {
|
|
struct k_fifo fifo;
|
|
struct packet data;
|
|
} fork_obj_t;
|
|
#define fork_init(x) do { \
|
|
k_fifo_init(x); \
|
|
((fork_obj_t *)(x))->data.data = MAGIC; \
|
|
k_fifo_put(x, &(((fork_obj_t *)(x))->data)); \
|
|
} while ((0))
|
|
#endif
|
|
#define take(x) do { \
|
|
struct packet *data; \
|
|
data = k_fifo_get(x, K_FOREVER); \
|
|
__ASSERT(data->data == MAGIC, ""); \
|
|
} while ((0))
|
|
#define drop(x) k_fifo_put(x, &(((fork_obj_t *)(x))->data))
|
|
#define fork_type_str "fifos"
|
|
#elif FORKS == LIFOS
|
|
#define fork_t struct k_lifo *
|
|
#if STATIC_OBJS
|
|
#error "not implemented yet."
|
|
#else
|
|
typedef struct {
|
|
struct k_lifo lifo;
|
|
struct packet data;
|
|
} fork_obj_t;
|
|
#define fork_init(x) do { \
|
|
k_lifo_init(x); \
|
|
((fork_obj_t *)(x))->data.data = MAGIC; \
|
|
k_lifo_put(x, &(((fork_obj_t *)(x))->data)); \
|
|
} while ((0))
|
|
#endif
|
|
#define take(x) do { \
|
|
struct packet *data; \
|
|
data = k_lifo_get(x, K_FOREVER); \
|
|
__ASSERT(data->data == MAGIC, ""); \
|
|
} while ((0))
|
|
#define drop(x) k_lifo_put(x, &(((fork_obj_t *)(x))->data))
|
|
#define fork_type_str "lifos"
|
|
#else
|
|
#error unknown fork type
|
|
#endif
|
|
|
|
#if STATIC_OBJS
|
|
#define obj_init_type "static"
|
|
#else
|
|
#define obj_init_type "dynamic"
|
|
fork_obj_t fork_objs[NUM_PHIL];
|
|
#endif
|
|
|
|
static fork_t forks[NUM_PHIL] = {
|
|
#if STATIC_OBJS
|
|
&fork0, &fork1, &fork2,
|
|
&fork3, &fork4, &fork5,
|
|
#else
|
|
(fork_t)&fork_objs[0], (fork_t)&fork_objs[1], (fork_t)&fork_objs[2],
|
|
(fork_t)&fork_objs[3], (fork_t)&fork_objs[4], (fork_t)&fork_objs[5],
|
|
#endif
|
|
};
|
|
|
|
static K_THREAD_STACK_ARRAY_DEFINE(stacks, NUM_PHIL, STACK_SIZE);
|
|
static struct k_thread threads[NUM_PHIL];
|
|
|
|
#endif /* phil_obj_abstract__h */
|