Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | /*
* 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;
u32_t stack_mem[1];
} fork_obj_t;
#define fork_init(x) do { \
k_stack_init(x, (u32_t *)((x) + 1), 1); \
k_stack_push(x, MAGIC); \
} while ((0))
#endif
#define take(x) do { \
u32_t data; k_stack_pop(x, &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 char __stack __noinit stacks[NUM_PHIL][STACK_SIZE];
static struct k_thread threads[NUM_PHIL];
#endif /* phil_obj_abstract__h */
|