From: Reto Buerki Date: Thu, 9 Aug 2012 10:47:58 +0000 (+0200) Subject: id_manager: Use array of bool instead of list X-Git-Tag: 5.0.3rc1~39^2~96 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7aa573a50e06fa02c78740abaa4911b35d635b18;p=thirdparty%2Fstrongswan.git id_manager: Use array of bool instead of list 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. --- diff --git a/src/charon-tkm/src/tkm/tkm_id_manager.c b/src/charon-tkm/src/tkm/tkm_id_manager.c index 806a8741b9..5a657fa433 100644 --- a/src/charon-tkm/src/tkm/tkm_id_manager.c +++ b/src/charon-tkm/src/tkm/tkm_id_manager.c @@ -20,6 +20,8 @@ #include #include +#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, ¤t)) - { - 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; diff --git a/src/charon-tkm/tests/id_manager_tests.c b/src/charon-tkm/tests/id_manager_tests.c index 0942c299a2..a71727a383 100644 --- a/src/charon-tkm/tests/id_manager_tests.c +++ b/src/charon-tkm/tests/id_manager_tests.c @@ -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);