18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Simple pointer stack 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "pstack.h" 98c2ecf20Sopenharmony_ci#include "debug.h" 108c2ecf20Sopenharmony_ci#include <linux/kernel.h> 118c2ecf20Sopenharmony_ci#include <linux/zalloc.h> 128c2ecf20Sopenharmony_ci#include <stdlib.h> 138c2ecf20Sopenharmony_ci#include <string.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistruct pstack { 168c2ecf20Sopenharmony_ci unsigned short top; 178c2ecf20Sopenharmony_ci unsigned short max_nr_entries; 188c2ecf20Sopenharmony_ci void *entries[]; 198c2ecf20Sopenharmony_ci}; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistruct pstack *pstack__new(unsigned short max_nr_entries) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci struct pstack *pstack = zalloc((sizeof(*pstack) + 248c2ecf20Sopenharmony_ci max_nr_entries * sizeof(void *))); 258c2ecf20Sopenharmony_ci if (pstack != NULL) 268c2ecf20Sopenharmony_ci pstack->max_nr_entries = max_nr_entries; 278c2ecf20Sopenharmony_ci return pstack; 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_civoid pstack__delete(struct pstack *pstack) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci free(pstack); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cibool pstack__empty(const struct pstack *pstack) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci return pstack->top == 0; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_civoid pstack__remove(struct pstack *pstack, void *key) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci unsigned short i = pstack->top, last_index = pstack->top - 1; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci while (i-- != 0) { 458c2ecf20Sopenharmony_ci if (pstack->entries[i] == key) { 468c2ecf20Sopenharmony_ci if (i < last_index) 478c2ecf20Sopenharmony_ci memmove(pstack->entries + i, 488c2ecf20Sopenharmony_ci pstack->entries + i + 1, 498c2ecf20Sopenharmony_ci (last_index - i) * sizeof(void *)); 508c2ecf20Sopenharmony_ci --pstack->top; 518c2ecf20Sopenharmony_ci return; 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci pr_err("%s: %p not on the pstack!\n", __func__, key); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_civoid pstack__push(struct pstack *pstack, void *key) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci if (pstack->top == pstack->max_nr_entries) { 608c2ecf20Sopenharmony_ci pr_err("%s: top=%d, overflow!\n", __func__, pstack->top); 618c2ecf20Sopenharmony_ci return; 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci pstack->entries[pstack->top++] = key; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_civoid *pstack__pop(struct pstack *pstack) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci void *ret; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (pstack->top == 0) { 718c2ecf20Sopenharmony_ci pr_err("%s: underflow!\n", __func__); 728c2ecf20Sopenharmony_ci return NULL; 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci ret = pstack->entries[--pstack->top]; 768c2ecf20Sopenharmony_ci pstack->entries[pstack->top] = NULL; 778c2ecf20Sopenharmony_ci return ret; 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_civoid *pstack__peek(struct pstack *pstack) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci if (pstack->top == 0) 838c2ecf20Sopenharmony_ci return NULL; 848c2ecf20Sopenharmony_ci return pstack->entries[pstack->top - 1]; 858c2ecf20Sopenharmony_ci} 86