Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:53:58 by
1.7.2
