1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 */ 16 17 #ifndef YLONG_QUEUE_H 18 #define YLONG_QUEUE_H 19 20 #ifdef __cplusplus 21 #include <atomic> 22 #else 23 #include <stdatomic.h> 24 #endif 25 26 #ifdef __cplusplus 27 #if __cplusplus 28 extern "C" { 29 #endif 30 #endif 31 #ifdef FFRT_IO_TASK_SCHEDULER 32 /** 33 * @ingroup mid 34 * @brief 生成模块号 35 * @param x [IN] 模块号。 36 */ 37 #define MID_MAKE(x) ((0x1000 + (x)) << 16) 38 39 #define MID_QUEUE MID_MAKE(2) 40 /** 41 * @brief 0x10020001 42 * 插入时队列已满 43 */ 44 #define ERROR_QUEUE_FULL ((MID_QUEUE) | 0x01) 45 46 /** 47 * @brief 0x10020002 48 * 取出时队列为空 49 */ 50 #define ERROR_QUEUE_EMPTY ((MID_QUEUE) | 0x02) 51 52 /** 53 * @brief 0x10020003 54 * 初始化时,queue->buf申请内存失败 55 */ 56 #define ERROR_QUEUE_BUF_ALLOC_FAILED ((MID_QUEUE) | 0x03) 57 58 /** 59 * @brief 0x10020004 60 * 函数传入的入参非法 61 */ 62 #define ERROR_QUEUE_ARG_INVALID ((MID_QUEUE) | 0x04) 63 64 /** 65 * @brief 0x10020005 66 * queue->buf为空,queue未初始化 67 */ 68 #define ERROR_QUEUE_BUF_UNINITIALIZED ((MID_QUEUE) | 0x05) 69 70 71 /** 72 * @ingroup queue 73 * @struct queue_s 74 * @brief queue结构体 \n 75 * 定义了queue的头尾、容量和队列指针 76 */ 77 struct queue_s { 78 std::atomic<unsigned int> head; 79 std::atomic<unsigned int> tail; 80 unsigned int capacity; 81 void **buf; 82 }; 83 84 /** 85 * @ingroup queue 86 * @brief 获取队列长度。 87 * @par 描述:获取指定队列的长度并返回。 88 * @attention 入参queue不得为NULL,否则段错误,且queue必须已经初始化 89 * @param queue [IN] 要获取长度的指定队列。 90 * @retval 成功返回队列长度,失败返回0 91 * @par 依赖:无。 92 * @li queue.h:该接口声明所在的文件。 93 * @see 94 */ 95 unsigned int queue_length(struct queue_s *queue); 96 97 /** 98 * @ingroup queue 99 * @brief 获取队列的容量。 100 * @par 描述:获取指定队列的容量并返回。 101 * @attention 入参queue不得为NULL,否则段错误,且queue必须已经初始化 102 * @param queue [IN] 要获取容量的指定队列。 103 * @retval 队列的容量。 104 * @par 依赖:无。 105 * @li queue.h:该接口声明所在的文件。 106 * @see 107 */ 108 unsigned int queue_capacity(struct queue_s *queue); 109 110 /** 111 * @ingroup queue 112 * @brief 从队列的首部取出元素。 113 * @par 描述:取出队列首部元素并返回指向此元素的指针。 114 * @attention 入参queue不得为NULL,否则段错误,且queue必须已经初始化 115 * @param queue [IN] 要取出头部的队列。 116 * @retval 指向首部元素的指针,若队列为空则返回NULL。 117 * @par 依赖:无。 118 * @li queue.h:该接口声明所在的文件。 119 * @see 120 */ 121 void *queue_pophead(struct queue_s *queue); 122 123 /** 124 * @ingroup queue 125 * @brief 从队列首部批量取出元素。 126 * @par 描述:批量取出队列首部元素并返回取出元素的数量。 127 * @attention 入参queue,buf不得为NULL,否则段错误,且queue必须已经初始化 128 * @param queue [IN] 要批量取出头部元素的队列。 129 * @param buf [IN] 将取出的元素放入此buffer。 130 * @param buf_len [IN] buffer的长度 131 * @retval 取出的元素数量,最大为buf_len。 132 * @par 依赖:无。 133 * @li queue.h:该接口声明所在的文件。 134 * @see queue_pophead 135 */ 136 unsigned int queue_pophead_batch(struct queue_s *queue, void *buf[], unsigned int buf_len); 137 138 /** 139 * @ingroup queue 140 * @brief 将元素推入队列尾部。 141 * @par 描述:将指定元素推入队列的尾部。 142 * @attention 入参queue不得为NULL,否则段错误,且queue必须已经初始化,仅支持单线程插入 143 * @param queue [IN] 要被推入元素的队列。 144 * @param object [IN] 要推入队列的元素。 145 * @retval 错误码,0为成功, 失败返回错误码。 146 * @par 依赖:无。 147 * @li queue.h:该接口声明所在的文件。 148 * @see 149 */ 150 int queue_pushtail(struct queue_s *queue, void *object); 151 152 /** 153 * @ingroup queue 154 * @brief 将元素批量推入队列尾部。 155 * @par 描述:将缓存区里的元素批量推入队列的尾部。 156 * @attention 入参queue,buf不得为NULL,否则段错误,且queue必须已经初始化,仅支持单线程插入 157 * @param queue [IN] 要被推入元素的队列。 158 * @param buf [IN] 包含要被推入队列尾部的元素的buffer。 159 * @param buf_len [IN] buffer的长度 160 * @retval 成功返回被推入队列尾部的元素数量,最大为buf_len。 161 * @par 依赖:无。 162 * @li queue.h:该接口声明所在的文件。 163 * @see queue_pushtail 164 */ 165 unsigned int queue_pushtail_batch(struct queue_s *queue, void *buf[], unsigned int buf_len); 166 167 /** 168 * @ingroup queue 169 * @brief 从队列A首部批量取出元素后将元素批量推入队列B尾部。 170 * @par 描述:批量取出队列A首部元素推入队列B的尾部并返回取出元素的数量。 171 * @attention 入参target_queue,local_queue不得为NULL,否则段错误,且queue必须已经初始化,仅支持单线程插入 172 * @param target_queue [IN] 要批量取出头部元素的队列。 173 * @param local_queue [IN] 要被推入元素的队列。 174 * @param buf [IN] 包含要被推入队列尾部的元素的buffer。 175 * @param pop_len [IN] pop的长度 176 * @retval 成功返回被推入队列尾部的元素数量,最大为pop_len。 177 * @par 依赖:无。 178 * @li queue.h:该接口声明所在的文件。 179 * @see queue_pophead_pushtail_batch 180 */ 181 unsigned int queue_pophead_pushtail_batch(struct queue_s *target_queue, struct queue_s *local_queue, 182 unsigned int pop_len); 183 184 /** 185 * @ingroup queue 186 * @brief 从本地队列首部批量取出一半元素后将元素批量推入全局队列尾部。 187 * @par 描述:批量取出队列A首部元素推入队列B的尾部并返回取出元素的数量。 188 * @attention 入参queue不得为NULL,否则段错误,且queue必须已经初始化,仅支持单线程插入 189 * @param queue [IN] 要批量取出头部元素的队列。 190 * @param pop_len [IN] pop的长度 191 * @param qos [IN] 要被推入元素的优先级。 192 * @param func [IN] 被封装的推入队列B的操作。 193 * @par 依赖:无。 194 * @li queue.h:该接口声明所在的文件。 195 * @see queue_pophead_to_gqueue_batch 196 */ 197 typedef bool (*queue_push_task_func_t)(void* task, int qos); 198 void queue_pophead_to_gqueue_batch(struct queue_s* queue, unsigned int pop_len, int qos, queue_push_task_func_t func); 199 200 /** 201 * @ingroup queue 202 * @brief 销毁队列 203 * @par 描述:释放队列资源,销毁后不能访问,只释放结构体内数组,队列结构体需用户自己释放。 204 * @attention 入参queue不得为NULL,否则段错误,且queue必须已经初始化 205 * @param queue [IN] 要被销毁的队列。 206 * @retval 无 207 * @par 依赖:无。 208 * @li queue.h:该接口声明所在的文件。 209 * @see 210 */ 211 /* 销毁队列,销毁后不能再访问 */ 212 void queue_destroy(struct queue_s *queue); 213 214 /** 215 * @ingroup queue 216 * @brief 初始化队列 217 * @par 描述:初始化指定队列。 218 * @attention 入参queue不得为NULL,否则段错误, capacity非0 219 * @param queue [IN] 将被初始化的队列 220 * @param capacity [IN] 新建队列的容量。 221 * @retval 成功返回0,失败返回错误码。 222 * @par 依赖:无。 223 * @li queue.h:该接口声明所在的文件。 224 * @see 225 */ 226 int queue_init(struct queue_s *queue, unsigned int capacity); 227 228 /** 229 * 估计偷取概率,取值为0-100 230 */ 231 unsigned int queue_prob(struct queue_s *queue); 232 #endif 233 #ifdef __cplusplus 234 #if __cplusplus 235 } 236 #endif 237 #endif 238 #endif /* _QUEUE_H */ 239 240