/* * 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 */