Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
atomic-queue.h
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2015-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #ifndef __ATOMIC_QUEUE_H__ 00020 #define __ATOMIC_QUEUE_H__ 00021 00022 #ifdef __cplusplus 00023 extern "C" { 00024 #endif 00025 00026 #include <stdint.h> 00027 00028 #if defined(ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK) && ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK == 0 00029 #undef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK 00030 #else 00031 #undef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK 00032 #define ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK 00033 #endif 00034 00035 #ifndef ATOMIC_QUEUE_CUSTOM_ELEMENT 00036 struct atomic_queue_element { 00037 struct atomic_queue_element * volatile next; 00038 #ifdef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK 00039 uintptr_t lock; 00040 #endif 00041 void * data; 00042 }; 00043 #endif 00044 00045 struct atomic_queue { 00046 struct atomic_queue_element * volatile tail; 00047 }; 00048 00049 enum aq_failure_codes { 00050 ATOMIC_QUEUE_SUCCESS = 0, 00051 ATOMIC_QUEUE_NULL_QUEUE, 00052 ATOMIC_QUEUE_DUPLICATE_ELEMENT, 00053 }; 00054 00055 /** 00056 * \brief Add an element to the tail of the queue 00057 * 00058 * Since the queue only maintains a tail pointer, this simply inserts the new element before the tail pointer 00059 * 00060 * @param[in,out] q the queue structure to operate on 00061 * @param[in] e The element to add to the queue 00062 */ 00063 int aq_push_tail(struct atomic_queue * q, struct atomic_queue_element * e); 00064 /** 00065 * \brief Get an element from the head of the queue 00066 * 00067 * This function iterates over the queue and removes an element from the head when it finds the head. This is slower 00068 * than maintaining a head pointer, but it is necessary to ensure that a pop is completely atomic. 00069 * 00070 * @param[in,out] q The queue to pop from 00071 * @return The popped element or NULL if the queue was empty 00072 */ 00073 struct atomic_queue_element * aq_pop_head(struct atomic_queue * q); 00074 /** 00075 * Check if there are any elements in the queue 00076 * 00077 * Note that there is no guarantee that a queue which is not empty when this API is called will not be become empty 00078 * before aq_pop_head is called 00079 * 00080 * @retval non-zero when the queue is empty 00081 * @retval 0 when the queue is not empty 00082 */ 00083 int aq_empty(struct atomic_queue * q); 00084 /** 00085 * Iterates over the queue and counts the elements in the queue 00086 * 00087 * The value returned by this function may be invalid by the time it returns. Do not depend on this value except in 00088 * a critical section. 00089 * 00090 * @return the number of elements in the queue 00091 */ 00092 unsigned aq_count(struct atomic_queue * q); 00093 00094 /** 00095 * Initialize an atomic queue element. 00096 * 00097 * WARNING: Only call this function one time per element, or it may result in undefined behaviour. 00098 * 00099 * @param[in] element Element to initialize 00100 */ 00101 void aq_initialize_element(struct atomic_queue_element* e); 00102 00103 #ifdef __cplusplus 00104 } 00105 #endif 00106 00107 #endif // __ATOMIC_QUEUE_H__
Generated on Tue Jul 12 2022 19:01:33 by 1.7.2