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 "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) {
return StorageGetById(h->storage, STORAGE_HOST, id);
return StorageGetById((Storage *)(h + HostStorageSize()), STORAGE_HOST, 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) {
StorageFreeById(h->storage, STORAGE_HOST, id);
StorageFreeById((Storage *)(h + HostStorageSize()), STORAGE_HOST, id);
}
void HostFreeStorage(Host *h) {
StorageFree(&h->storage, STORAGE_HOST);
StorageFreeAll((Storage *)(h + HostStorageSize()), STORAGE_HOST);
}
#ifdef UNITTESTS
static int HostStorageTest01(void) {
return 1;
}
#endif
void RegisterHostStorageTests(void) {
#ifdef UNITTESTS
UtRegisterTest("HostStorageTest01", HostStorageTest01, 1);
#endif
}

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

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

@ -31,7 +31,7 @@ typedef struct StorageMapping_ {
const char *name;
StorageEnum type; // host, flow, tx, stream, ssn, etc
unsigned int size;
int (*Init)(void *);
void *(*Init)(unsigned int);
void (*Free)(void *);
} StorageMapping;
@ -89,7 +89,7 @@ void StorageCleanup(void) {
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)
return -1;
@ -185,7 +185,21 @@ int StorageFinalize(void) {
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);
if (storage == NULL)
return NULL;
@ -206,7 +220,7 @@ void *StorageAllocById(Storage **storage, StorageEnum type, int id) {
SCLogDebug("store %p", store);
if (store[id] == NULL) {
store[id] = SCMalloc(map->size);
store[id] = map->Init(map->size);
if (store[id] == NULL) {
SCFree(store);
*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;
return store[id];
}
@ -233,12 +241,26 @@ void StorageFreeById(Storage *storage, StorageEnum type, int id) {
SCLogDebug("store %p", store);
if (store[id] != NULL) {
map->Free(store[id]);
SCFree(store[id]);
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) {
if (*storage == NULL)
return;
@ -249,7 +271,6 @@ void StorageFree(Storage **storage, StorageEnum type) {
StorageMapping *map = &storage_map[type][i];
if (store[i] != NULL) {
map->Free(store[i]);
SCFree(store[i]);
store[i] = NULL;
}
}
@ -259,10 +280,13 @@ void StorageFree(Storage **storage, StorageEnum type) {
#ifdef UNITTESTS
static int StorageTestInit(void *x) {
return 0;
static void *StorageTestInit(unsigned int size) {
void *x = SCMalloc(size);
return x;
}
void StorageTestFree(void *x) {
if (x)
SCFree(x);
}
static int StorageTest01(void) {
@ -292,10 +316,11 @@ struct StorageTest02Data {
int abc;
};
static int StorageTest02Init(void *x) {
struct StorageTest02Data *data = (struct StorageTest02Data *)x;
data->abc = 1234;
return 0;
static void *StorageTest02Init(unsigned int size) {
struct StorageTest02Data *data = (struct StorageTest02Data *)SCMalloc(size);
if (data != NULL)
data->abc = 1234;
return (void *)data;
}
static int StorageTest02(void) {

@ -38,13 +38,17 @@ typedef void* Storage;
void StorageInit(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);
void *StorageGetById(Storage *storage, StorageEnum type, int id);
void *StorageAllocById(Storage **storage, StorageEnum type, int id);
void StorageFreeById(Storage *storage, StorageEnum type, int id);
void StorageFree(Storage **storage, StorageEnum type);
unsigned int StorageGetCnt(const StorageEnum type);
unsigned int StorageGetSize(const 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);
#endif

Loading…
Cancel
Save