]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
id_manager: Use array of bool instead of list
authorReto Buerki <reet@codelabs.ch>
Thu, 9 Aug 2012 10:47:58 +0000 (12:47 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:45 +0000 (15:23 +0100)
Instead of storing the acquired context ids in a linked list, use an
array of booleans for the job. A boolean value of true in the array
designates an available context id.

src/charon-tkm/src/tkm/tkm_id_manager.c
src/charon-tkm/tests/id_manager_tests.c

index 806a8741b9d40bd09708a23362443dd1b4b223e4..5a657fa43327e48b7ae7dc52e507e293c6efad82 100644 (file)
@@ -20,6 +20,8 @@
 #include <collections/linked_list.h>
 #include <threading/rwlock.h>
 
+#define TKM_LIMIT 100
+
 ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_DH,
        "NONCE_CONTEXT",
        "DH_CONTEXT");
@@ -38,14 +40,9 @@ struct private_tkm_id_manager_t {
        tkm_id_manager_t public;
 
        /**
-        * Next free context id values.
-        */
-       int nextids[TKM_CTX_MAX];
-
-       /**
-        * Per-kind list of acquired context ids
+        * Per-kind array of free context ids
         */
-       linked_list_t *ctxids[TKM_CTX_MAX];
+       bool* ctxids[TKM_CTX_MAX];
 
        /**
         * rwlocks for context id lists
@@ -69,8 +66,7 @@ static bool is_valid_kind(const tkm_context_kind_t kind)
 METHOD(tkm_id_manager_t, acquire_id, int,
        private_tkm_id_manager_t * const this, const tkm_context_kind_t kind)
 {
-       int *current;
-       int id = 0;
+       int j, id = 0;
 
        if (!is_valid_kind(kind))
        {
@@ -80,13 +76,15 @@ METHOD(tkm_id_manager_t, acquire_id, int,
        }
 
        this->locks[kind]->write_lock(this->locks[kind]);
-
-       id = this->nextids[kind];
-       current = malloc(sizeof(int));
-       *current = id;
-       this->ctxids[kind]->insert_last(this->ctxids[kind], current);
-       this->nextids[kind]++;
-
+       for (j = 0; j < TKM_LIMIT; j++)
+       {
+               if (this->ctxids[kind][j])
+               {
+                       this->ctxids[kind][j] = false;
+                       id = j + 1;
+                       break;
+               }
+       }
        this->locks[kind]->unlock(this->locks[kind]);
 
        if (!id)
@@ -102,9 +100,7 @@ METHOD(tkm_id_manager_t, release_id, bool,
        private_tkm_id_manager_t * const this, const tkm_context_kind_t kind,
        const int id)
 {
-       enumerator_t *enumerator;
-       int *current;
-       bool found = FALSE;
+       const int idx = id - 1;
 
        if (!is_valid_kind(kind))
        {
@@ -114,25 +110,9 @@ METHOD(tkm_id_manager_t, release_id, bool,
        }
 
        this->locks[kind]->write_lock(this->locks[kind]);
-       enumerator = this->ctxids[kind]->create_enumerator(this->ctxids[kind]);
-       while (enumerator->enumerate(enumerator, &current))
-       {
-               if (*current == id)
-               {
-                       this->ctxids[kind]->remove_at(this->ctxids[kind], enumerator);
-                       found = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
+       this->ctxids[kind][idx] = true;
        this->locks[kind]->unlock(this->locks[kind]);
 
-       if (!found)
-       {
-               DBG3(DBG_LIB, "releasing non-existent %N context id %d, nothing to do",
-                                         tkm_context_kind_names, kind, id);
-       }
-
        return TRUE;
 }
 
@@ -141,10 +121,9 @@ METHOD(tkm_id_manager_t, destroy, void,
        private_tkm_id_manager_t *this)
 {
        int i;
-
        for (i = 0; i < TKM_CTX_MAX; i++)
        {
-               this->ctxids[i]->destroy(this->ctxids[i]);
+               free(this->ctxids[i]);
                this->locks[i]->destroy(this->locks[i]);
        }
        free(this);
@@ -156,7 +135,7 @@ METHOD(tkm_id_manager_t, destroy, void,
 tkm_id_manager_t *tkm_id_manager_create()
 {
        private_tkm_id_manager_t *this;
-       int i;
+       int i, j;
 
        INIT(this,
                .public = {
@@ -168,9 +147,13 @@ tkm_id_manager_t *tkm_id_manager_create()
 
        for (i = 0; i < TKM_CTX_MAX; i++)
        {
-               this->nextids[i] = 1;
-               this->ctxids[i] = linked_list_create();
+               this->ctxids[i] = malloc(TKM_LIMIT * sizeof(bool));
                this->locks[i] = rwlock_create(RWLOCK_TYPE_DEFAULT);
+               for (j = 0; j < TKM_LIMIT; j++)
+               {
+                       /* available id slots are in true state (is_available) */
+                       this->ctxids[i][j] = true;
+               }
        }
 
        return &this->public;
index 0942c299a2cde4a41996d91bb061d9bf1b9d679b..a71727a383dcc9c4f8e8e6e9d44d6830454f513a 100644 (file)
@@ -66,6 +66,23 @@ START_TEST(test_acquire_id_invalid_kind)
 }
 END_TEST
 
+START_TEST(test_acquire_id_same)
+{
+       int id1 = 0, id2 = 0;
+       tkm_id_manager_t *idmgr = tkm_id_manager_create();
+
+       id1 = idmgr->acquire_id(idmgr, TKM_CTX_NONCE);
+       fail_unless(id1 > 0, "Unable to acquire first id");
+
+       /* Acquire another id, must be different than first */
+       id2 = idmgr->acquire_id(idmgr, TKM_CTX_NONCE);
+       fail_unless(id2 > 0, "Unable to acquire second id");
+       fail_unless(id1 != id2, "Same id received twice");
+
+       idmgr->destroy(idmgr);
+}
+END_TEST
+
 START_TEST(test_release_id)
 {
        int i, id = 0;
@@ -123,6 +140,7 @@ TCase *make_id_manager_tests(void)
        tcase_add_test(tc, test_id_mgr_creation);
        tcase_add_test(tc, test_acquire_id);
        tcase_add_test(tc, test_acquire_id_invalid_kind);
+       tcase_add_test(tc, test_acquire_id_same);
        tcase_add_test(tc, test_release_id);
        tcase_add_test(tc, test_release_id_invalid_kind);
        tcase_add_test(tc, test_release_id_nonexistent);