blob: 95754b339f9ff35aa35481a8b7d286f5baeb7ff9 [file] [log] [blame]
Song Zhaoc03ba122020-12-23 21:54:02 -08001/*
bo.xiao00387eb2023-02-24 18:44:29 +08002 * Copyright (C) 2021 Amlogic Corporation.
Song Zhaoc03ba122020-12-23 21:54:02 -08003 *
bo.xiao00387eb2023-02-24 18:44:29 +08004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Song Zhaoc03ba122020-12-23 21:54:02 -080015 *
16 * Description: fifo implementation for single reader single writer
17 * Author: song.zhao@amlogic.com
18 */
19#include <stdbool.h>
20#include <stdlib.h>
21#include <stdio.h>
sheng.liu75a36d12023-07-28 07:54:03 +000022#include <stdatomic.h>
Song Zhaoc03ba122020-12-23 21:54:02 -080023#include "aml_avsync.h"
Song Zhao4f632952021-12-16 09:00:18 -080024#include "aml_queue.h"
Song Zhaoc03ba122020-12-23 21:54:02 -080025
26struct queue {
27 int max_len;
28 int ri; //read index
29 int wi; //write index
sheng.liu75a36d12023-07-28 07:54:03 +000030 atomic_intptr_t *items;
Song Zhaoc03ba122020-12-23 21:54:02 -080031};
32
33void* create_q(int max_len)
34{
35 struct queue *q;
36
37 if (max_len <= 0) {
38 printf("%s %d invalid max_len:%d\n",
39 __func__, __LINE__, max_len);
40 return NULL;
41 }
42
43 q = (struct queue*)calloc(1, sizeof(*q));
44 if (!q) {
45 printf("%s %d OOM\n", __func__, __LINE__);
46 return NULL;
47 }
sheng.liu75a36d12023-07-28 07:54:03 +000048 q->items = (atomic_intptr_t *)calloc(max_len, sizeof(void *));
Song Zhaoc03ba122020-12-23 21:54:02 -080049 if (!q->items) {
50 printf("%s %d OOM\n", __func__, __LINE__);
51 free(q);
52 return NULL;
53 }
54
55 q->max_len = max_len;
56 q->ri = q->wi = 0;
Song Zhaoc03ba122020-12-23 21:54:02 -080057 return q;
58}
59
60void destroy_q(void * queue)
61{
62 struct queue *q = queue;
63
64 if (!q)
65 return;
66 free(q->items);
67 free(q);
68}
69
70int queue_item(void *queue, void * item)
71{
72 struct queue *q = queue;
yongchun.li0ee6e372021-08-20 04:26:04 -070073 int fullness;
Song Zhaoc03ba122020-12-23 21:54:02 -080074
yongchun.li0ee6e372021-08-20 04:26:04 -070075 if (!q)
Song Zhaoc03ba122020-12-23 21:54:02 -080076 return -1;
yongchun.li0ee6e372021-08-20 04:26:04 -070077 fullness = q->wi - q->ri;
78 if (fullness < 0) fullness += q->max_len;
79 if (fullness >= q->max_len - 1)
80 return -1; // not enough space
81
sheng.liu75a36d12023-07-28 07:54:03 +000082 atomic_store(&q->items[q->wi], (atomic_intptr_t)item);
83
84 if (q->wi >= q->max_len - 1)
Song Zhaoc03ba122020-12-23 21:54:02 -080085 q->wi = 0;
86 else
87 q->wi++;
Song Zhaoc03ba122020-12-23 21:54:02 -080088 return 0;
89}
90
91int peek_item(void *queue, void** p_item, uint32_t cnt)
92{
93 struct queue *q = queue;
94 int32_t index;
yongchun.li0ee6e372021-08-20 04:26:04 -070095 int fullness;
Song Zhaoc03ba122020-12-23 21:54:02 -080096
yongchun.li0ee6e372021-08-20 04:26:04 -070097 if (!q)
Song Zhaoc03ba122020-12-23 21:54:02 -080098 return -1;
99
yongchun.li0ee6e372021-08-20 04:26:04 -0700100 fullness = q->wi - q->ri;
101 if (fullness < 0) fullness += q->max_len;
102 if (fullness == 0 || fullness <= cnt)
103 return -1; //no enough to peek
Song Zhaoc03ba122020-12-23 21:54:02 -0800104 index = q->ri;
105 index += cnt;
106 if (index >= q->max_len)
107 index -= q->max_len;
Song Zhaoc03ba122020-12-23 21:54:02 -0800108
sheng.liu75a36d12023-07-28 07:54:03 +0000109 *p_item = (void *)atomic_load(&q->items[index]);
110
111 if (*p_item != NULL)
112 return 0;
113 else
114 return -1;
Song Zhaoc03ba122020-12-23 21:54:02 -0800115}
116
117int dqueue_item(void *queue, void** p_item)
118{
119 struct queue *q = queue;
yongchun.li0ee6e372021-08-20 04:26:04 -0700120 int fullness;
Song Zhaoc03ba122020-12-23 21:54:02 -0800121
yongchun.li0ee6e372021-08-20 04:26:04 -0700122 if (!q)
Song Zhaoc03ba122020-12-23 21:54:02 -0800123 return -1;
yongchun.li0ee6e372021-08-20 04:26:04 -0700124 fullness = q->wi - q->ri;
125 if (fullness < 0) fullness += q->max_len;
126 if (fullness == 0)
127 return -1; //empty
sheng.liu75a36d12023-07-28 07:54:03 +0000128
129 *p_item = (void *)atomic_load(&q->items[q->ri]);
130 q->items[q->ri] = 0;
131
132 if (q->ri >= q->max_len - 1)
Song Zhaoc03ba122020-12-23 21:54:02 -0800133 q->ri = 0;
134 else
135 q->ri++;
Song Zhaoc03ba122020-12-23 21:54:02 -0800136 return 0;
137}
138
139int queue_size(void *queue)
140{
141 struct queue *q = queue;
yongchun.li0ee6e372021-08-20 04:26:04 -0700142 int fullness;
Song Zhaoc03ba122020-12-23 21:54:02 -0800143
144 if (!q)
145 return -1;
yongchun.li0ee6e372021-08-20 04:26:04 -0700146 fullness = q->wi - q->ri;
147 if (fullness < 0) fullness += q->max_len;
148 return fullness;
Song Zhaoc03ba122020-12-23 21:54:02 -0800149}