cyclic_buffer.c (3492B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * SHARED CYCLIC BUFFER 9 */ 10 11 12 #include <shared/error.h> 13 #include <shared/cyclic_buffer.h> 14 #include <sal/core/alloc.h> 15 #include <sal/core/libc.h> 16 #include <soc/error.h> 17 18 19 int 20 cyclic_buffer_create(int unit, cyclic_buffer_t* buffer, int max_entry_size, int max_buffered_elements, char* buffer_name) 21 { 22 if(NULL == buffer) { 23 return _SHR_E_PARAM; 24 } 25 26 buffer->elements = (uint8*)sal_alloc(max_buffered_elements*max_entry_size,buffer_name); 27 if(NULL == buffer->elements) { 28 return _SHR_E_MEMORY; 29 } 30 31 buffer->oldest = 0; 32 buffer->count = 0; 33 buffer->max_allowed = max_buffered_elements; 34 buffer->entry_size = max_entry_size; 35 36 return _SHR_E_NONE; 37 } 38 39 int 40 cyclic_buffer_destroy(int unit, cyclic_buffer_t* buffer) 41 { 42 if(NULL == buffer) { 43 return _SHR_E_PARAM; 44 } 45 46 if(NULL != buffer->elements) { 47 SOC_FREE(buffer->elements); 48 } 49 buffer->elements = NULL; 50 buffer->oldest = 0; 51 buffer->count = 0; 52 buffer->max_allowed = 0; 53 buffer->entry_size = 0; 54 55 return _SHR_E_NONE; 56 } 57 58 int 59 cyclic_buffer_add(int unit, cyclic_buffer_t* buffer, const void* new_element) 60 { 61 int rc, is_full; 62 int free_pos; 63 64 if(NULL == buffer || NULL == new_element) { 65 return _SHR_E_PARAM; 66 } 67 68 if(NULL == buffer->elements) { 69 return _SHR_E_INIT; 70 } 71 72 rc = cyclic_buffer_is_full(unit, buffer, &is_full); 73 _SHR_E_IF_ERROR_RETURN(rc); 74 if(is_full) { 75 return _SHR_E_FULL; 76 } 77 78 free_pos = (buffer->oldest + buffer->count) % buffer->max_allowed; 79 sal_memcpy(&(buffer->elements[free_pos*buffer->entry_size]), (const uint8*)new_element, buffer->entry_size); 80 buffer->count++; 81 82 return _SHR_E_NONE; 83 } 84 85 int 86 cyclic_buffer_get(int unit, cyclic_buffer_t* buffer, void* received_element) 87 { 88 int rc, is_empty; 89 90 if(NULL == buffer || NULL == received_element) { 91 return _SHR_E_PARAM; 92 } 93 94 if(NULL == buffer->elements) { 95 return _SHR_E_INIT; 96 } 97 98 rc = cyclic_buffer_is_empty(unit, buffer, &is_empty); 99 _SHR_E_IF_ERROR_RETURN(rc); 100 if(is_empty) { 101 return _SHR_E_EMPTY; 102 } 103 104 sal_memcpy((uint8*)received_element, &(buffer->elements[buffer->oldest*buffer->entry_size]), buffer->entry_size); 105 buffer->oldest = (buffer->oldest+1) % buffer->max_allowed; 106 buffer->count--; 107 108 return _SHR_E_NONE; 109 } 110 111 int 112 cyclic_buffer_is_empty(int unit, const cyclic_buffer_t* buffer, int* is_empty) 113 { 114 if(NULL == buffer || NULL == is_empty) { 115 return _SHR_E_PARAM; 116 } 117 118 if(NULL == buffer->elements) { 119 return _SHR_E_INIT; 120 } 121 122 *is_empty = (0 == buffer->count ? 1 : 0); 123 124 return _SHR_E_NONE; 125 } 126 127 int 128 cyclic_buffer_is_full(int unit, const cyclic_buffer_t* buffer, int* is_full) 129 { 130 131 if(NULL == buffer || NULL == is_full) { 132 return _SHR_E_PARAM; 133 } 134 135 if(NULL == buffer->elements) { 136 return _SHR_E_INIT; 137 } 138 139 *is_full = (buffer->max_allowed == buffer->count ? 1 : 0); 140 141 return _SHR_E_NONE; 142 } 143 144 int 145 cyclic_buffer_cells_count(int unit, const cyclic_buffer_t* buffer, int* count) 146 { 147 if(NULL == buffer || NULL == count) { 148 return _SHR_E_PARAM; 149 } 150 151 if(NULL == buffer->elements) { 152 return _SHR_E_INIT; 153 } 154 155 *count = buffer->count; 156 157 return _SHR_E_NONE; 158 } 159 160