storage: allow preallocated storage

pull/466/head
Victor Julien 13 years ago
parent e2b006f523
commit b5ccf0b9c7

@ -25,30 +25,36 @@
#include "suricata-common.h" #include "suricata-common.h"
#include "host-storage.h" #include "host-storage.h"
#include "util-unittests.h" #include "util-unittest.h"
unsigned int HostStorageSize(void) {
return StorageGetSize(STORAGE_HOST);
}
void *HostGetStorageById(Host *h, int id) { void *HostGetStorageById(Host *h, int id) {
return StorageGetById(h->storage, STORAGE_HOST, id); return StorageGetById((Storage *)(h + HostStorageSize()), STORAGE_HOST, id);
} }
void *HostAllocStorageById(Host *h, int id) { void *HostAllocStorageById(Host *h, int id) {
return StorageAllocById(&h->storage, STORAGE_HOST, id); return StorageAllocById((Storage **)&h + HostStorageSize(), STORAGE_HOST, id);
} }
void HostFreeStorageById(Host *h, int id) { void HostFreeStorageById(Host *h, int id) {
StorageFreeById(h->storage, STORAGE_HOST, id); StorageFreeById((Storage *)(h + HostStorageSize()), STORAGE_HOST, id);
} }
void HostFreeStorage(Host *h) { void HostFreeStorage(Host *h) {
StorageFree(&h->storage, STORAGE_HOST); StorageFreeAll((Storage *)(h + HostStorageSize()), STORAGE_HOST);
} }
#ifdef UNITTESTS #ifdef UNITTESTS
static int HostStorageTest01(void) {
return 1;
}
#endif #endif
void RegisterHostStorageTests(void) { void RegisterHostStorageTests(void) {
#ifdef UNITTESTS #ifdef UNITTESTS
UtRegisterTest("HostStorageTest01", HostStorageTest01, 1);
#endif #endif
} }

@ -23,11 +23,20 @@
* Host wrapper around storage api * Host wrapper around storage api
*/ */
#ifndef __HOST_STORAGE_H__
#define __HOST_STORAGE_H__
#include "util-storage.h" #include "util-storage.h"
#include "host.h" #include "host.h"
unsigned int HostStorageSize(void);
void *HostGetStorageById(Host *h, int id); void *HostGetStorageById(Host *h, int id);
void *HostAllocStorageById(Host *h, int id); void *HostAllocStorageById(Host *h, int id);
void HostFreeStorageById(Host *h, int id); void HostFreeStorageById(Host *h, int id);
void HostFreeStorage(Host *h); void HostFreeStorage(Host *h);
void RegisterHostStorageTests(void);
#endif /* __HOST_STORAGE_H__ */

@ -28,6 +28,7 @@
#include "util-debug.h" #include "util-debug.h"
#include "host.h" #include "host.h"
#include "host-storage.h"
#include "util-random.h" #include "util-random.h"
#include "util-misc.h" #include "util-misc.h"
@ -55,17 +56,19 @@ void HostMoveToSpare(Host *h) {
} }
Host *HostAlloc(void) { Host *HostAlloc(void) {
if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) { size_t size = sizeof(Host) + HostStorageSize();
if (!(HOST_CHECK_MEMCAP(size))) {
return NULL; return NULL;
} }
(void) SC_ATOMIC_ADD(host_memuse, sizeof(Host)); (void) SC_ATOMIC_ADD(host_memuse, size);
Host *h = SCMalloc(sizeof(Host)); Host *h = SCMalloc(size);
if (unlikely(h == NULL)) if (unlikely(h == NULL))
goto error; goto error;
memset(h, 0x00, sizeof(Host)); memset(h, 0x00, size);
SCMutexInit(&h->m, NULL); SCMutexInit(&h->m, NULL);
SC_ATOMIC_INIT(h->use_cnt); SC_ATOMIC_INIT(h->use_cnt);
@ -82,7 +85,7 @@ void HostFree(Host *h) {
SC_ATOMIC_DESTROY(h->use_cnt); SC_ATOMIC_DESTROY(h->use_cnt);
SCMutexDestroy(&h->m); SCMutexDestroy(&h->m);
SCFree(h); SCFree(h);
(void) SC_ATOMIC_SUB(host_memuse, sizeof(Host)); (void) SC_ATOMIC_SUB(host_memuse, (sizeof(Host) + HostStorageSize()));
} }
} }
@ -113,6 +116,9 @@ void HostClearMemory(Host *h) {
SCFree(h->iprep); SCFree(h->iprep);
h->iprep = NULL; h->iprep = NULL;
} }
if (HostStorageSize() > 0)
HostFreeStorage(h);
} }
#define HOST_DEFAULT_HASHSIZE 4096 #define HOST_DEFAULT_HASHSIZE 4096
@ -673,4 +679,7 @@ static Host *HostGetUsedHost(void) {
return NULL; return NULL;
} }
void HostRegisterUnittests(void) {
RegisterHostStorageTests();
}

