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.
This commit is contained in:
parent
49c513c1d9
commit
7aa573a50e
|
@ -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.
|
||||
* Per-kind array of free context ids
|
||||
*/
|
||||
int nextids[TKM_CTX_MAX];
|
||||
|
||||
/**
|
||||
* Per-kind list of acquired 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue