suricata
thread-storage.c
Go to the documentation of this file.
1/* Copyright (C) 2024 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include "suricata-common.h"
19#include "thread-storage.h"
20#include "util-storage.h"
21#include "util-unittest.h"
22
24
25unsigned int ThreadStorageSize(void)
26{
28}
29
34
36{
37 return StorageSetById(tv->storage, storage_type, id.id, ptr);
38}
39
44
49
55
56ThreadStorageId ThreadStorageRegister(const char *name, const unsigned int size,
57 void *(*Alloc)(unsigned int), void (*Free)(void *))
58{
59 int id = StorageRegister(storage_type, name, size, Alloc, Free);
60 ThreadStorageId tsi = { .id = id };
61 return tsi;
62}
63
64#ifdef UNITTESTS
65
66static void *StorageTestAlloc(unsigned int size)
67{
68 return SCCalloc(1, size);
69}
70
71static void StorageTestFree(void *x)
72{
73 SCFree(x);
74}
75
76static int ThreadStorageTest01(void)
77{
79
80 ThreadStorageId id1 = ThreadStorageRegister("test", 8, StorageTestAlloc, StorageTestFree);
81 FAIL_IF(id1.id < 0);
82
83 ThreadStorageId id2 = ThreadStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree);
84 FAIL_IF(id2.id < 0);
85
86 ThreadStorageId id3 =
87 ThreadStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree);
88 FAIL_IF(id3.id < 0);
89
91
94
95 void *ptr = ThreadGetStorageById(tv, id1);
97
98 ptr = ThreadGetStorageById(tv, id2);
100
101 ptr = ThreadGetStorageById(tv, id3);
102 FAIL_IF_NOT_NULL(ptr);
103
104 void *ptr1a = ThreadAllocStorageById(tv, id1);
105 FAIL_IF_NULL(ptr1a);
106
107 void *ptr2a = ThreadAllocStorageById(tv, id2);
108 FAIL_IF_NULL(ptr2a);
109
110 void *ptr3a = ThreadAllocStorageById(tv, id3);
111 FAIL_IF_NULL(ptr3a);
112
113 void *ptr1b = ThreadGetStorageById(tv, id1);
114 FAIL_IF(ptr1a != ptr1b);
115
116 void *ptr2b = ThreadGetStorageById(tv, id2);
117 FAIL_IF(ptr2a != ptr2b);
118
119 void *ptr3b = ThreadGetStorageById(tv, id3);
120 FAIL_IF(ptr3a != ptr3b);
121
124 SCFree(tv);
125 PASS;
126}
127
128static int ThreadStorageTest02(void)
129{
130 StorageInit();
131
132 ThreadStorageId id1 = ThreadStorageRegister("test", sizeof(void *), NULL, StorageTestFree);
133 FAIL_IF(id1.id < 0);
134
136
139
140 void *ptr = ThreadGetStorageById(tv, id1);
141 FAIL_IF_NOT_NULL(ptr);
142
143 void *ptr1a = SCMalloc(128);
144 FAIL_IF_NULL(ptr1a);
145
146 ThreadSetStorageById(tv, id1, ptr1a);
147
148 void *ptr1b = ThreadGetStorageById(tv, id1);
149 FAIL_IF(ptr1a != ptr1b);
150
153 PASS;
154}
155
156static int ThreadStorageTest03(void)
157{
158 StorageInit();
159
160 ThreadStorageId id1 = ThreadStorageRegister("test1", sizeof(void *), NULL, StorageTestFree);
161 FAIL_IF(id1.id < 0);
162
163 ThreadStorageId id2 = ThreadStorageRegister("test2", sizeof(void *), NULL, StorageTestFree);
164 FAIL_IF(id2.id < 0);
165
166 ThreadStorageId id3 = ThreadStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree);
167 FAIL_IF(id3.id < 0);
168
170
173
174 void *ptr = ThreadGetStorageById(tv, id1);
175 FAIL_IF_NOT_NULL(ptr);
176
177 void *ptr1a = SCMalloc(128);
178 FAIL_IF_NULL(ptr1a);
179
180 ThreadSetStorageById(tv, id1, ptr1a);
181
182 void *ptr2a = SCMalloc(256);
183 FAIL_IF_NULL(ptr2a);
184
185 ThreadSetStorageById(tv, id2, ptr2a);
186
187 void *ptr3a = ThreadAllocStorageById(tv, id3);
188 FAIL_IF_NULL(ptr3a);
189
190 void *ptr1b = ThreadGetStorageById(tv, id1);
191 FAIL_IF(ptr1a != ptr1b);
192
193 void *ptr2b = ThreadGetStorageById(tv, id2);
194 FAIL_IF(ptr2a != ptr2b);
195
196 void *ptr3b = ThreadGetStorageById(tv, id3);
197 FAIL_IF(ptr3a != ptr3b);
198
201 PASS;
202}
203#endif
204
206{
207#ifdef UNITTESTS
208 UtRegisterTest("ThreadStorageTest01", ThreadStorageTest01);
209 UtRegisterTest("ThreadStorageTest02", ThreadStorageTest02);
210 UtRegisterTest("ThreadStorageTest03", ThreadStorageTest03);
211#endif
212}
ThreadVars * tv
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Per thread variable structure.
Definition threadvars.h:58
Storage storage[]
Definition threadvars.h:141
void RegisterThreadStorageTests(void)
void ThreadFreeStorageById(ThreadVars *tv, ThreadStorageId id)
unsigned int ThreadStorageSize(void)
void * ThreadGetStorageById(const ThreadVars *tv, ThreadStorageId id)
ThreadStorageId ThreadStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
void * ThreadAllocStorageById(ThreadVars *tv, ThreadStorageId id)
const StorageEnum storage_type
int ThreadSetStorageById(ThreadVars *tv, ThreadStorageId id, void *ptr)
void ThreadFreeStorage(ThreadVars *tv)
const char * name
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
void * StorageGetById(const Storage *storage, const StorageEnum type, const int id)
get storage for id
void StorageCleanup(void)
int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register new storage.
unsigned int StorageGetSize(StorageEnum type)
get the size of the void array used to store the pointers
void StorageFreeAll(Storage *storage, StorageEnum type)
void StorageFreeById(Storage *storage, StorageEnum type, int id)
int StorageFinalize(void)
int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr)
set storage for id
void StorageInit(void)
void * StorageAllocByIdPrealloc(Storage *storage, StorageEnum type, int id)
AllocById func for prealloc'd base storage (storage ptrs are part of another memory block)
enum StorageEnum_ StorageEnum
@ STORAGE_THREAD