@ -31,7 +31,7 @@ typedef struct StorageMapping_ {
const char *name; const char *name;
StorageEnum type; // host, flow, tx, stream, ssn, etc StorageEnum type; // host, flow, tx, stream, ssn, etc
unsigned int size; unsigned int size;
int (*Init)(void *); void *(*Init)(unsigned int);
void (*Free)(void *); void (*Free)(void *);
} StorageMapping; } StorageMapping;
@ -89,7 +89,7 @@ void StorageCleanup(void) {
storage_list = NULL; storage_list = NULL;
} }
int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, int (*Init)(void *), void (*Free)(void *)) { int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Init)(unsigned int), void (*Free)(void *)) {
if (storage_registraton_closed) if (storage_registraton_closed)
return -1; return -1;
@ -185,7 +185,21 @@ int StorageFinalize(void) {
return 0; return 0;
} }
void *StorageGetById(Storage *storage, StorageEnum type, int id) { unsigned int StorageGetCnt(StorageEnum type) {
return storage_max_id[type];
}
/** \brief get the size of the void array used to store
* the pointers
* \retval size size in bytes, can return 0 if not storage is needed
*
* \todo we could return -1 when registration isn't closed yet, however
* this will break lots of tests currently, so not doing it now */
unsigned int StorageGetSize(StorageEnum type) {
return storage_max_id[type] * sizeof(void *);
}
void *StorageGetById(const Storage *storage, const StorageEnum type, const int id) {
SCLogDebug("storage %p id %d", storage, id); SCLogDebug("storage %p id %d", storage, id);
if (storage == NULL) if (storage == NULL)
return NULL; return NULL;
@ -206,7 +220,7 @@ void *StorageAllocById(Storage **storage, StorageEnum type, int id) {
SCLogDebug("store %p", store); SCLogDebug("store %p", store);
if (store[id] == NULL) { if (store[id] == NULL) {
store[id] = SCMalloc(map->size); store[id] = map->Init(map->size);
if (store[id] == NULL) { if (store[id] == NULL) {
SCFree(store); SCFree(store);
*storage = NULL; *storage = NULL;
@ -214,12 +228,6 @@ void *StorageAllocById(Storage **storage, StorageEnum type, int id) {
} }
} }
if (map->Init(store[id]) < 0) {
SCFree(store);
*storage = NULL;
return NULL;
}
*storage = store; *storage = store;
return store[id]; return store[id];
} }
@ -233,12 +241,26 @@ void StorageFreeById(Storage *storage, StorageEnum type, int id) {
SCLogDebug("store %p", store); SCLogDebug("store %p", store);
if (store[id] != NULL) { if (store[id] != NULL) {
map->Free(store[id]); map->Free(store[id]);
SCFree(store[id]);
store[id] = NULL; store[id] = NULL;
} }
} }
} }
void StorageFreeAll(Storage *storage, StorageEnum type) {
if (*storage == NULL)
return;
Storage *store = storage;
int i;
for (i = 0; i < storage_max_id[type]; i++) {
StorageMapping *map = &storage_map[type][i];
if (store[i] != NULL) {
map->Free(store[i]);
store[i] = NULL;
}
}
}
void StorageFree(Storage **storage, StorageEnum type) { void StorageFree(Storage **storage, StorageEnum type) {
if (*storage == NULL) if (*storage == NULL)
return; return;
@ -249,7 +271,6 @@ void StorageFree(Storage **storage, StorageEnum type) {
StorageMapping *map = &storage_map[type][i]; StorageMapping *map = &storage_map[type][i];
if (store[i] != NULL) { if (store[i] != NULL) {
map->Free(store[i]); map->Free(store[i]);
SCFree(store[i]);
store[i] = NULL; store[i] = NULL;
} }
} }
@ -259,10 +280,13 @@ void StorageFree(Storage **storage, StorageEnum type) {
#ifdef UNITTESTS #ifdef UNITTESTS
static int StorageTestInit(void *x) { static void *StorageTestInit(unsigned int size) {
return 0; void *x = SCMalloc(size);
return x;
} }
void StorageTestFree(void *x) { void StorageTestFree(void *x) {
if (x)
SCFree(x);
} }
static int StorageTest01(void) { static int StorageTest01(void) {
@ -292,10 +316,11 @@ struct StorageTest02Data {
int abc; int abc;
}; };
static int StorageTest02Init(void *x) { static void *StorageTest02Init(unsigned int size) {
struct StorageTest02Data *data = (struct StorageTest02Data *)x; struct StorageTest02Data *data = (struct StorageTest02Data *)SCMalloc(size);
data->abc = 1234; if (data != NULL)
return 0; data->abc = 1234;
return (void *)data;
} }
static int StorageTest02(void) { static int StorageTest02(void) {

@ -38,13 +38,17 @@ typedef void* Storage;
void StorageInit(void); void StorageInit(void);
void StorageCleanup(void); void StorageCleanup(void);
int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, int (*Init)(void *), void (*Free)(void *)); int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Init)(unsigned int), void (*Free)(void *));
int StorageFinalize(void); int StorageFinalize(void);
void *StorageGetById(Storage *storage, StorageEnum type, int id); unsigned int StorageGetCnt(const StorageEnum type);
void *StorageAllocById(Storage **storage, StorageEnum type, int id); unsigned int StorageGetSize(const StorageEnum type);
void StorageFreeById(Storage *storage, StorageEnum type, int id);
void StorageFree(Storage **storage, StorageEnum type); void *StorageGetById(const Storage *storage, const StorageEnum type, const int id);
void *StorageAllocById(Storage **storage, const StorageEnum type, const int id);
void StorageFreeById(Storage *storage, const StorageEnum type, const int id);
void StorageFreeAll(Storage *storage, const StorageEnum type);
void StorageFree(Storage **storage, const StorageEnum type);
void StorageRegisterTests(void); void StorageRegisterTests(void);
#endif #endif

Loading…
Cancel
Save