1 /* 2 * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. 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 #ifndef SHAREDEFS_H_ 19 #define SHAREDEFS_H_ 20 21 /* 22 * STG_DECLARE(name, datatype, indextype) - declare structure 23 * STG_ALLOC(name, size) - allocate 24 * STG_CLEAR(name) - clear all fields up to stg_avail 25 * STG_DELETE(name) - deallocate 26 * STG_RESET(name) - reset stg_avail 27 * i = STG_NEXT(name) - return next available index (no free list) 28 * i = STG_NEXT_SIZE(name, size) - return next available index, allocate size 29 * i = STG_NEXT_FREELIST(name) - return index from free list 30 * STG_NEED(name) - test avail vs size, realloc if needed 31 * STG_RETURN(name) - return lastest added element 32 * STG_ADD_FREELIST(name, i) - add to free list 33 * STG_ALLOC_SIDECAR(basename, name, datatype) 34 * allocate name the same size as basename 35 * register name on the sidecar list of basename 36 * STG_DELETE_SIDECAR(basename, name) 37 * remove name from the sidecar list of basename 38 * deallocate name 39 */ 40 41 /* declare: 42 * struct{ 43 * dt* stg_base; 44 * unsigned int stg_size, stg_avail, stg_free, stg_cleared, 45 * stg_dtsize; 46 * void* stg_sidecar; * }name; */ 47 48 /* declare the stg_ members; useful in a struct that also has other members */ 49 #define STG_MEMBERS(dt) \ 50 dt *stg_base; \ 51 unsigned int stg_size, stg_avail, stg_free, stg_cleared, stg_dtsize, \ 52 stg_freelink_offset, stg_flags; \ 53 const char *stg_name; \ 54 void *stg_sidecar 55 56 /* to statically initialize STG_MEMBERS */ 57 #define STG_INIT NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL 58 59 /* declare a struct with the stg_members */ 60 #define STG_DECLARE(name, dt) \ 61 struct { \ 62 STG_MEMBERS(dt); \ 63 } name 64 65 typedef STG_DECLARE(STG, void); 66 67 /* allocate the above structure 68 * clear all fields 69 * allocate stg_base 70 * set stg_size, stg_avail 71 * clear element zero */ 72 void stg_alloc(STG *stg, int dtsize, int size, const char *name); 73 #define STG_ALLOC(name, size) \ 74 stg_alloc((STG *)&name.stg_base, sizeof(name.stg_base[0]), size, #name) 75 76 /* clear a single field */ 77 void stg_clear(STG *stg, int r, int n); 78 #define STG_CLEAR(name, r) stg_clear((STG *)&name.stg_base, r, 1) 79 80 /* clear a number of fields */ 81 #define STG_CLEAR_N(name, r, n) stg_clear((STG *)&name.stg_base, r, n) 82 83 /* clear all allocated fields */ 84 void stg_clear_all(STG *stg); 85 #define STG_CLEAR_ALL(name) stg_clear_all((STG *)&name.stg_base); 86 87 /* delete the data structure */ 88 void stg_delete(STG *stg); 89 #define STG_DELETE(name) stg_delete((STG *)&name.stg_base); 90 91 /* reset the data structure */ 92 void stg_reset(STG *stg); 93 #define STG_RESET(name) stg_reset((STG *)&name.stg_base); 94 95 /* allocate one element at stg_avail */ 96 int stg_next(STG *stg, int n); 97 #define STG_NEXT(name) stg_next((STG *)&name.stg_base, 1) 98 99 /* allocate 'size' elements at stg_avail */ 100 #define STG_NEXT_SIZE(name, size) stg_next((STG *)&name.stg_base, size) 101 102 /* check that stg_avail does not overflow stg_size */ 103 void stg_need(STG *stg); 104 #define STG_NEED(name) stg_need((STG *)&name.stg_base) 105 106 /* set free link offset */ 107 void stg_set_freelink(STG *stg, int offset); 108 #define STG_SET_FREELINK(name, dt, field) \ 109 stg_set_freelink((STG *)&name.stg_base, offsetof(dt, field)) 110 111 /* get the next element from free list, if any, otherwise, from stg_avail */ 112 int stg_next_freelist(STG *stg); 113 #define STG_NEXT_FREELIST(name) stg_next_freelist((STG *)&name.stg_base) 114 115 /* return latest added field */ 116 void stg_return(STG *stg); 117 #define STG_RETURN(name) \ 118 stg_return((STG *)&name.stg_base) 119 120 /* put this element on the free list */ 121 void stg_add_freelist(STG *stg, int r); 122 #define STG_ADD_FREELIST(name, index) \ 123 stg_add_freelist((STG *)&name.stg_base, index) 124 125 /* allocate sidecar the same size as name */ 126 void stg_alloc_sidecar(STG *basestg, STG *stg, int dtsize, const char *name); 127 #define STG_ALLOC_SIDECAR(basename, name) \ 128 stg_alloc_sidecar((STG *)&basename.stg_base, (STG *)&name.stg_base, \ 129 sizeof(name.stg_base[0]), #name) 130 131 /* deallocate sidecar */ 132 void stg_delete_sidecar(STG *basestg, STG *stg); 133 #define STG_DELETE_SIDECAR(basename, name) \ 134 stg_delete_sidecar((STG *)&basename.stg_base, (STG *)&name.stg_base); 135 136 /* set a flag in stg_flags */ 137 #define STG_SETFLAG(name, flag) name.stg_flags |= (1 << (flag)) 138 139 /* test a flag in stg_flags */ 140 #define STG_CHECKFLAG(name, flag) (name.stg_flags & (1 << (flag))) 141 142 /* flags that can be set in stg_flags */ 143 #define STG_FLAG_NOCLEAR 0 144 #endif 145