]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
storage: allow preallocated storage
authorVictor Julien <victor@inliniac.net>
Fri, 25 Jan 2013 13:28:41 +0000 (14:28 +0100)
committerVictor Julien <victor@inliniac.net>
Sun, 28 Jul 2013 21:41:11 +0000 (23:41 +0200)
src/host-storage.c
src/host-storage.h
src/host.c
src/util-storage.c
src/util-storage.h

index 3bcbfbe556220a64e9193c0fb6bbf3428b91d3b4..0e028a739a79cd3d983c19b815886f8894b71b09 100644 (file)
 
 #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
 }
index 4905744d7193f5bfcf58a0f43b2d045d5a3a8fca..bc43d31566949609b12015988379ec66cdc44c63 100644 (file)
  * 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__ */
index a159df82bf6834a191f3b50b59da16058391a3b2..4661ca589c5b95e686218c24227d3e1682b7ab0b 100644 (file)
@@ -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();
+}
 
index c829905d75ac2cf4b4fac9ecf30afc1a3bfaea6d..934ff799ee2022b26b258db213b4ced112c6113c 100644 (file)
@@ -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) {
index 785c4d02a8c072990e988dd2ce686180f30afd17..2e4061beaaecc9a9a0c0ff0f0e90ff9254117c1a 100644 (file)
@@ -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