1 /*
2 * Copyright (C) 2017-2018 NXP Semiconductors
3 *
4 * 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.
15 */
16
17 /*
18 ************************* Header Files ****************************************
19 */
20
21 /* System include files */
22
23 #include "phOsal_LinkList.h"
24
25 #include <cstring>
26
27 /**
28 * Structure for link list node
29 */
30 typedef struct phOsal_ListNode {
31 struct phOsal_ListNode* ps_next;
32 void* pvData;
33 } phOsal_ListNode_t;
34
35 /**
36 * Context structure for Link List
37 */
38 typedef struct phOsal_ListCtxt {
39 phOsal_ListCreateParams_t sListCreateParams;
40 phOsal_ListNode_t* psHead;
41 phOsal_ListNode_t* psTail;
42 uint32_t dwNumNodes;
43 } phOsal_ListCtxt_t;
44
45 #undef ALOGD
46 #define ALOGD
47
48 static OSALSTATUS phOsali_ListDeleteAllNodes(void* pvListHandle);
49
50 /**
51 * Create resources for linked list data structure
52 */
phOsal_ListCreate(void ** phListHandle,phOsal_ListCreateParams_t * psCreateParams)53 OSALSTATUS phOsal_ListCreate(void** phListHandle,
54 phOsal_ListCreateParams_t* psCreateParams) {
55 phOsal_ListCtxt_t* psListCtxt = NULL;
56 void* memHdl;
57
58 /*Input validity check*/
59 if (NULL == psCreateParams || NULL == phListHandle) {
60 return OSALSTATUS_INVALID_PARAMS;
61 } /* if(NULL == psCreateParams || NULL == ph_ll_handle)*/
62
63 /*Allocate memory to linked list context*/
64 memHdl = psCreateParams->memHdl;
65 psListCtxt = (phOsal_ListCtxt_t*)psCreateParams->MemAllocCb(
66 memHdl, sizeof(phOsal_ListCtxt_t));
67
68 if (NULL == psListCtxt) {
69 return OSALSTATUS_FAILED;
70 } /*if(NULL == psListCtxt)*/
71
72 memset(psListCtxt, 0, sizeof(phOsal_ListCtxt_t));
73
74 /*Copy required variables from inargs to context*/
75 memcpy(&(psListCtxt->sListCreateParams), psCreateParams,
76 sizeof(phOsal_ListCreateParams_t));
77
78 /*Initialize context variables*/
79 psListCtxt->psHead = NULL;
80 psListCtxt->psTail = NULL;
81 psListCtxt->dwNumNodes = 0;
82
83 /*Update the link list handle*/
84 *phListHandle = psListCtxt;
85
86 return OSALSTATUS_SUCCESS;
87 }
88
89 /**
90 * Insert an object/node into linkedlist
91 */
phOsal_ListInsertNode(void * pvListHandle,PHOSAL_LIST_POSITION_T eListPos,void * pvData)92 OSALSTATUS phOsal_ListInsertNode(void* pvListHandle,
93 PHOSAL_LIST_POSITION_T eListPos,
94 void* pvData) {
95 phOsal_ListCtxt_t* psListCtxt = (phOsal_ListCtxt_t*)pvListHandle;
96 phOsal_ListNode_t* psNodeTba = NULL; /*Node to be added*/
97
98 /*Validity check*/
99 if (NULL == pvListHandle) {
100 return OSALSTATUS_INVALID_PARAMS;
101 } /*if(NULL == pvListHandle)*/
102
103 /*Create new obj node to be added and update its parameters*/
104 psNodeTba = (phOsal_ListNode_t*)psListCtxt->sListCreateParams.MemAllocCb(
105 psListCtxt->sListCreateParams.memHdl, sizeof(phOsal_ListNode_t));
106
107 psNodeTba->ps_next = NULL;
108 psNodeTba->pvData = pvData;
109
110 switch (eListPos) /*Update head and tail pointers based on the position of
111 obj to be added*/
112 {
113 case PHOSAL_LIST_POS_TAIL: {
114 if (NULL == psListCtxt->psTail) {
115 /** First node is being added */
116 psListCtxt->psHead = psNodeTba;
117 psListCtxt->psTail = psNodeTba;
118 } else {
119 /** Node is being added to the tail of the list */
120 psListCtxt->psTail->ps_next = psNodeTba;
121 psListCtxt->psTail = psNodeTba;
122 } /*if (NULL == psListCtxt->psTail)*/
123
124 break;
125 } /*case PHOSAL_LIST_POS_TAIL:*/
126 case PHOSAL_LIST_POS_HEAD: {
127 if (NULL == psListCtxt->psHead) {
128 /** First node is being added */
129 psListCtxt->psHead = psNodeTba;
130 psListCtxt->psTail = psNodeTba;
131 } else {
132 /** Node is being added to the head of the list */
133 psNodeTba->ps_next = psListCtxt->psHead;
134 psListCtxt->psHead = psNodeTba;
135 } /*if (NULL == psListCtxt->psHead)*/
136 break;
137 } /*case PHOSAL_LIST_POS_HEAD:*/
138 case PHOSAL_LIST_POS_CUR: {
139 return OSALSTATUS_NOT_SUPPORTED;
140 ; /*TBD: Currently not supported*/
141 // break;
142 } /*case PHOSAL_LIST_POS_CUR:*/
143 case PHOSAL_LIST_POS_NEXT: {
144 return OSALSTATUS_NOT_SUPPORTED;
145 ; /*TBD: Currently not supported*/
146 // break;
147 } /*case PHOSAL_LIST_POS_NEXT:*/
148 case PHOSAL_LIST_POS_PREV: {
149 return OSALSTATUS_NOT_SUPPORTED;
150 ; /*TBD: Currently not supported*/
151 break;
152 } /*case PHOSAL_LIST_POS_PREV:*/
153 default: {
154 return OSALSTATUS_INVALID_PARAMS;
155 } /*default*/
156 } /*switch(eListPos)*/
157
158 psListCtxt->dwNumNodes++;
159 return OSALSTATUS_SUCCESS;
160 }
161
162 /**
163 * Removes an object/node from linkedlist
164 */
phOsal_ListRemoveNode(void * pvListHandle,PHOSAL_LIST_POSITION_T eListPos,void ** ppvData)165 OSALSTATUS phOsal_ListRemoveNode(void* pvListHandle,
166 PHOSAL_LIST_POSITION_T eListPos,
167 void** ppvData) {
168 phOsal_ListCtxt_t* psListCtxt = (phOsal_ListCtxt_t*)pvListHandle;
169 phOsal_ListNode_t* psNodeTbd = NULL; /*Node to be deleted*/
170
171 /*Validity check*/
172 if (NULL == pvListHandle || NULL == ppvData) {
173 return OSALSTATUS_INVALID_PARAMS;
174 } /*if(NULL == pvListHandle || NULL == pvData)*/
175
176 switch (eListPos) /*Update head and tail pointers based on the position of
177 obj to be deleted*/
178 {
179 case PHOSAL_LIST_POS_HEAD: {
180 if (NULL == psListCtxt->psHead) { /** No elements in the list*/
181 *ppvData = NULL;
182 return OSALSTATUS_INVALID_PARAMS;
183 } else if (NULL ==
184 psListCtxt->psHead
185 ->ps_next) { /** There is only one object in the list*/
186 *ppvData = psListCtxt->psHead->pvData;
187 psNodeTbd = psListCtxt->psHead;
188 psListCtxt->psHead = NULL;
189 psListCtxt->psTail = NULL;
190 } else { /*There are more than one element in the list*/
191 *ppvData = psListCtxt->psHead->pvData;
192 psNodeTbd = psListCtxt->psHead;
193 psListCtxt->psHead = psListCtxt->psHead->ps_next;
194 } /*if (NULL == psListCtxt->psHead)*/
195
196 break;
197 }
198 case PHOSAL_LIST_POS_TAIL: {
199 if (NULL == psListCtxt->psTail) { /** No elements in the list*/
200 *ppvData = NULL;
201 return OSALSTATUS_INVALID_PARAMS;
202 } else if (NULL ==
203 psListCtxt->psHead
204 ->ps_next) { /** There is only one object in the list*/
205
206 *ppvData = psListCtxt->psHead->pvData;
207 psNodeTbd = psListCtxt->psHead;
208 psListCtxt->psHead = NULL;
209 psListCtxt->psTail = NULL;
210 } else { /*There are more than one element in the list*/
211 phOsal_ListNode_t* ps_ll_node = NULL;
212 phOsal_ListNode_t* ps_ll_node_prev = NULL;
213
214 ps_ll_node = psListCtxt->psHead;
215
216 /*Traverse till the end of the link list*/
217 while (NULL != ps_ll_node->ps_next) {
218 ps_ll_node_prev = ps_ll_node;
219 ps_ll_node = ps_ll_node->ps_next;
220 } /*while(NULL != ps_ll_node->ps_next)*/
221
222 *ppvData = ps_ll_node->pvData;
223 psNodeTbd = ps_ll_node;
224 psListCtxt->psTail = ps_ll_node_prev;
225
226 } /*if (NULL == psListCtxt->psTail)*/
227 break;
228 }
229 case PHOSAL_LIST_POS_CUR: {
230 return OSALSTATUS_NOT_SUPPORTED;
231 ; /*TBD: Currently not supported*/
232 // break;
233 } /*case PHOSAL_LIST_POS_CUR:*/
234 case PHOSAL_LIST_POS_NEXT: {
235 return OSALSTATUS_NOT_SUPPORTED;
236 ; /*TBD: Currently not supported*/
237 // break;
238 } /*case PHOSAL_LIST_POS_NEXT:*/
239 case PHOSAL_LIST_POS_PREV: {
240 return OSALSTATUS_NOT_SUPPORTED;
241 ; /*TBD: Currently not supported*/
242 // break;
243 } /*case PHOSAL_LIST_POS_PREV:*/
244 default: {
245 return OSALSTATUS_INVALID_PARAMS;
246 } /*default:*/
247 } /*switch(eListPos)*/
248
249 { /*Free up the memory for the node to be deleted*/
250
251 psListCtxt->sListCreateParams.MemFreeCb(
252 psListCtxt->sListCreateParams.memHdl, psNodeTbd);
253
254 psListCtxt->dwNumNodes--;
255 }
256 return OSALSTATUS_SUCCESS;
257 }
258
259 /**
260 * Destroy the linkedlist
261 */
phOsal_ListDestroy(void * pvListHandle)262 OSALSTATUS phOsal_ListDestroy(void* pvListHandle) {
263 phOsal_ListCtxt_t* psListCtxt = (phOsal_ListCtxt_t*)pvListHandle;
264
265 /*Validity check*/
266 if (NULL == pvListHandle) {
267 return OSALSTATUS_INVALID_PARAMS;
268 } /*if(NULL == pvListHandle)*/
269
270 /*Delete all nodes*/
271 phOsali_ListDeleteAllNodes(psListCtxt);
272
273 { /*Free up memory to queue context*/
274
275 psListCtxt->sListCreateParams.MemFreeCb(
276 psListCtxt->sListCreateParams.memHdl, psListCtxt);
277
278 psListCtxt = NULL;
279 }
280
281 return OSALSTATUS_SUCCESS;
282 }
283
284 /**
285 * Flush all objects/nodes in the linked list
286 */
phOsal_ListFlush(void * pvListHandle)287 OSALSTATUS phOsal_ListFlush(void* pvListHandle) {
288 phOsal_ListCtxt_t* psListCtxt = (phOsal_ListCtxt_t*)pvListHandle;
289 /*Validity check*/
290 if (NULL == pvListHandle) {
291 return OSALSTATUS_INVALID_PARAMS;
292 } /*if(NULL == pvListHandle)*/
293
294 /*Delete all nodes*/
295 phOsali_ListDeleteAllNodes(psListCtxt);
296
297 /*Update the link list context*/
298 psListCtxt->psHead = NULL;
299 psListCtxt->psTail = NULL;
300 psListCtxt->dwNumNodes = 0;
301
302 return OSALSTATUS_SUCCESS;
303 }
304
305 /**
306 * Flush all objects/nodes in the linked list
307 */
phOsali_ListDeleteAllNodes(void * pvListHandle)308 OSALSTATUS phOsali_ListDeleteAllNodes(void* pvListHandle) {
309 phOsal_ListCtxt_t* psListCtxt = (phOsal_ListCtxt_t*)pvListHandle;
310 phOsal_ListNode_t* psNodeTbd = NULL; /*Node to be deleted*/
311
312 /*Delete all nodes*/
313 if (psListCtxt->psHead) { /*Atleast one element exists in the list*/
314 while (NULL !=
315 psListCtxt->psHead) { /*Delete all nodes until head becomes null*/
316 psNodeTbd = psListCtxt->psHead;
317
318 psListCtxt->psHead = psListCtxt->psHead->ps_next;
319
320 /*Free up memory of the node to be deleted*/
321 psListCtxt->sListCreateParams.MemFreeCb(
322 psListCtxt->sListCreateParams.memHdl, psNodeTbd);
323 } /*while(NULL != psListCtxt->psHead)*/
324 } /*if(psListCtxt->psHead)*/
325
326 return OSALSTATUS_SUCCESS;
327 }
328
329 /* nothing past this point */
330