blob: e749a3f8d498284db4f73b659083e3a3c6d7ad5d [file] [log] [blame]
/*
* 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, (stack_data_t *)((x) + 1), 1); \
k_stack_push(x, MAGIC); \
} while ((0))
#endif
#define take(x) do { \
stack_data_t data; k_stack_pop(x, &data, K_FOREVER); \
__ASSERT(data == MAGIC, "data was %lx\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 */