diff --git a/src/include/configobj.h b/src/include/configobj.h new file mode 100644 index 00000000..e69de29b diff --git a/src/include/kv.h b/src/include/kv.h index 07c76cf3..a132ea4e 100644 --- a/src/include/kv.h +++ b/src/include/kv.h @@ -3,12 +3,31 @@ #define _KV_H_ 1 #include +#include #include #include -extern typeinfo_t kvtab_int64_type; -extern typeinfo_t kvtab_string_type; -extern typeinfo_t kvtab_generic_type; +typedef uint32_t (*kv_key_hash_fn_t)(void*); +typedef int (*kv_key_assign_fn_t)(void**, void*); +typedef int (*kv_key_cmp_fn_t)(void*, void*); +typedef void (*kv_key_destroy_fn_t)(void*); + +typedef struct { + kv_key_hash_fn_t hash; + kv_key_assign_fn_t assign; + kv_key_cmp_fn_t cmp; + kv_key_destroy_fn_t destroy; +} kv_key_ops_t; + +typedef struct { + uint32_t nslots; + kv_key_ops_t* keyops; + destroy_fn_t datakiller; +} kv_params_t; + +extern typeinfo_t kvtab_type; +extern kv_key_ops_t int_key_ops; +extern kv_key_ops_t string_key_ops; extern int key_cmp_default(void*, void*, size_t); #endif diff --git a/src/include/kvmgr.h b/src/include/kvmgr.h index 161ff3f9..29805d82 100644 --- a/src/include/kvmgr.h +++ b/src/include/kvmgr.h @@ -8,6 +8,11 @@ #include "xlist.h" #include "zarray.h" +typedef enum { + KVMGR_KEY_INT = 0, + KVMGR_KEY_STRING +} kvmgr_key_type_t; + typedef struct { mylock_t lock; htab_t htab; @@ -65,4 +70,12 @@ extern worker_t* workermgr_lock(workermgr_t*, char*, int); extern worker_t* workermgr_lock_byid(workermgr_t*, int, int); extern void workermgr_del(workermgr_t*, worker_t*); +typedef struct { + kvmgr_key_type_t key_type; + unsigned int dynamic : 1; + uint32_t nslots; + uint32_t delta; + destroy_fn_t datakiller; +} kvmgr_params_t; + #endif diff --git a/src/include/qobj.h b/src/include/qobj.h new file mode 100644 index 00000000..df69a1f3 --- /dev/null +++ b/src/include/qobj.h @@ -0,0 +1,9 @@ +#if !defined(_QOBJ_H_) + +#define _QOBJ_H_ 1 + +#include "xce/types.h" + +extern xce_queue_t *makeQueue(xce_queue_t*); + +#endif diff --git a/src/include/resobj.h b/src/include/resobj.h new file mode 100644 index 00000000..e69de29b diff --git a/src/include/wobj.h b/src/include/wobj.h new file mode 100644 index 00000000..af724594 --- /dev/null +++ b/src/include/wobj.h @@ -0,0 +1,9 @@ +#if !defined(_WOBBJ_H_) + +#define _WOBJ_H_ 1 + +#include "xce/types.h" + +extern xce_worker_t* makeWorker(xce_worker_t*); + +#endif diff --git a/src/include/zarray.h b/src/include/zarray.h index dce47558..cfce4883 100644 --- a/src/include/zarray.h +++ b/src/include/zarray.h @@ -2,8 +2,8 @@ #define _ZARRAY_H_ 1 -#include #include +#include #include "mylock.h" #include "xlist.h" @@ -36,7 +36,10 @@ extern void* zarray_get(zarray_t*, int); extern void* zarray_find(zarray_t*, zarray_find_cond_fn_t, ...); extern void zarray_fini(zarray_t*); -typedef void (*xzarray_item_killer_t)(void *); +typedef struct { + int delta; + destroy_fn_t datakiller; +} xzarray_params_t; extern typeinfo_t xzarray_type; diff --git a/src/lib/configobj.c b/src/lib/configobj.c new file mode 100644 index 00000000..52b84c34 --- /dev/null +++ b/src/lib/configobj.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include +#include + +#include "mylock.h" +#include "qobj.h" +#include "utils.h" +#include "xstring.h" + diff --git a/src/lib/jobj.c b/src/lib/jobj.c index 53ab8d8f..621a89eb 100644 --- a/src/lib/jobj.c +++ b/src/lib/jobj.c @@ -23,6 +23,47 @@ static struct { static typeinfo_t job_submit_type; +static uint32_t submit_data_key_hash(job_submit_data_t* key) +{ + return hash_block((char*)key, sizeof(*key)); +} + +static int submit_data_key_assign(job_submit_data_t** dst, + job_submit_data_t* src) +{ + job_submit_data_t* p = calloc(1, sizeof(*p)); + + if (p == NULL) { + return -ENOMEM; + } + + memcpy(p, src, sizeof(*p)); + + *dst = p; + + return 1; +} + +static int submit_data_key_cmp(job_submit_data_t* key1, job_submit_data_t* key2) +{ + return memcmp((void*)key1, (void*)key2, sizeof(*key1)); +} + +static void submit_data_key_destroy(job_submit_data_t* key) +{ + if (key == NULL) { + return; + } + + FREEUP(key); +} + +static kv_key_ops_t submit_data_key_ops + = { .hash = (kv_key_hash_fn_t)submit_data_key_hash, + .assign = (kv_key_assign_fn_t)submit_data_key_assign, + .cmp = (kv_key_cmp_fn_t)submit_data_key_cmp, + .destroy = (kv_key_destroy_fn_t)submit_data_key_destroy }; + static void jobsub_destroy(meta_obj_t*); static void jobsub_killer(var s) @@ -36,14 +77,18 @@ static void jobsub_killer(var s) static int jobsub_table_init(int nslots) { + kv_params_t params; + if (nslots <= 1) { return -EINVAL; } + params.nslots = nslots; + params.keyops = &submit_data_key_ops; + params.datakiller = jobsub_killer; + mylock_init(&(jobsub_table.lock)); - jobsub_table.sub_table - = makeInstance(&kvtab_generic_type, nslots, jobsub_killer, - sizeof(job_submit_data_t), key_cmp_default); + jobsub_table.sub_table = makeInstance(&kvtab_type, ¶ms); if (jobsub_table.sub_table == NULL) { return -errno; } @@ -417,16 +462,59 @@ static void startinfo_killer(var s) destroy_(s, (obj_destroy_fn_t)startinfo_destroy); } +static uint32_t startinfo_key_hash(job_startinfo_t* key) +{ + return hash_block((void*)key, sizeof(*key)); +} + +static int startinfo_key_assign(job_startinfo_t** dst, job_startinfo_t* src) +{ + job_startinfo_t* p = calloc(1, sizeof(*p)); + + if (p == NULL) { + return -ENOMEM; + } + + memcpy(p, src, sizeof(*p)); + + *dst = p; + + return 1; +} + +static int startinfo_key_cmp(job_startinfo_t* k1, job_startinfo_t* k2) +{ + return memcmp((void*)k1, (void*)k2, sizeof(*k1)); +} + +static void startinfo_key_destroy(job_startinfo_t* key) +{ + if (key == NULL) { + return; + } + + FREEUP(key); +} + +static kv_key_ops_t startinfo_key_ops + = { .hash = (kv_key_hash_fn_t)startinfo_key_hash, + .assign = (kv_key_assign_fn_t)startinfo_key_assign, + .cmp = (kv_key_cmp_fn_t)startinfo_key_cmp, + .destroy = (kv_key_destroy_fn_t)startinfo_key_destroy }; + static int startinfo_table_init(int nslots) { + kv_params_t params; + if (nslots <= 1) { return -EINVAL; } + params.nslots = nslots; + params.keyops = &startinfo_key_ops; + params.datakiller = startinfo_killer; mylock_init(&(startinfo_table.lock)); - startinfo_table.startinfo_table - = makeInstance(&kvtab_generic_type, nslots, startinfo_killer, - sizeof(job_startinfo_t), key_cmp_default); + startinfo_table.startinfo_table = makeInstance(&kvtab_type, ¶ms); if (startinfo_table.startinfo_table == NULL) { return -errno; } diff --git a/src/lib/kv.c b/src/lib/kv.c index e4acd3fa..0f349a7e 100644 --- a/src/lib/kv.c +++ b/src/lib/kv.c @@ -8,6 +8,72 @@ typedef struct kvent_ kvent_t; +static uint32_t hash_int_key(void* key) +{ + uint64_t intkey = (uint64_t)(long)key; + + return hash64(intkey); +} + +static int assign_int_key(void** dst, void* src) +{ + *dst = src; + return 0; +} + +static int cmp_int_key(void* key1, void* key2) +{ + uint64_t intkey1 = (uint64_t)(long)key1; + uint64_t intkey2 = (uint64_t)(long)key2; + + if (intkey1 > intkey2) { + return 1; + } else if (intkey2 > intkey1) { + return -1; + } + + return 0; +} + +kv_key_ops_t int_key_ops = { .hash = (kv_key_hash_fn_t)hash_int_key, + .assign = (kv_key_assign_fn_t)assign_int_key, + .cmp = (kv_key_cmp_fn_t)cmp_int_key }; + +static uint32_t hash_string_key(void* key) { return hash_string((char*)key); } + +static int cmp_string_key(void* key1, void* key2) +{ + return strcmp((char*)key1, (char*)key2); +} + +static int assign_string_key(char** dst, char* src) +{ + char* p = strdup(src); + + if (p == NULL) { + return -ENOMEM; + } + + *dst = p; + + return 1; +} + +static void destroy_string_key(char* s) +{ + if (s == NULL) { + return; + } + + free(s); +} + +kv_key_ops_t string_key_ops + = { .hash = (kv_key_hash_fn_t)hash_string_key, + .cmp = (kv_key_cmp_fn_t)cmp_string_key, + .assign = (kv_key_assign_fn_t)assign_string_key, + .destroy = (kv_key_destroy_fn_t)destroy_string_key }; + struct kvent_ { kvent_t* next; void* key; @@ -15,9 +81,10 @@ struct kvent_ { }; typedef struct { - uint32_t nslots; - destroy_fn_t val_killer; - kvent_t** slots; + uint32_t nslots; + kv_key_ops_t* keyops; + destroy_fn_t val_killer; + kvent_t** slots; } kvtab_t; static size_t kvtab_datasize(va_list ap) @@ -29,143 +96,26 @@ static size_t kvtab_datasize(va_list ap) static int kvtab_init(meta_obj_t* obj, va_list ap) { kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj); - uint32_t nslots = va_arg(ap, uint32_t); - destroy_fn_t killer = va_arg(ap, destroy_fn_t); + kv_params_t* params = va_arg(ap, kv_params_t*); - if (nslots <= 1) { + if ((params == NULL) || (params->nslots <= 1) || (params->keyops == NULL) + || (params->keyops->hash == NULL) || (params->keyops->cmp == NULL)) { return -EINVAL; } - kvtab->slots = (kvent_t**)calloc(nslots, sizeof(*(kvtab->slots))); + kvtab->slots = (kvent_t**)calloc(params->nslots, sizeof(*(kvtab->slots))); if (kvtab->slots == NULL) { return -ENOMEM; } - kvtab->nslots = nslots; - kvtab->val_killer = killer; + kvtab->nslots = params->nslots; + kvtab->keyops = params->keyops; + kvtab->val_killer = params->datakiller; return 1; } -static void kvtab_int64_destroy(meta_obj_t* obj) -{ - kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj); - int i; - - for (i = 0; i < kvtab->nslots; i++) { - kvent_t* e = NULL; - while ((e = kvtab->slots[i]) != NULL) { - kvtab->slots[i] = e->next; - e->next = NULL; - if (kvtab->val_killer != NULL) { - kvtab->val_killer(e->value); - } - - FREEUP(e); - } - } - - FREEUP(kvtab->slots); -} - -static kvent_t* kvtab_int64_get(kvtab_t* t, uint64_t key) -{ - uint32_t hc; - kvent_t* e = NULL; - - hc = hash_block((char*)&key, sizeof(key)) % t->nslots; - e = t->slots[hc]; - - while (e != NULL) { - if (((uint64_t)(long)e->key) == key) { - break; - } - - e = e->next; - } - - return e; -} -static int kvtab_int64_add(meta_obj_t* obj, void* key, void* value) -{ - kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj); - kvent_t* e = NULL; - uint32_t hc; - uint64_t keyint; - - e = kvtab_int64_get(t, (uint64_t)(long)key); - if (e != NULL) { - return -EEXIST; - } - - e = (kvent_t*)calloc(1, sizeof(*e)); - if (e == NULL) { - return -ENOMEM; - } - - e->key = key; - e->value = value; - - keyint = (uint64_t)(long)key; - hc = hash_block((char*)&keyint, sizeof(keyint)) % t->nslots; - - e->next = t->slots[hc]; - t->slots[hc] = e; - - return 1; -} - -static int kvtab_int64_del(meta_obj_t* obj, void* key) -{ - uint64_t keyint = (uint64_t)(long)key; - kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj); - kvent_t** e = NULL; - uint32_t hc; - - hc = hash_block((char*)&keyint, sizeof(keyint)) % t->nslots; - e = &(t->slots[hc]); - while ((*e) != NULL) { - if ((uint64_t)(long)(*e)->key == keyint) { - kvent_t* e1 = *e; - - *e = e1->next; - - if (t->val_killer != NULL) { - t->val_killer(e1->value); - } - - FREEUP(e1); - - return 1; - } - - e = &((*e)->next); - } - - return 0; -} - -static int kvtab_int64_find(meta_obj_t* obj, void* key, void** value) -{ - uint64_t keyint = (uint64_t)(long)key; - kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj); - kvent_t* e = NULL; - - if (value == NULL) { - return -EINVAL; - } - - e = kvtab_int64_get(t, keyint); - if (e == NULL) { - return -ENOENT; - } - - *value = e->value; - - return 1; -} - -static void kvtab_string_destroy(meta_obj_t* obj) +static void kvtab_destroy(meta_obj_t* obj) { kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj); int i; @@ -176,12 +126,15 @@ static void kvtab_string_destroy(meta_obj_t* obj) while ((e = kvtab->slots[i]) != NULL) { kvtab->slots[i] = e->next; e->next = NULL; - FREEUP(e->key); if (kvtab->val_killer != NULL) { kvtab->val_killer(e->value); } + if (kvtab->keyops->destroy != NULL) { + kvtab->keyops->destroy(e->key); + } + FREEUP(e); } } @@ -189,16 +142,16 @@ static void kvtab_string_destroy(meta_obj_t* obj) FREEUP(kvtab->slots); } -static kvent_t* kvtab_string_get(kvtab_t* t, char* key) +static kvent_t* kvtab_get(kvtab_t* t, void* key) { uint32_t hc; kvent_t* e = NULL; - hc = hash_string(key) % t->nslots; + hc = t->keyops->hash(key) % t->nslots; e = t->slots[hc]; while (e != NULL) { - if (strcmp((char*)e->key, key) == 0) { + if (t->keyops->cmp(e->key, key) == 0) { break; } @@ -208,13 +161,13 @@ static kvent_t* kvtab_string_get(kvtab_t* t, char* key) return e; } -static int kvtab_string_add(meta_obj_t* obj, void* key, void* value) +static int kvtab_add(meta_obj_t* obj, void* key, void* value) { kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj); kvent_t* e = NULL; uint32_t hc; - e = kvtab_string_get(t, (char*)key); + e = kvtab_get(t, key); if (e != NULL) { return -EEXIST; } @@ -224,15 +177,20 @@ static int kvtab_string_add(meta_obj_t* obj, void* key, void* value) return -ENOMEM; } - e->key = strdup((char*)key); - if (e->key == NULL) { - FREEUP(e); - return -ENOMEM; + if (t->keyops->assign == NULL) { + e->key = key; + } else { + int rc; + + rc = t->keyops->assign(&(e->key), key); + if (rc < 0) { + free(e); + return rc; + } } e->value = value; - - hc = hash_string((char*)key) % t->nslots; + hc = t->keyops->hash(key) % t->nslots; e->next = t->slots[hc]; t->slots[hc] = e; @@ -240,26 +198,27 @@ static int kvtab_string_add(meta_obj_t* obj, void* key, void* value) return 1; } -static int kvtab_string_del(meta_obj_t* obj, void* key) +static int kvtab_del(meta_obj_t* obj, void* key) { kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj); kvent_t** e = NULL; uint32_t hc; - hc = hash_string((char*)key) % t->nslots; + hc = t->keyops->hash(key) % t->nslots; e = &(t->slots[hc]); - while ((*e) != NULL) { - if (strcmp((char*)(*e)->key, (char*)key) == 0) { + if (t->keyops->cmp((*e)->key, key) == 0) { kvent_t* e1 = *e; *e = e1->next; - FREEUP(e1->key); - if (t->val_killer != NULL) { t->val_killer(e1->value); } + if (t->keyops->destroy != NULL) { + t->keyops->destroy(e1->key); + } + FREEUP(e1); return 1; @@ -271,7 +230,7 @@ static int kvtab_string_del(meta_obj_t* obj, void* key) return 0; } -static int kvtab_string_find(meta_obj_t* obj, void* key, void** value) +static int kvtab_find(meta_obj_t* obj, void* key, void** value) { kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj); kvent_t* e = NULL; @@ -280,7 +239,7 @@ static int kvtab_string_find(meta_obj_t* obj, void* key, void** value) return -EINVAL; } - e = kvtab_string_get(t, (char*)key); + e = kvtab_get(t, key); if (e == NULL) { return -ENOENT; } @@ -289,204 +248,13 @@ static int kvtab_string_find(meta_obj_t* obj, void* key, void** value) return 1; } -typeinfo_t kvtab_int64_type - = { .name = "kvtab_int", +typeinfo_t kvtab_type + = { .name = "kvtab", .privateSize = 0, .dataSize = (datasize_fn_t)kvtab_datasize, .init = (obj_init_fn_t)kvtab_init, - .destroy = (obj_destroy_fn_t)kvtab_int64_destroy, - .interfaces = { .kv = &(intf_kv_t) { - .add_key = (key_add_fn_t)kvtab_int64_add, - .del_key = (key_del_fn_t)kvtab_int64_del, - .find_key = (key_find_fn_t)kvtab_int64_find } } }; - -typeinfo_t kvtab_string_type - = { .name = "kvtab_int", - .privateSize = 0, - .dataSize = (datasize_fn_t)kvtab_datasize, - .init = (obj_init_fn_t)kvtab_init, - .destroy = (obj_destroy_fn_t)kvtab_string_destroy, - .interfaces = { .kv = &(intf_kv_t) { - .add_key = (key_add_fn_t)kvtab_string_add, - .del_key = (key_del_fn_t)kvtab_string_del, - .find_key = (key_find_fn_t)kvtab_string_find } } }; - -typedef struct { - uint32_t nslots; - size_t keylen; - destroy_fn_t val_killer; - comp_fn_t cmp; - kvent_t** slots; -} kvtab_generic_t; - -static size_t kvtab_generic_datasize(va_list ap) -{ - size_t sz = sizeof(kvtab_generic_t); - - return sz; -} - -static int kvtab_generic_init(meta_obj_t* obj, va_list ap) -{ - uint32_t nslots = va_arg(ap, uint32_t); - destroy_fn_t killer = va_arg(ap, destroy_fn_t); - size_t keylen = va_arg(ap, size_t); - comp_fn_t cmp = va_arg(ap, comp_fn_t); - kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj); - - if (nslots <= 1) { - return -EINVAL; - } - - kvtab->slots = (kvent_t**)calloc(nslots, sizeof(*(kvtab->slots))); - if (kvtab->slots == NULL) { - return -EINVAL; - } - - kvtab->nslots = nslots; - kvtab->val_killer = killer; - kvtab->cmp = cmp; - kvtab->keylen = keylen; - - return 1; -} - -static void kvtab_generic_destroy(meta_obj_t* obj) -{ - kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj); - int i; - - for (i = 0; i < kvtab->nslots; i++) { - kvent_t* e = NULL; - while ((e = kvtab->slots[i]) != NULL) { - kvtab->slots[i] = e->next; - e->next = NULL; - FREEUP(e->key); - if (kvtab->val_killer != NULL) { - kvtab->val_killer(e->value); - } - - FREEUP(e); - } - } - - FREEUP(kvtab->slots); - - return; -} - -static kvent_t* kvtab_generic_get(kvtab_generic_t* kvtab, void* key) -{ - uint32_t hc; - kvent_t* e = NULL; - - hc = hash_block((char*)key, kvtab->keylen) % kvtab->nslots; - e = kvtab->slots[hc]; - - while (e != NULL) { - if (kvtab->cmp(e->key, key, kvtab->keylen) == 0) { - break; - } - - e = e->next; - } - - return e; -} - -static int kvtab_generic_add(meta_obj_t* obj, void* key, void* value) -{ - kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj); - kvent_t* e = NULL; - uint32_t hc; - - e = kvtab_generic_get(kvtab, key); - if (e != NULL) { - return -EEXIST; - } - - e = (kvent_t*)calloc(1, sizeof(*e)); - if (e == NULL) { - return -ENOMEM; - } - - e->key = (void*)calloc(1, kvtab->keylen); - if (e->key == NULL) { - FREEUP(e); - return -ENOMEM; - } - - memcpy(e->key, key, kvtab->keylen); - e->value = value; - - hc = hash_block((char*)key, kvtab->keylen) % kvtab->nslots; - e->next = kvtab->slots[hc]; - kvtab->slots[hc] = e; - - return 1; -} - -static int kvtab_generic_del(meta_obj_t* obj, void* key) -{ - kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj); - kvent_t** e = NULL; - uint32_t hc; - - hc = hash_block((char*)key, kvtab->keylen) % kvtab->nslots; - e = &(kvtab->slots[hc]); - - while ((*e) != NULL) { - if (kvtab->cmp((*e)->key, key, kvtab->keylen) == 0) { - kvent_t* e1 = *e; - - *e = e1->next; - FREEUP(e1->key); - if (kvtab->val_killer != NULL) { - kvtab->val_killer(e1->value); - } - - FREEUP(e1); - - return 1; - } - - e = &((*e)->next); - } - - return 0; -} - -static int kvtab_generic_find(meta_obj_t* obj, void* key, void** value) -{ - kvtab_generic_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_generic_t, obj); - kvent_t* e = NULL; - - if (value == NULL) { - return -EINVAL; - } - - e = kvtab_generic_get(kvtab, key); - if (e == NULL) { - return -ENOENT; - } - - *value = e->value; - - return 1; -} - -typeinfo_t kvtab_generic_type - = { .name = "kvtab_generic", - .privateSize = 0, - .dataSize = (datasize_fn_t)kvtab_generic_datasize, - .init = (obj_init_fn_t)kvtab_generic_init, - .destroy = (obj_destroy_fn_t)kvtab_generic_destroy, - .interfaces = { .kv = &(intf_kv_t) { - .add_key = (key_add_fn_t)kvtab_generic_add, - .del_key = (key_del_fn_t)kvtab_generic_del, - .find_key = (key_find_fn_t)kvtab_generic_find } } }; - -int key_cmp_default(void* k1, void* k2, size_t len) -{ - return memcmp(k1, k2, len); -} + .destroy = (obj_destroy_fn_t)kvtab_destroy, + .interfaces + = { .kv = &(intf_kv_t) { .add_key = (key_add_fn_t)kvtab_add, + .del_key = (key_del_fn_t)kvtab_del, + .find_key = (key_find_fn_t)kvtab_find } } }; diff --git a/src/lib/kvmgr.c b/src/lib/kvmgr.c index b44fadc1..dd171d2b 100644 --- a/src/lib/kvmgr.c +++ b/src/lib/kvmgr.c @@ -1,9 +1,12 @@ #include +#include #include #include #include "htab.h" +#include "kv.h" #include "kvmgr.h" +#include "mylock.h" #include "objmgr.h" #include "utils.h" #include "xce/types.h" @@ -393,3 +396,211 @@ int jobmgr_iter(jobmgr_t* mgr, xlist_t* l, void* arg) return kvmgr_iter(&(mgr->jobs), NULL, l, arg); } +typedef struct { + my_rwlock_t lock; +} xkvmgr_private_t; + +typedef struct { + kvmgr_key_type_t key_type; + unsigned int dynamic : 1; + uint32_t nslots; + var kvtab; + var data; +} xkvmgr_t; + +static size_t xkvmgr_datasize(va_list ap) +{ + size_t sz = sizeof(xkvmgr_t); + + return sz; +} + +static int xkvmgr_init(meta_obj_t* obj, va_list ap) +{ + xkvmgr_t* kvm = RTTI_OBJ_TO_DATA(xkvmgr_t, obj); + kvmgr_params_t* params = va_arg(ap, kvmgr_params_t*); + kv_params_t kv_params; + xzarray_params_t data_params; + + if ((params == NULL) + || ((params->key_type != KVMGR_KEY_INT) + && (params->key_type != KVMGR_KEY_STRING)) + || (params->nslots <= 1) || (params->delta < 1)) { + return -EINVAL; + } + + kv_params.nslots = params->nslots; + kv_params.datakiller = params->datakiller; + + switch (params->key_type) { + case KVMGR_KEY_INT: + kv_params.keyops = &int_key_ops; + break; + case KVMGR_KEY_STRING: + kv_params.keyops = &string_key_ops; + break; + default: + return -EINVAL; + } + + kvm->kvtab = makeInstance(&kvtab_type, &kv_params); + if (kvm->kvtab == NULL) { + return -errno; + } + + data_params.delta = params->delta; + data_params.datakiller = params->datakiller; + kvm->data = makeInstance(&xzarray_type, &data_params); + if (kvm->data == NULL) { + destroy(kvm->kvtab); + + return -errno; + } + + kvm->nslots = params->nslots; + kvm->key_type = params->key_type; + + if (params->dynamic) { + xkvmgr_private_t* priv = RTTI_OBJ_TO_PRIV(obj); + + my_rwlock_init(&(priv->lock)); + } + + return 1; +} + +static void xkvmgr_destroy(meta_obj_t* obj) +{ + xkvmgr_t* kvm = RTTI_OBJ_TO_DATA(xkvmgr_t, obj); + + if (kvm->data != NULL) { + destroy(kvm->data); + } + + if (kvm->kvtab != NULL) { + destroy(kvm->kvtab); + } + + if (kvm->dynamic) { + xkvmgr_private_t* priv = RTTI_OBJ_TO_PRIV(obj); + + my_rwlock_fini(&(priv->lock)); + } + memset(kvm, 0x0, sizeof(*kvm)); + + return; +} + +static int xkvmgr_add(meta_obj_t* obj, void* key, void* value) +{ + xkvmgr_t* kvm = RTTI_OBJ_TO_DATA(xkvmgr_t, obj); + int rc; + xkvmgr_private_t* priv = RTTI_OBJ_TO_PRIV(obj); + + if (kvm->dynamic) { + my_rwlock_wlock(&(priv->lock)); + } + + rc = key_add(kvm->kvtab, key, value); + + if (kvm->dynamic) { + my_rwlock_unlock(&(priv->lock)); + } + + return rc; +} + +static int xkvmgr_find(meta_obj_t* obj, void* key, void** value) +{ + xkvmgr_t* kvm = RTTI_OBJ_TO_DATA(xkvmgr_t, obj); + int rc; + xkvmgr_private_t* priv = RTTI_OBJ_TO_PRIV(obj); + + if (kvm->dynamic) { + my_rwlock_rlock(&(priv->lock)); + } + + rc = key_find(kvm->kvtab, key, value); + + if (kvm->dynamic) { + my_rwlock_unlock(&(priv->lock)); + } + + return rc; +} + +static int xkvmgr_make_iter(iterator_t* iter, va_list ap) +{ + meta_obj_t* obj = iter->obj; + xkvmgr_t* kvm = RTTI_OBJ_TO_DATA(xkvmgr_t, obj); + xkvmgr_private_t* priv = RTTI_OBJ_TO_PRIV(obj); + iterator_t* it = calloc(1, sizeof(*it)); + int rc = 0; + + if (it == NULL) { + return -ENOMEM; + } + + if (kvm->dynamic) { + my_rwlock_rlock(&(priv->lock)); + } + rc = iter_make(it, kvm->data); + if (rc < 0) { + FREEUP(it); + if (kvm->dynamic) { + my_rwlock_unlock(&(priv->lock)); + } + return rc; + } + + iter->data = it; + + return RTTI_ITER_OK; +} + +static int xkvmgr_iter_next(iterator_t* iter, void** data) +{ + iterator_t* it = (iterator_t*)iter->data; + + return iter_next(it, data); +} + +static void xkvmgr_iter_destroy(iterator_t* iter) +{ + iterator_t* it = iter->data; + meta_obj_t* obj = iter->obj; + xkvmgr_t* kvm = RTTI_OBJ_TO_DATA(xkvmgr_t, obj); + xkvmgr_private_t* priv = RTTI_OBJ_TO_PRIV(obj); + + if (it != NULL) { + iter_destroy(it); + + FREEUP(it); + } + + iter->data = NULL; + + if (kvm->dynamic) { + my_rwlock_unlock(&(priv->lock)); + } + + return; +} + +typeinfo_t xkvmgr_type = { + .name = "xkvmgr", + .privateSize = sizeof(xkvmgr_private_t), + .dataSize = (datasize_fn_t)xkvmgr_datasize, + .init = (obj_init_fn_t)xkvmgr_init, + .destroy = (obj_destroy_fn_t)xkvmgr_destroy, + .interfaces + = { .kv = &(intf_kv_t) { .add_key = (key_add_fn_t)xkvmgr_add, + .del_key = (key_del_fn_t)NULL, + .find_key = (key_find_fn_t)xkvmgr_find }, + .iter + = &(intf_iterator_t) { .make = (iter_make_fn_t)xkvmgr_make_iter, + .next = (iter_next_fn_t)xkvmgr_iter_next, + .reset = (iter_reset_fn_t)NULL, + .destroy + = (iter_destroy_fn_t)xkvmgr_iter_destroy } } +}; diff --git a/src/lib/meson.build b/src/lib/meson.build index dcaf6ac8..c356390e 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -88,6 +88,7 @@ libxce_src = [ gen_srcs[0], 'qobj.c', 'resobj.c', 'wobj.c', + 'configobj.c', ] incdir = include_directories('../include') @@ -142,6 +143,8 @@ libxce_test_src = ['testsuite/test.c', 'testsuite/test_bitset.c', 'testsuite/test_kv.c', 'testsuite/test_jobj.c', + 'testsuite/test_wobj.c', + 'testsuite/test_qobj.c', ] libxce_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep] diff --git a/src/lib/qobj.c b/src/lib/qobj.c index 60f96d8e..79b9dc0b 100644 --- a/src/lib/qobj.c +++ b/src/lib/qobj.c @@ -3,3 +3,168 @@ #include #include #include + +#include "mylock.h" +#include "qobj.h" +#include "utils.h" +#include "xstring.h" + +typedef struct { + my_rwlock_t lock; + uint64_t refcount; +} queue_private_t; + +static size_t queue_datasize(va_list ap) +{ + size_t sz = sizeof(xce_queue_t); + + return sz; +} + +static int queue_init(meta_obj_t* obj, va_list ap) +{ + xce_queue_t* dst = RTTI_OBJ_TO_DATA(xce_queue_t, obj); + queue_private_t* priv = (queue_private_t*)RTTI_OBJ_TO_PRIV(obj); + xce_queue_t* src = va_arg(ap, xce_queue_t*); + + if (src == NULL) { + return -EINVAL; + } + + dst->queue = makeString(src->queue); + dst->attrs = src->attrs; + dst->status = src->status; + dst->priority = src->priority; + dst->accept_interval = src->accept_interval; + dst->sched_delay = src->sched_delay; + dst->resreq = makeString(src->resreq); + MOVE_PTR(dst->users, src->users); + MOVE_PTR(dst->hosts, src->hosts); + dst->nthresholds = src->nthresholds; + MOVE_PTR(dst->thresholds, src->thresholds); + + MOVE_PTR(dst->runwindow, src->runwindow); + MOVE_PTR(dst->dispatchwindow, src->dispatchwindow); + MOVE_PTR(dst->runwindow_config, src->runwindow_config); + MOVE_PTR(dst->dispatchwindow_config, src->dispatchwindow_config); + dst->pending_ctrl = src->pending_ctrl; + dst->pre_exec = makeString(src->pre_exec); + dst->post_exec = makeString(src->post_exec); + dst->autopscaler = makeString(src->autopscaler); + + my_rwlock_init(&(priv->lock)); + priv->refcount = 1; + + return 1; +} + +static void queue_destroy(meta_obj_t* obj) +{ + xce_queue_t* q = RTTI_OBJ_TO_DATA(xce_queue_t, obj); + queue_private_t* priv = (queue_private_t*)RTTI_OBJ_TO_PRIV(obj); + + dereference(q->queue); + dereference(q->resreq); + + /* FIXME: */ + if (q->users != NULL) { } + + if (q->hosts != NULL) { } + + if (q->thresholds != NULL) { } + + if (q->runwindow != NULL) { } + + if (q->dispatchwindow != NULL) { } + + if (q->runwindow_config != NULL) { } + + if (q->dispatchwindow_config != NULL) { } + + dereference(q->pre_exec); + dereference(q->post_exec); + dereference(q->autopscaler); + + my_rwlock_fini(&(priv->lock)); + memset(priv, 0x0, sizeof(*priv)); + + return; +} + +static int queue_reference(meta_obj_t* obj) +{ + queue_private_t* priv = (queue_private_t*)RTTI_OBJ_TO_PRIV(obj); + + my_rwlock_wlock(&(priv->lock)); + priv->refcount++; + my_rwlock_unlock(&(priv->lock)); + + return 1; +} + +static void queue_dereference(meta_obj_t* obj) +{ + queue_private_t* priv = (queue_private_t*)RTTI_OBJ_TO_PRIV(obj); + xce_queue_t* w = RTTI_OBJ_TO_DATA(xce_queue_t, obj); + uint64_t count = 0; + + my_rwlock_wlock(&(priv->lock)); + priv->refcount--; + count = priv->refcount; + my_rwlock_unlock(&(priv->lock)); + + if (count == 0) { + destroy_(w, (obj_destroy_fn_t)queue_destroy); + } + + return; +} + +static int queue_lock(meta_obj_t* obj, uint64_t option) +{ + queue_private_t* priv = (queue_private_t*)RTTI_OBJ_TO_PRIV(obj); + int rc = -EINVAL; + + switch (option) { + case RTTI_LOCK_READ: + rc = my_rwlock_rlock(&(priv->lock)); + break; + case RTTI_LOCK_WRITE: + rc = my_rwlock_wlock(&(priv->lock)); + break; + default: + break; + } + + return rc; +} + +static void queue_unlock(meta_obj_t* obj) +{ + queue_private_t* priv = (queue_private_t*)RTTI_OBJ_TO_PRIV(obj); + + my_rwlock_unlock(&(priv->lock)); + + return; +} + +static typeinfo_t queue_type = { + .name = "xce queue", + .privateSize = sizeof(queue_private_t), + .dataSize = (datasize_fn_t)queue_datasize, + .init = (obj_init_fn_t)queue_init, + .destroy = NULL, + .interfaces + = { .reference + = &(intf_reference_t) { .reference = (reference_fn_t)queue_reference, + .dereference + = (dereference_fn_t)queue_dereference }, + .lock = &(intf_lock_t) { .lock = (lock_fn_t)queue_lock, + .unlock = (unlock_fn_t)queue_unlock } } +}; + +xce_queue_t* makeQueue(xce_queue_t* w) +{ + xce_queue_t* queue = makeInstance(&queue_type, w); + return queue; +} diff --git a/src/lib/resobj.c b/src/lib/resobj.c index 60f96d8e..def235a5 100644 --- a/src/lib/resobj.c +++ b/src/lib/resobj.c @@ -3,3 +3,117 @@ #include #include #include + +#include "mylock.h" +#include "resobj.h" +#include "utils.h" +#include "xstring.h" + +typedef struct { + mylock_t lock; + uint64_t refcount; +} resobj_private_t; + +static size_t resobj_datasize(va_list ap) +{ + size_t sz = sizeof(xce_resource_t); + + return sz; +} + +static int resobj_init(meta_obj_t* obj, va_list ap) +{ + xce_resource_t* dst = RTTI_OBJ_TO_DATA(xce_resource_t, obj); + resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); + xce_resource_t* src = va_arg(ap, xce_resource_t*); + + if (src == NULL) { + return -EINVAL; + } + + memcpy(dst, src, sizeof(*dst)); + + dst->name = makeString(src->name); + dst->desc = makeString(src->desc); + +#if 0 + if (src->distributions != NULL) { + MOVE_PTR(dst->distributions, src->distributions); + } +#else + /* FIXME: */ + dst->distributions = NULL; +#endif + +#if 0 + MOVE_PTR(dst->hbased_defined, src->hbased_defined); +#else + /* FIXME: */ + dst->hbased_defined = NULL; +#endif + + mylock_init(&(priv->lock)); + priv->refcount = 1; + + return 1; +} + +static void resobj_destroy(meta_obj_t* obj) +{ + xce_resource_t* r = RTTI_OBJ_TO_DATA(xce_resource_t, obj); + resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); + + dereference(r->name); + dereference(r->desc); + + mylock_fini(&(priv->lock)); + memset(priv, 0x0, sizeof(*priv)); + + return; +} + +static int resobj_reference(meta_obj_t* obj) +{ + resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); + + mylock_lock(&(priv->lock)); + priv->refcount++; + mylock_unlock(&(priv->lock)); + + return 1; +} + +static void resobj_dereference(meta_obj_t* obj) +{ + resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); + xce_resource_t* w = RTTI_OBJ_TO_DATA(xce_resource_t, obj); + uint64_t count = 0; + + mylock_lock(&(priv->lock)); + priv->refcount--; + count = priv->refcount; + mylock_unlock(&(priv->lock)); + + if (count == 0) { + destroy_(w, (obj_destroy_fn_t)resobj_destroy); + } + + return; +} + +static typeinfo_t resobj_type + = { .name = "xce resobj", + .privateSize = sizeof(resobj_private_t), + .dataSize = (datasize_fn_t)resobj_datasize, + .init = (obj_init_fn_t)resobj_init, + .destroy = NULL, + .interfaces + = { .reference = &(intf_reference_t) { + .reference = (reference_fn_t)resobj_reference, + .dereference = (dereference_fn_t)resobj_dereference } } }; + +xce_resource_t* makeResource(xce_resource_t* w) +{ + xce_resource_t* resobj = makeInstance(&resobj_type, w); + return resobj; +} diff --git a/src/lib/testsuite/test.c b/src/lib/testsuite/test.c index 0b71b60c..ab9e9c26 100644 --- a/src/lib/testsuite/test.c +++ b/src/lib/testsuite/test.c @@ -25,6 +25,8 @@ extern void test_resreq(void); extern void test_bitset(void); extern void test_kv(void); extern void test_jobobj(void); +extern void test_qobj(void); +extern void test_wobj(void); void setUp(void) { return; } @@ -119,6 +121,8 @@ int main(int argc, char* argv[]) TEST(test_bitset); TEST(test_kv); TEST(test_jobobj); + TEST(test_wobj); + TEST(test_qobj); return UNITY_END(); } diff --git a/src/lib/testsuite/test_jobj.c b/src/lib/testsuite/test_jobj.c index 659aadd6..79ebbf2b 100644 --- a/src/lib/testsuite/test_jobj.c +++ b/src/lib/testsuite/test_jobj.c @@ -272,7 +272,7 @@ static void test_job_create(void) && (j2->submit->mintasks == 1) && (j2->submit->maxtasks == 5) && (j2->submit->user_group == NULL)); - destroy(j2); + dereference(j2); job_obj_fini(); xstring_table_fini(); diff --git a/src/lib/testsuite/test_kv.c b/src/lib/testsuite/test_kv.c index 8491e1fe..5c912aea 100644 --- a/src/lib/testsuite/test_kv.c +++ b/src/lib/testsuite/test_kv.c @@ -10,7 +10,10 @@ static void test_kv_int_create() { - var tab = makeInstance(&kvtab_int64_type, 31, NULL); + kv_params_t params + = { .nslots = 32, .keyops = &int_key_ops, .datakiller = NULL }; + + var tab = makeInstance(&kvtab_type, ¶ms); TEST_ASSERT_TRUE(tab != NULL); @@ -19,7 +22,9 @@ static void test_kv_int_create() static void test_kv_int1() { - var tab = makeInstance(&kvtab_int64_type, 31, NULL); + kv_params_t params + = { .nslots = 32, .keyops = &int_key_ops, .datakiller = NULL }; + var tab = makeInstance(&kvtab_type, ¶ms); int i; int rc; @@ -71,7 +76,9 @@ static void my_free(void* p) static void test_kv_int2() { - var tab = makeInstance(&kvtab_int64_type, 31, my_free); + kv_params_t params + = { .nslots = 32, .keyops = &int_key_ops, .datakiller = my_free }; + var tab = makeInstance(&kvtab_type, ¶ms); int i; int rc; char buf[128]; @@ -105,7 +112,9 @@ static void test_kv_int2() static void test_kv_string1() { - var tab = makeInstance(&kvtab_string_type, 31, NULL); + kv_params_t params + = { .nslots = 32, .keyops = &string_key_ops, .datakiller = NULL }; + var tab = makeInstance(&kvtab_type, ¶ms); int i; int rc; char buf[64]; @@ -153,7 +162,9 @@ static void test_kv_string1() static void test_kv_string_create() { - var tab = makeInstance(&kvtab_string_type, 31, NULL); + kv_params_t params + = { .nslots = 32, .keyops = &string_key_ops, .datakiller = NULL }; + var tab = makeInstance(&kvtab_type, ¶ms); TEST_ASSERT_TRUE(tab != NULL); diff --git a/src/lib/testsuite/test_qobj.c b/src/lib/testsuite/test_qobj.c new file mode 100644 index 00000000..bf342a07 --- /dev/null +++ b/src/lib/testsuite/test_qobj.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +#include + +#include "qobj.h" +#include "utils.h" +#include "xstring.h" + +static void test_queue_create(void) +{ + int rc; + xce_queue_t q1 = { 0 }; + xce_queue_t* q = NULL; + + rc = xstring_table_init(32); + TEST_ASSERT_TRUE(rc >= 0); + + q = makeQueue(&q1); + + TEST_ASSERT_TRUE(q != NULL); + + destroy(q); + + xstring_table_fini(); +} + +void test_qobj(void) +{ + printf("\n>> queue obj test\n\n"); + + RUN_TEST(test_queue_create); +} diff --git a/src/lib/testsuite/test_wobj.c b/src/lib/testsuite/test_wobj.c new file mode 100644 index 00000000..eadb5213 --- /dev/null +++ b/src/lib/testsuite/test_wobj.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include + +#include "utils.h" +#include "wobj.h" +#include "xstring.h" + +static void test_worker_create(void) +{ + int rc; + hostattrs_t attrs1 = { .hosttype = "LINUX64", + .hostmodel = "linux-gnu-x86_64", + .cpufactor = 100.0, + .maxcpus = 5, + .maxmem = 65536.0, + .maxswap = 65536.0, + .maxtmp = 0.0, + .ndisks = 2 }; + xce_worker_t w1 = { + .name = "worker1", + .attrs = &attrs1, + }; + xce_worker_t* w = NULL; + + rc = xstring_table_init(32); + TEST_ASSERT_TRUE(rc >= 0); + + w = makeWorker(&w1); + + TEST_ASSERT_TRUE(w != NULL); + TEST_ASSERT_TRUE(EQUAL_STRING(w->name, w1.name) + && EQUAL_STRING(w->attrs->hosttype, attrs1.hosttype) + && EQUAL_STRING(w->attrs->hostmodel, attrs1.hostmodel) + && (w->attrs->cpufactor == attrs1.cpufactor) + && (w->attrs->maxcpus == attrs1.maxcpus)); + + dereference(w); + + xstring_table_fini(); +} + +void test_wobj(void) +{ + printf("\n>> worker obj test\n\n"); + + RUN_TEST(test_worker_create); +} diff --git a/src/lib/testsuite/test_zarray.c b/src/lib/testsuite/test_zarray.c index 947cc94e..73c9b495 100644 --- a/src/lib/testsuite/test_zarray.c +++ b/src/lib/testsuite/test_zarray.c @@ -9,7 +9,8 @@ static void test_zarray_create() { - var a = makeInstance(&xzarray_type, 4, NULL); + xzarray_params_t params = { .delta = 4, .datakiller = NULL }; + var a = makeInstance(&xzarray_type, ¶ms); TEST_ASSERT_TRUE(a != NULL); @@ -18,10 +19,11 @@ static void test_zarray_create() static void test_zarray_store() { - var a = makeInstance(&xzarray_type, 4, NULL); - int idx; - int rc; - char* p = NULL; + xzarray_params_t params = { .delta = 4, .datakiller = NULL }; + var a = makeInstance(&xzarray_type, ¶ms); + int idx; + int rc; + char* p = NULL; TEST_ASSERT_TRUE(a != NULL); @@ -39,9 +41,10 @@ static void test_zarray_store() static void test_zarray_put() { - var a = makeInstance(&xzarray_type, 4, NULL); - int rc, idx = 10; - char* p; + xzarray_params_t params = { .delta = 4, .datakiller = NULL }; + var a = makeInstance(&xzarray_type, ¶ms); + int rc, idx = 10; + char* p; TEST_ASSERT_TRUE(a != NULL); @@ -58,13 +61,14 @@ static void test_zarray_put() static void test_zarray_put_get_vec() { - var a = makeInstance(&xzarray_type, 4, NULL); - int idxs[5] = { 1, 3, 5, 7, 9 }; - void* vals[5] = { (void*)(long)2, (void*)(long)4, (void*)(long)6, - (void*)(long)8, (void*)(long)10 }; - void* vals1[5]; - int i; - int rc; + xzarray_params_t params = { .delta = 4, .datakiller = NULL }; + var a = makeInstance(&xzarray_type, ¶ms); + int idxs[5] = { 1, 3, 5, 7, 9 }; + void* vals[5] = { (void*)(long)2, (void*)(long)4, (void*)(long)6, + (void*)(long)8, (void*)(long)10 }; + void* vals1[5]; + int i; + int rc; TEST_ASSERT_TRUE(a != NULL); @@ -83,12 +87,13 @@ static void test_zarray_put_get_vec() static void test_zarray_iter() { - var a = makeInstance(&xzarray_type, 4, NULL); - int idxs[5] = { 1, 3, 5, 7, 9 }; - int vals[5] = { 2, 4, 6, 8, 10 }; - int i; - iterator_t it; - int rc; + xzarray_params_t params = { .delta = 4, .datakiller = NULL }; + var a = makeInstance(&xzarray_type, ¶ms); + int idxs[5] = { 1, 3, 5, 7, 9 }; + int vals[5] = { 2, 4, 6, 8, 10 }; + int i; + iterator_t it; + int rc; TEST_ASSERT_TRUE(a != NULL); @@ -131,11 +136,12 @@ static void my_killer(void* p) static void test_zarray_clear() { - var a = makeInstance(&xzarray_type, 4, my_killer); - char* s = strdup("Hello"); - char* d = NULL; - int idx = 31; - int rc; + xzarray_params_t params = { .delta = 4, .datakiller = my_killer }; + var a = makeInstance(&xzarray_type, ¶ms); + char* s = strdup("Hello"); + char* d = NULL; + int idx = 31; + int rc; TEST_ASSERT_TRUE(a != NULL); diff --git a/src/lib/wobj.c b/src/lib/wobj.c index 60f96d8e..4e62b068 100644 --- a/src/lib/wobj.c +++ b/src/lib/wobj.c @@ -3,3 +3,164 @@ #include #include #include + +#include "mylock.h" +#include "utils.h" +#include "wobj.h" +#include "xstring.h" + +typedef struct { + my_rwlock_t lock; + uint64_t refcount; +} worker_private_t; + +static size_t worker_datasize(va_list ap) +{ + size_t sz = sizeof(xce_worker_t); + + return sz; +} + +static int worker_init(meta_obj_t* obj, va_list ap) +{ + xce_worker_t* dst = RTTI_OBJ_TO_DATA(xce_worker_t, obj); + worker_private_t* priv = (worker_private_t*)RTTI_OBJ_TO_PRIV(obj); + xce_worker_t* src = va_arg(ap, xce_worker_t*); + + if ((src == NULL) || (src->attrs == NULL)) { + return -EINVAL; + } + + dst->name = makeString(src->name); + dst->attrs = (hostattrs_t*)calloc(1, sizeof(hostattrs_t)); + if (dst->attrs == NULL) { + return -ENOMEM; + } + + memcpy(dst->attrs, src->attrs, sizeof(*(dst->attrs))); + + dst->attrs->hosttype = makeString(src->attrs->hosttype); + dst->attrs->hostmodel = makeString(src->attrs->hostmodel); + dst->status = src->status; + + /* FIXME: */ + zarray_init(&(dst->resvals), 64, NULL); + + dst->dead_since = src->dead_since; + dst->pending_ctrl = src->pending_ctrl; + MOVE_PTR(dst->dispatch_window_config, src->dispatch_window_config); + dst->nthresholds = src->nthresholds; + MOVE_PTR(dst->thresholds, src->thresholds); + dst->nresvals_to_sched = 0; + dst->resvals_to_sched = NULL; + + my_rwlock_init(&(priv->lock)); + priv->refcount = 1; + + return 1; +} + +static void worker_destroy(meta_obj_t* obj) +{ + xce_worker_t* w = RTTI_OBJ_TO_DATA(xce_worker_t, obj); + worker_private_t* priv = (worker_private_t*)RTTI_OBJ_TO_PRIV(obj); + + dereference(w->name); + + if (w->attrs != NULL) { + dereference(w->attrs->hosttype); + dereference(w->attrs->hostmodel); + FREEUP(w->attrs); + } + + if (w->dispatch_window_config != NULL) { } + + if (w->thresholds != NULL) { } + + if (w->resvals_to_sched != NULL) { } + + zarray_fini(&(w->resvals)); + + my_rwlock_fini(&(priv->lock)); + memset(priv, 0x0, sizeof(*priv)); + + return; +} + +static int worker_reference(meta_obj_t* obj) +{ + worker_private_t* priv = (worker_private_t*)RTTI_OBJ_TO_PRIV(obj); + + my_rwlock_wlock(&(priv->lock)); + priv->refcount++; + my_rwlock_unlock(&(priv->lock)); + + return 1; +} + +static void worker_dereference(meta_obj_t* obj) +{ + worker_private_t* priv = (worker_private_t*)RTTI_OBJ_TO_PRIV(obj); + xce_worker_t* w = RTTI_OBJ_TO_DATA(xce_worker_t, obj); + uint64_t count = 0; + + my_rwlock_wlock(&(priv->lock)); + priv->refcount--; + count = priv->refcount; + my_rwlock_unlock(&(priv->lock)); + + if (count == 0) { + destroy_(w, (obj_destroy_fn_t)worker_destroy); + } + + return; +} + +static int worker_lock(meta_obj_t* obj, uint64_t option) +{ + worker_private_t* priv = (worker_private_t*)RTTI_OBJ_TO_PRIV(obj); + int rc = -EINVAL; + + switch (option) { + case RTTI_LOCK_READ: + rc = my_rwlock_rlock(&(priv->lock)); + break; + case RTTI_LOCK_WRITE: + rc = my_rwlock_wlock(&(priv->lock)); + break; + default: + break; + } + + return rc; +} + +static void worker_unlock(meta_obj_t* obj) +{ + worker_private_t* priv = (worker_private_t*)RTTI_OBJ_TO_PRIV(obj); + + my_rwlock_unlock(&(priv->lock)); + + return; +} + +static typeinfo_t worker_type = { + .name = "xce worker", + .privateSize = sizeof(worker_private_t), + .dataSize = (datasize_fn_t)worker_datasize, + .init = (obj_init_fn_t)worker_init, + .destroy = NULL, + .interfaces + = { .reference + = &(intf_reference_t) { .reference = (reference_fn_t)worker_reference, + .dereference + = (dereference_fn_t)worker_dereference }, + .lock = &(intf_lock_t) { .lock = (lock_fn_t)worker_lock, + .unlock = (unlock_fn_t)worker_unlock } } +}; + +xce_worker_t* makeWorker(xce_worker_t* w) +{ + xce_worker_t* worker = makeInstance(&worker_type, w); + return worker; +} diff --git a/src/lib/xstring.c b/src/lib/xstring.c index 672a26e4..5997f8fa 100644 --- a/src/lib/xstring.c +++ b/src/lib/xstring.c @@ -169,13 +169,15 @@ static void my_xstring_killer(var s) int xstring_table_init(int nslots) { + kv_params_t params = { .nslots = nslots, + .keyops = &string_key_ops, + .datakiller = my_xstring_killer }; if (nslots <= 1) { return -EINVAL; } mylock_init(&(xstring_table.lock)); - xstring_table.xstr_table - = makeInstance(&kvtab_string_type, nslots, my_xstring_killer); + xstring_table.xstr_table = makeInstance(&kvtab_type, ¶ms); if (xstring_table.xstr_table == NULL) { return -errno; diff --git a/src/lib/zarray.c b/src/lib/zarray.c index cb93bf2b..64d4dcce 100644 --- a/src/lib/zarray.c +++ b/src/lib/zarray.c @@ -379,19 +379,18 @@ static int xzarray_init(meta_obj_t* obj, va_list ap) { xzarray_private_t* priv = (xzarray_private_t*)RTTI_OBJ_TO_PRIV(obj); xzarray_t* a = RTTI_OBJ_TO_DATA(xzarray_t, obj); - size_t delta = va_arg(ap, size_t); - destroy_fn_t killer = va_arg(ap, destroy_fn_t); + xzarray_params_t* params = va_arg(ap, xzarray_params_t*); - if (delta < 1) { + if ((params == NULL) || (params->delta < 1)) { return -EINVAL; } a->count = 0; a->caps = 0; - a->delta = delta; + a->delta = params->delta; a->data = NULL; a->pos = 0; - a->killer = killer; + a->killer = params->datakiller; mylock_init(&(priv->lock));