1 /* 2 * Copyright (c) 2016 Wind River Systems, Inc. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file 9 * 10 * Object type abstraction. 11 * 12 * Each object type that can be used as a "fork" provides: 13 * 14 * - a definition for fork_t (a reference to a fork) and fork_obj_t (an 15 * instance of the fork object) 16 * - a 'fork_init' function that initializes the object 17 * - a 'take' function that simulates taking the fork (eg. k_sem_take) 18 * - a 'drop' function that simulates dropping the fork (eg. k_mutex_unlock) 19 * - a 'fork_type_str' string defining the object type 20 * 21 * When using dynamic objects, the instances of the fork objects are placed 22 * automatically in the fork_objs[] array . References to these are in turn 23 * placed automatically in the forks[] array, the array of references to the 24 * forks. 25 * 26 * When using static objects, references to each object must be put by hand in 27 * the forks[] array. 28 */ 29 30 #ifndef phil_obj_abstract__h 31 #define phil_obj_abstract__h 32 33 #define MAGIC 0xa5a5ee11 34 35 #if (FORKS == FIFOS) || (FORKS == LIFOS) 36 struct packet { 37 void *next; 38 int data; 39 } orig_packet[NUM_PHIL]; 40 #endif 41 42 #if FORKS == SEMAPHORES 43 #define fork_t struct k_sem * 44 #if STATIC_OBJS 45 K_SEM_DEFINE(fork0, 1, 1); 46 K_SEM_DEFINE(fork1, 1, 1); 47 K_SEM_DEFINE(fork2, 1, 1); 48 K_SEM_DEFINE(fork3, 1, 1); 49 K_SEM_DEFINE(fork4, 1, 1); 50 K_SEM_DEFINE(fork5, 1, 1); 51 #else 52 #define fork_obj_t struct k_sem 53 #define fork_init(x) k_sem_init(x, 1, 1) 54 #endif 55 #define take(x) k_sem_take(x, K_FOREVER) 56 #define drop(x) k_sem_give(x) 57 #define fork_type_str "semaphores" 58 #elif FORKS == MUTEXES 59 #define fork_t struct k_mutex * 60 #if STATIC_OBJS 61 K_MUTEX_DEFINE(fork0); 62 K_MUTEX_DEFINE(fork1); 63 K_MUTEX_DEFINE(fork2); 64 K_MUTEX_DEFINE(fork3); 65 K_MUTEX_DEFINE(fork4); 66 K_MUTEX_DEFINE(fork5); 67 #else 68 #define fork_obj_t struct k_mutex 69 #define fork_init(x) k_mutex_init(x) 70 #endif 71 #define take(x) k_mutex_lock(x, K_FOREVER) 72 #define drop(x) k_mutex_unlock(x) 73 #define fork_type_str "mutexes" 74 #elif FORKS == STACKS 75 #define fork_t struct k_stack * 76 #if STATIC_OBJS 77 #error "not implemented yet." 78 #else 79 typedef struct { 80 struct k_stack stack; 81 uint32_t stack_mem[1]; 82 } fork_obj_t; 83 #define fork_init(x) do { \ 84 k_stack_init(x, (stack_data_t *)((x) + 1), 1); \ 85 k_stack_push(x, MAGIC); \ 86 } while ((0)) 87 #endif 88 #define take(x) do { \ 89 stack_data_t data; k_stack_pop(x, &data, K_FOREVER); \ 90 __ASSERT(data == MAGIC, "data was %lx\n", data); \ 91 } while ((0)) 92 #define drop(x) k_stack_push(x, MAGIC) 93 #define fork_type_str "stacks" 94 #elif FORKS == FIFOS 95 #define fork_t struct k_fifo * 96 #if STATIC_OBJS 97 #error "not implemented yet." 98 #else 99 typedef struct { 100 struct k_fifo fifo; 101 struct packet data; 102 } fork_obj_t; 103 #define fork_init(x) do { \ 104 k_fifo_init(x); \ 105 ((fork_obj_t *)(x))->data.data = MAGIC; \ 106 k_fifo_put(x, &(((fork_obj_t *)(x))->data)); \ 107 } while ((0)) 108 #endif 109 #define take(x) do { \ 110 struct packet *data; \ 111 data = k_fifo_get(x, K_FOREVER); \ 112 __ASSERT(data->data == MAGIC, ""); \ 113 } while ((0)) 114 #define drop(x) k_fifo_put(x, &(((fork_obj_t *)(x))->data)) 115 #define fork_type_str "fifos" 116 #elif FORKS == LIFOS 117 #define fork_t struct k_lifo * 118 #if STATIC_OBJS 119 #error "not implemented yet." 120 #else 121 typedef struct { 122 struct k_lifo lifo; 123 struct packet data; 124 } fork_obj_t; 125 #define fork_init(x) do { \ 126 k_lifo_init(x); \ 127 ((fork_obj_t *)(x))->data.data = MAGIC; \ 128 k_lifo_put(x, &(((fork_obj_t *)(x))->data)); \ 129 } while ((0)) 130 #endif 131 #define take(x) do { \ 132 struct packet *data; \ 133 data = k_lifo_get(x, K_FOREVER); \ 134 __ASSERT(data->data == MAGIC, ""); \ 135 } while ((0)) 136 #define drop(x) k_lifo_put(x, &(((fork_obj_t *)(x))->data)) 137 #define fork_type_str "lifos" 138 #else 139 #error unknown fork type 140 #endif 141 142 #if STATIC_OBJS 143 #define obj_init_type "static" 144 #else 145 #define obj_init_type "dynamic" 146 fork_obj_t fork_objs[NUM_PHIL]; 147 #endif 148 149 static fork_t forks[NUM_PHIL] = { 150 #if STATIC_OBJS 151 &fork0, &fork1, &fork2, 152 &fork3, &fork4, &fork5, 153 #else 154 (fork_t)&fork_objs[0], (fork_t)&fork_objs[1], (fork_t)&fork_objs[2], 155 (fork_t)&fork_objs[3], (fork_t)&fork_objs[4], (fork_t)&fork_objs[5], 156 #endif 157 }; 158 159 static K_THREAD_STACK_ARRAY_DEFINE(stacks, NUM_PHIL, STACK_SIZE); 160 static struct k_thread threads[NUM_PHIL]; 161 162 #endif /* phil_obj_abstract__h */ 163