Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
pool_queue_exports.h
00001 /* 00002 * Copyright (c) 2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #ifndef UVISOR_POOL_QUEUE_EXPORTS_H 00018 #define UVISOR_POOL_QUEUE_EXPORTS_H 00019 00020 #include "api/inc/magic_exports.h" 00021 #include "api/inc/uvisor_exports.h" 00022 #include "api/inc/uvisor_spinlock_exports.h" 00023 #include <stdint.h> 00024 #include <stddef.h> 00025 00026 #define UVISOR_POOL_QUEUE_NON_BLOCKING (0) 00027 #define UVISOR_POOL_QUEUE_BLOCKING (1) 00028 00029 #define UVISOR_POOL_SLOT_INVALID ((uint8_t) 0xFFU) 00030 #define UVISOR_POOL_SLOT_IS_DEQUEUED ((uint8_t) 0xFEU) 00031 #define UVISOR_POOL_SLOT_IS_FREE ((uint8_t) 0xFDU) 00032 #define UVISOR_POOL_MAX_VALID ((uint8_t) 0xFCU) 00033 00034 typedef uint8_t uvisor_pool_slot_t; 00035 00036 typedef struct uvisor_pool_queue_entry { 00037 union { 00038 struct { 00039 /* The next slot in the queue */ 00040 uvisor_pool_slot_t next; 00041 00042 /* The previous slot in the queue */ 00043 uvisor_pool_slot_t prev; 00044 } queued; 00045 struct { 00046 /* If the slot is free, the next available slot in the free list */ 00047 uvisor_pool_slot_t next; 00048 00049 /* If the slot is free or dequeued */ 00050 uvisor_pool_slot_t state; 00051 } dequeued; 00052 }; 00053 } uvisor_pool_queue_entry_t; 00054 00055 /* These are assumed to only be statically allocated, so the management array 00056 * in in-place. */ 00057 typedef struct uvisor_pool { 00058 /* Magic that identifies this as a uvisor_pool type. */ 00059 uint32_t magic; 00060 00061 /* The array holds slots of data. */ 00062 void const * array; 00063 00064 /* The distance between elements in the array. */ 00065 size_t stride; 00066 00067 /* The maximum number of elements that could be in the array. */ 00068 uvisor_pool_slot_t num; 00069 00070 /* The number of items currently allocated from the pool. For testing and 00071 * debug purposes only. */ 00072 uvisor_pool_slot_t num_allocated; 00073 00074 /* The first free slot. */ 00075 uvisor_pool_slot_t first_free; 00076 00077 /* The spinlock serializes updates to the management array. */ 00078 UvisorSpinlock spinlock; 00079 00080 /* This must be at the end so we can allocate memory for pools by 00081 * allocating enough room for the size of the pool appended by an array of 00082 * entries. */ 00083 uvisor_pool_queue_entry_t management_array[]; 00084 } uvisor_pool_t; 00085 00086 typedef struct uvisor_pool_queue { 00087 /* Magic that identifies this as a uvisor_pool_queue type. */ 00088 uint32_t magic; 00089 00090 /* The first allocated slot */ 00091 uvisor_pool_slot_t head; 00092 00093 /* The last allocated slot */ 00094 uvisor_pool_slot_t tail; 00095 00096 uvisor_pool_t * pool; 00097 } uvisor_pool_queue_t; 00098 00099 /* Intialize a pool. 00100 * Return 0 on success, non-zero otherwise. */ 00101 UVISOR_EXTERN int uvisor_pool_init(uvisor_pool_t * pool, void * array, size_t stride, size_t num); 00102 00103 /* Initialize a pool queue. 00104 * Return 0 on success, non-zero otherwise. */ 00105 UVISOR_EXTERN int uvisor_pool_queue_init(uvisor_pool_queue_t * pool_queue, uvisor_pool_t * pool, void * array, size_t stride, size_t num); 00106 00107 /* Allocate a slot from the pool. This doesn't put anything in the slot for 00108 * you. It's up to you to do that. Return the index of the allocated slot, or 00109 * UVISOR_POOL_SLOT_INVALID if there is no available slot. This function will 00110 * spin until the spin lock serializing access to the pool can be taken. */ 00111 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_allocate(uvisor_pool_t * pool); 00112 /* Attempt to allocate a slot. This function will fail if the spin lock 00113 * serializing access to the pool can not be taken. */ 00114 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_try_allocate(uvisor_pool_t * pool); 00115 00116 /* Enqueue the specified slot into the queue. */ 00117 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_enqueue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot); 00118 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_enqueue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot); 00119 00120 /* Free the specified slot back into the pool. Invalid slots are ignored. 00121 * Return the slot that was freed, or UVISOR_POOL_SLOT_IS_FREE if the slot was 00122 * already freed, or UVISOR_POOL_SLOT_INVALID if the slot being requested to 00123 * free is outside the range of the queue. */ 00124 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_free(uvisor_pool_t * pool, uvisor_pool_slot_t slot); 00125 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_try_free(uvisor_pool_t * pool, uvisor_pool_slot_t slot); 00126 00127 /* Remove the specified slot from the queue. This function does not free the 00128 * specified slot back into the pool. Return the slot that was dequeued, or 00129 * UVISOR_POOL_SLOT_IS_DEQUEUED if the slot was already dequeued, or 00130 * UVISOR_POOL_SLOT_INVALID if the slot being requested to dequeue is outside 00131 * the range of the queue. */ 00132 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_dequeue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot); 00133 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_dequeue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot); 00134 00135 /* Remove the first slot from the queue. This function does not free the 00136 * specified slot back into the pool. Return the slot that was dequeued or 00137 * UVISOR_POOL_SLOT_INVALID if the slot being requested to dequeue is outside 00138 * the range of the queue. */ 00139 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_dequeue_first(uvisor_pool_queue_t * pool_queue); 00140 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_dequeue_first(uvisor_pool_queue_t * pool_queue); 00141 00142 /* Find the first (in queue order) slot that the supplied query function 00143 * returns non-zero for. The query function is provided with `context` on every 00144 * invocation. This allows query functions to access additional data without 00145 * having to use global variables. `uvisor_pool_queue_find_first` is reentrant. */ 00146 typedef int (*TQueryFN_Ptr)(uvisor_pool_slot_t slot, void * context); 00147 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_find_first(uvisor_pool_queue_t * pool_queue, 00148 TQueryFN_Ptr query_fn, void * context); 00149 UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_find_first(uvisor_pool_queue_t * pool_queue, 00150 TQueryFN_Ptr query_fn, void * context); 00151 00152 /* Inline helper function to make allocating slots for pool queues easier and 00153 * better encapsulated (clients don't need to pull the pool out of the pool 00154 * queue, or even realize pool_queue is implemented with a pool) */ 00155 static inline uvisor_pool_slot_t uvisor_pool_queue_allocate(uvisor_pool_queue_t * pool_queue) 00156 { 00157 return uvisor_pool_allocate(pool_queue->pool); 00158 } 00159 00160 static inline uvisor_pool_slot_t uvisor_pool_queue_try_allocate(uvisor_pool_queue_t * pool_queue) 00161 { 00162 return uvisor_pool_try_allocate(pool_queue->pool); 00163 } 00164 00165 /* Inline helper function to make freeing slots for pool queues easier and 00166 * better encapsulated (clients don't need to pull the pool out of the pool 00167 * queue, or even realize pool_queue is implemented with a pool) */ 00168 static inline uvisor_pool_slot_t uvisor_pool_queue_free(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot) 00169 { 00170 return uvisor_pool_free(pool_queue->pool, slot); 00171 } 00172 00173 static inline uvisor_pool_slot_t uvisor_pool_queue_try_free(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot) 00174 { 00175 return uvisor_pool_try_free(pool_queue->pool, slot); 00176 } 00177 00178 /* Return a pointer to the specified slot within the pool. */ 00179 static inline void * uvisor_pool_pointer_to(uvisor_pool_t * pool, uvisor_pool_slot_t slot) 00180 { 00181 if (slot >= pool->num) { 00182 return NULL; 00183 } 00184 return (uint8_t *) pool->array + pool->stride * slot; 00185 } 00186 00187 #endif
Generated on Sun Jul 17 2022 08:25:29 by 1.7.2