use librtti for worker/queue/resource
This commit is contained in:
parent
532c68e6e1
commit
2ee87d4ee6
23 changed files with 1078 additions and 396 deletions
0
src/include/configobj.h
Normal file
0
src/include/configobj.h
Normal file
|
|
@ -3,12 +3,31 @@
|
||||||
#define _KV_H_ 1
|
#define _KV_H_ 1
|
||||||
|
|
||||||
#include <rtti.h>
|
#include <rtti.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
extern typeinfo_t kvtab_int64_type;
|
typedef uint32_t (*kv_key_hash_fn_t)(void*);
|
||||||
extern typeinfo_t kvtab_string_type;
|
typedef int (*kv_key_assign_fn_t)(void**, void*);
|
||||||
extern typeinfo_t kvtab_generic_type;
|
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);
|
extern int key_cmp_default(void*, void*, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,11 @@
|
||||||
#include "xlist.h"
|
#include "xlist.h"
|
||||||
#include "zarray.h"
|
#include "zarray.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
KVMGR_KEY_INT = 0,
|
||||||
|
KVMGR_KEY_STRING
|
||||||
|
} kvmgr_key_type_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mylock_t lock;
|
mylock_t lock;
|
||||||
htab_t htab;
|
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 worker_t* workermgr_lock_byid(workermgr_t*, int, int);
|
||||||
extern void workermgr_del(workermgr_t*, worker_t*);
|
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
|
#endif
|
||||||
|
|
|
||||||
9
src/include/qobj.h
Normal file
9
src/include/qobj.h
Normal file
|
|
@ -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
|
||||||
0
src/include/resobj.h
Normal file
0
src/include/resobj.h
Normal file
9
src/include/wobj.h
Normal file
9
src/include/wobj.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
#define _ZARRAY_H_ 1
|
#define _ZARRAY_H_ 1
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <rtti.h>
|
#include <rtti.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "mylock.h"
|
#include "mylock.h"
|
||||||
#include "xlist.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_find(zarray_t*, zarray_find_cond_fn_t, ...);
|
||||||
extern void zarray_fini(zarray_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;
|
extern typeinfo_t xzarray_type;
|
||||||
|
|
||||||
|
|
|
||||||
11
src/lib/configobj.c
Normal file
11
src/lib/configobj.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <rtti.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mylock.h"
|
||||||
|
#include "qobj.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "xstring.h"
|
||||||
|
|
||||||
100
src/lib/jobj.c
100
src/lib/jobj.c
|
|
@ -23,6 +23,47 @@ static struct {
|
||||||
|
|
||||||
static typeinfo_t job_submit_type;
|
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_destroy(meta_obj_t*);
|
||||||
|
|
||||||
static void jobsub_killer(var s)
|
static void jobsub_killer(var s)
|
||||||
|
|
@ -36,14 +77,18 @@ static void jobsub_killer(var s)
|
||||||
|
|
||||||
static int jobsub_table_init(int nslots)
|
static int jobsub_table_init(int nslots)
|
||||||
{
|
{
|
||||||
|
kv_params_t params;
|
||||||
|
|
||||||
if (nslots <= 1) {
|
if (nslots <= 1) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.nslots = nslots;
|
||||||
|
params.keyops = &submit_data_key_ops;
|
||||||
|
params.datakiller = jobsub_killer;
|
||||||
|
|
||||||
mylock_init(&(jobsub_table.lock));
|
mylock_init(&(jobsub_table.lock));
|
||||||
jobsub_table.sub_table
|
jobsub_table.sub_table = makeInstance(&kvtab_type, ¶ms);
|
||||||
= makeInstance(&kvtab_generic_type, nslots, jobsub_killer,
|
|
||||||
sizeof(job_submit_data_t), key_cmp_default);
|
|
||||||
if (jobsub_table.sub_table == NULL) {
|
if (jobsub_table.sub_table == NULL) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
@ -417,16 +462,59 @@ static void startinfo_killer(var s)
|
||||||
destroy_(s, (obj_destroy_fn_t)startinfo_destroy);
|
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)
|
static int startinfo_table_init(int nslots)
|
||||||
{
|
{
|
||||||
|
kv_params_t params;
|
||||||
|
|
||||||
if (nslots <= 1) {
|
if (nslots <= 1) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.nslots = nslots;
|
||||||
|
params.keyops = &startinfo_key_ops;
|
||||||
|
params.datakiller = startinfo_killer;
|
||||||
mylock_init(&(startinfo_table.lock));
|
mylock_init(&(startinfo_table.lock));
|
||||||
startinfo_table.startinfo_table
|
startinfo_table.startinfo_table = makeInstance(&kvtab_type, ¶ms);
|
||||||
= makeInstance(&kvtab_generic_type, nslots, startinfo_killer,
|
|
||||||
sizeof(job_startinfo_t), key_cmp_default);
|
|
||||||
if (startinfo_table.startinfo_table == NULL) {
|
if (startinfo_table.startinfo_table == NULL) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
460
src/lib/kv.c
460
src/lib/kv.c
|
|
@ -8,6 +8,72 @@
|
||||||
|
|
||||||
typedef struct kvent_ kvent_t;
|
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_ {
|
struct kvent_ {
|
||||||
kvent_t* next;
|
kvent_t* next;
|
||||||
void* key;
|
void* key;
|
||||||
|
|
@ -15,9 +81,10 @@ struct kvent_ {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t nslots;
|
uint32_t nslots;
|
||||||
destroy_fn_t val_killer;
|
kv_key_ops_t* keyops;
|
||||||
kvent_t** slots;
|
destroy_fn_t val_killer;
|
||||||
|
kvent_t** slots;
|
||||||
} kvtab_t;
|
} kvtab_t;
|
||||||
|
|
||||||
static size_t kvtab_datasize(va_list ap)
|
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)
|
static int kvtab_init(meta_obj_t* obj, va_list ap)
|
||||||
{
|
{
|
||||||
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||||
uint32_t nslots = va_arg(ap, uint32_t);
|
kv_params_t* params = va_arg(ap, kv_params_t*);
|
||||||
destroy_fn_t killer = va_arg(ap, destroy_fn_t);
|
|
||||||
|
|
||||||
if (nslots <= 1) {
|
if ((params == NULL) || (params->nslots <= 1) || (params->keyops == NULL)
|
||||||
|
|| (params->keyops->hash == NULL) || (params->keyops->cmp == NULL)) {
|
||||||
return -EINVAL;
|
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) {
|
if (kvtab->slots == NULL) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
kvtab->nslots = nslots;
|
kvtab->nslots = params->nslots;
|
||||||
kvtab->val_killer = killer;
|
kvtab->keyops = params->keyops;
|
||||||
|
kvtab->val_killer = params->datakiller;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvtab_int64_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;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
kvtab_t* kvtab = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -176,12 +126,15 @@ static void kvtab_string_destroy(meta_obj_t* obj)
|
||||||
while ((e = kvtab->slots[i]) != NULL) {
|
while ((e = kvtab->slots[i]) != NULL) {
|
||||||
kvtab->slots[i] = e->next;
|
kvtab->slots[i] = e->next;
|
||||||
e->next = NULL;
|
e->next = NULL;
|
||||||
FREEUP(e->key);
|
|
||||||
|
|
||||||
if (kvtab->val_killer != NULL) {
|
if (kvtab->val_killer != NULL) {
|
||||||
kvtab->val_killer(e->value);
|
kvtab->val_killer(e->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kvtab->keyops->destroy != NULL) {
|
||||||
|
kvtab->keyops->destroy(e->key);
|
||||||
|
}
|
||||||
|
|
||||||
FREEUP(e);
|
FREEUP(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -189,16 +142,16 @@ static void kvtab_string_destroy(meta_obj_t* obj)
|
||||||
FREEUP(kvtab->slots);
|
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;
|
uint32_t hc;
|
||||||
kvent_t* e = NULL;
|
kvent_t* e = NULL;
|
||||||
|
|
||||||
hc = hash_string(key) % t->nslots;
|
hc = t->keyops->hash(key) % t->nslots;
|
||||||
e = t->slots[hc];
|
e = t->slots[hc];
|
||||||
|
|
||||||
while (e != NULL) {
|
while (e != NULL) {
|
||||||
if (strcmp((char*)e->key, key) == 0) {
|
if (t->keyops->cmp(e->key, key) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,13 +161,13 @@ static kvent_t* kvtab_string_get(kvtab_t* t, char* key)
|
||||||
return e;
|
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);
|
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||||
kvent_t* e = NULL;
|
kvent_t* e = NULL;
|
||||||
uint32_t hc;
|
uint32_t hc;
|
||||||
|
|
||||||
e = kvtab_string_get(t, (char*)key);
|
e = kvtab_get(t, key);
|
||||||
if (e != NULL) {
|
if (e != NULL) {
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
}
|
}
|
||||||
|
|
@ -224,15 +177,20 @@ static int kvtab_string_add(meta_obj_t* obj, void* key, void* value)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->key = strdup((char*)key);
|
if (t->keyops->assign == NULL) {
|
||||||
if (e->key == NULL) {
|
e->key = key;
|
||||||
FREEUP(e);
|
} else {
|
||||||
return -ENOMEM;
|
int rc;
|
||||||
|
|
||||||
|
rc = t->keyops->assign(&(e->key), key);
|
||||||
|
if (rc < 0) {
|
||||||
|
free(e);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e->value = value;
|
e->value = value;
|
||||||
|
hc = t->keyops->hash(key) % t->nslots;
|
||||||
hc = hash_string((char*)key) % t->nslots;
|
|
||||||
|
|
||||||
e->next = t->slots[hc];
|
e->next = t->slots[hc];
|
||||||
t->slots[hc] = e;
|
t->slots[hc] = e;
|
||||||
|
|
@ -240,26 +198,27 @@ static int kvtab_string_add(meta_obj_t* obj, void* key, void* value)
|
||||||
return 1;
|
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);
|
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||||
kvent_t** e = NULL;
|
kvent_t** e = NULL;
|
||||||
uint32_t hc;
|
uint32_t hc;
|
||||||
|
|
||||||
hc = hash_string((char*)key) % t->nslots;
|
hc = t->keyops->hash(key) % t->nslots;
|
||||||
e = &(t->slots[hc]);
|
e = &(t->slots[hc]);
|
||||||
|
|
||||||
while ((*e) != NULL) {
|
while ((*e) != NULL) {
|
||||||
if (strcmp((char*)(*e)->key, (char*)key) == 0) {
|
if (t->keyops->cmp((*e)->key, key) == 0) {
|
||||||
kvent_t* e1 = *e;
|
kvent_t* e1 = *e;
|
||||||
|
|
||||||
*e = e1->next;
|
*e = e1->next;
|
||||||
FREEUP(e1->key);
|
|
||||||
|
|
||||||
if (t->val_killer != NULL) {
|
if (t->val_killer != NULL) {
|
||||||
t->val_killer(e1->value);
|
t->val_killer(e1->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t->keyops->destroy != NULL) {
|
||||||
|
t->keyops->destroy(e1->key);
|
||||||
|
}
|
||||||
|
|
||||||
FREEUP(e1);
|
FREEUP(e1);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -271,7 +230,7 @@ static int kvtab_string_del(meta_obj_t* obj, void* key)
|
||||||
return 0;
|
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);
|
kvtab_t* t = RTTI_OBJ_TO_DATA(kvtab_t, obj);
|
||||||
kvent_t* e = NULL;
|
kvent_t* e = NULL;
|
||||||
|
|
@ -280,7 +239,7 @@ static int kvtab_string_find(meta_obj_t* obj, void* key, void** value)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = kvtab_string_get(t, (char*)key);
|
e = kvtab_get(t, key);
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
@ -289,204 +248,13 @@ static int kvtab_string_find(meta_obj_t* obj, void* key, void** value)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeinfo_t kvtab_int64_type
|
typeinfo_t kvtab_type
|
||||||
= { .name = "kvtab_int",
|
= { .name = "kvtab",
|
||||||
.privateSize = 0,
|
.privateSize = 0,
|
||||||
.dataSize = (datasize_fn_t)kvtab_datasize,
|
.dataSize = (datasize_fn_t)kvtab_datasize,
|
||||||
.init = (obj_init_fn_t)kvtab_init,
|
.init = (obj_init_fn_t)kvtab_init,
|
||||||
.destroy = (obj_destroy_fn_t)kvtab_int64_destroy,
|
.destroy = (obj_destroy_fn_t)kvtab_destroy,
|
||||||
.interfaces = { .kv = &(intf_kv_t) {
|
.interfaces
|
||||||
.add_key = (key_add_fn_t)kvtab_int64_add,
|
= { .kv = &(intf_kv_t) { .add_key = (key_add_fn_t)kvtab_add,
|
||||||
.del_key = (key_del_fn_t)kvtab_int64_del,
|
.del_key = (key_del_fn_t)kvtab_del,
|
||||||
.find_key = (key_find_fn_t)kvtab_int64_find } } };
|
.find_key = (key_find_fn_t)kvtab_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);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
211
src/lib/kvmgr.c
211
src/lib/kvmgr.c
|
|
@ -1,9 +1,12 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <rtti.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "htab.h"
|
#include "htab.h"
|
||||||
|
#include "kv.h"
|
||||||
#include "kvmgr.h"
|
#include "kvmgr.h"
|
||||||
|
#include "mylock.h"
|
||||||
#include "objmgr.h"
|
#include "objmgr.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "xce/types.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);
|
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 } }
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ libxce_src = [ gen_srcs[0],
|
||||||
'qobj.c',
|
'qobj.c',
|
||||||
'resobj.c',
|
'resobj.c',
|
||||||
'wobj.c',
|
'wobj.c',
|
||||||
|
'configobj.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
incdir = include_directories('../include')
|
incdir = include_directories('../include')
|
||||||
|
|
@ -142,6 +143,8 @@ libxce_test_src = ['testsuite/test.c',
|
||||||
'testsuite/test_bitset.c',
|
'testsuite/test_bitset.c',
|
||||||
'testsuite/test_kv.c',
|
'testsuite/test_kv.c',
|
||||||
'testsuite/test_jobj.c',
|
'testsuite/test_jobj.c',
|
||||||
|
'testsuite/test_wobj.c',
|
||||||
|
'testsuite/test_qobj.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
libxce_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep]
|
libxce_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep]
|
||||||
|
|
|
||||||
165
src/lib/qobj.c
165
src/lib/qobj.c
|
|
@ -3,3 +3,168 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
|
||||||
114
src/lib/resobj.c
114
src/lib/resobj.c
|
|
@ -3,3 +3,117 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ extern void test_resreq(void);
|
||||||
extern void test_bitset(void);
|
extern void test_bitset(void);
|
||||||
extern void test_kv(void);
|
extern void test_kv(void);
|
||||||
extern void test_jobobj(void);
|
extern void test_jobobj(void);
|
||||||
|
extern void test_qobj(void);
|
||||||
|
extern void test_wobj(void);
|
||||||
|
|
||||||
void setUp(void) { return; }
|
void setUp(void) { return; }
|
||||||
|
|
||||||
|
|
@ -119,6 +121,8 @@ int main(int argc, char* argv[])
|
||||||
TEST(test_bitset);
|
TEST(test_bitset);
|
||||||
TEST(test_kv);
|
TEST(test_kv);
|
||||||
TEST(test_jobobj);
|
TEST(test_jobobj);
|
||||||
|
TEST(test_wobj);
|
||||||
|
TEST(test_qobj);
|
||||||
|
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ static void test_job_create(void)
|
||||||
&& (j2->submit->mintasks == 1) && (j2->submit->maxtasks == 5)
|
&& (j2->submit->mintasks == 1) && (j2->submit->maxtasks == 5)
|
||||||
&& (j2->submit->user_group == NULL));
|
&& (j2->submit->user_group == NULL));
|
||||||
|
|
||||||
destroy(j2);
|
dereference(j2);
|
||||||
|
|
||||||
job_obj_fini();
|
job_obj_fini();
|
||||||
xstring_table_fini();
|
xstring_table_fini();
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@
|
||||||
|
|
||||||
static void test_kv_int_create()
|
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);
|
TEST_ASSERT_TRUE(tab != NULL);
|
||||||
|
|
||||||
|
|
@ -19,7 +22,9 @@ static void test_kv_int_create()
|
||||||
|
|
||||||
static void test_kv_int1()
|
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 i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
|
@ -71,7 +76,9 @@ static void my_free(void* p)
|
||||||
|
|
||||||
static void test_kv_int2()
|
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 i;
|
||||||
int rc;
|
int rc;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
@ -105,7 +112,9 @@ static void test_kv_int2()
|
||||||
|
|
||||||
static void test_kv_string1()
|
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 i;
|
||||||
int rc;
|
int rc;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
@ -153,7 +162,9 @@ static void test_kv_string1()
|
||||||
|
|
||||||
static void test_kv_string_create()
|
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);
|
TEST_ASSERT_TRUE(tab != NULL);
|
||||||
|
|
||||||
|
|
|
||||||
35
src/lib/testsuite/test_qobj.c
Normal file
35
src/lib/testsuite/test_qobj.c
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <unity/unity.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
51
src/lib/testsuite/test_wobj.c
Normal file
51
src/lib/testsuite/test_wobj.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <unity/unity.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
static void test_zarray_create()
|
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);
|
TEST_ASSERT_TRUE(a != NULL);
|
||||||
|
|
||||||
|
|
@ -18,10 +19,11 @@ static void test_zarray_create()
|
||||||
|
|
||||||
static void test_zarray_store()
|
static void test_zarray_store()
|
||||||
{
|
{
|
||||||
var a = makeInstance(&xzarray_type, 4, NULL);
|
xzarray_params_t params = { .delta = 4, .datakiller = NULL };
|
||||||
int idx;
|
var a = makeInstance(&xzarray_type, ¶ms);
|
||||||
int rc;
|
int idx;
|
||||||
char* p = NULL;
|
int rc;
|
||||||
|
char* p = NULL;
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(a != NULL);
|
TEST_ASSERT_TRUE(a != NULL);
|
||||||
|
|
||||||
|
|
@ -39,9 +41,10 @@ static void test_zarray_store()
|
||||||
|
|
||||||
static void test_zarray_put()
|
static void test_zarray_put()
|
||||||
{
|
{
|
||||||
var a = makeInstance(&xzarray_type, 4, NULL);
|
xzarray_params_t params = { .delta = 4, .datakiller = NULL };
|
||||||
int rc, idx = 10;
|
var a = makeInstance(&xzarray_type, ¶ms);
|
||||||
char* p;
|
int rc, idx = 10;
|
||||||
|
char* p;
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(a != NULL);
|
TEST_ASSERT_TRUE(a != NULL);
|
||||||
|
|
||||||
|
|
@ -58,13 +61,14 @@ static void test_zarray_put()
|
||||||
|
|
||||||
static void test_zarray_put_get_vec()
|
static void test_zarray_put_get_vec()
|
||||||
{
|
{
|
||||||
var a = makeInstance(&xzarray_type, 4, NULL);
|
xzarray_params_t params = { .delta = 4, .datakiller = NULL };
|
||||||
int idxs[5] = { 1, 3, 5, 7, 9 };
|
var a = makeInstance(&xzarray_type, ¶ms);
|
||||||
void* vals[5] = { (void*)(long)2, (void*)(long)4, (void*)(long)6,
|
int idxs[5] = { 1, 3, 5, 7, 9 };
|
||||||
(void*)(long)8, (void*)(long)10 };
|
void* vals[5] = { (void*)(long)2, (void*)(long)4, (void*)(long)6,
|
||||||
void* vals1[5];
|
(void*)(long)8, (void*)(long)10 };
|
||||||
int i;
|
void* vals1[5];
|
||||||
int rc;
|
int i;
|
||||||
|
int rc;
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(a != NULL);
|
TEST_ASSERT_TRUE(a != NULL);
|
||||||
|
|
||||||
|
|
@ -83,12 +87,13 @@ static void test_zarray_put_get_vec()
|
||||||
|
|
||||||
static void test_zarray_iter()
|
static void test_zarray_iter()
|
||||||
{
|
{
|
||||||
var a = makeInstance(&xzarray_type, 4, NULL);
|
xzarray_params_t params = { .delta = 4, .datakiller = NULL };
|
||||||
int idxs[5] = { 1, 3, 5, 7, 9 };
|
var a = makeInstance(&xzarray_type, ¶ms);
|
||||||
int vals[5] = { 2, 4, 6, 8, 10 };
|
int idxs[5] = { 1, 3, 5, 7, 9 };
|
||||||
int i;
|
int vals[5] = { 2, 4, 6, 8, 10 };
|
||||||
iterator_t it;
|
int i;
|
||||||
int rc;
|
iterator_t it;
|
||||||
|
int rc;
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(a != NULL);
|
TEST_ASSERT_TRUE(a != NULL);
|
||||||
|
|
||||||
|
|
@ -131,11 +136,12 @@ static void my_killer(void* p)
|
||||||
|
|
||||||
static void test_zarray_clear()
|
static void test_zarray_clear()
|
||||||
{
|
{
|
||||||
var a = makeInstance(&xzarray_type, 4, my_killer);
|
xzarray_params_t params = { .delta = 4, .datakiller = my_killer };
|
||||||
char* s = strdup("Hello");
|
var a = makeInstance(&xzarray_type, ¶ms);
|
||||||
char* d = NULL;
|
char* s = strdup("Hello");
|
||||||
int idx = 31;
|
char* d = NULL;
|
||||||
int rc;
|
int idx = 31;
|
||||||
|
int rc;
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(a != NULL);
|
TEST_ASSERT_TRUE(a != NULL);
|
||||||
|
|
||||||
|
|
|
||||||
161
src/lib/wobj.c
161
src/lib/wobj.c
|
|
@ -3,3 +3,164 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,13 +169,15 @@ static void my_xstring_killer(var s)
|
||||||
|
|
||||||
int xstring_table_init(int nslots)
|
int xstring_table_init(int nslots)
|
||||||
{
|
{
|
||||||
|
kv_params_t params = { .nslots = nslots,
|
||||||
|
.keyops = &string_key_ops,
|
||||||
|
.datakiller = my_xstring_killer };
|
||||||
if (nslots <= 1) {
|
if (nslots <= 1) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mylock_init(&(xstring_table.lock));
|
mylock_init(&(xstring_table.lock));
|
||||||
xstring_table.xstr_table
|
xstring_table.xstr_table = makeInstance(&kvtab_type, ¶ms);
|
||||||
= makeInstance(&kvtab_string_type, nslots, my_xstring_killer);
|
|
||||||
|
|
||||||
if (xstring_table.xstr_table == NULL) {
|
if (xstring_table.xstr_table == NULL) {
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
|
||||||
|
|
@ -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_private_t* priv = (xzarray_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||||
xzarray_t* a = RTTI_OBJ_TO_DATA(xzarray_t, obj);
|
xzarray_t* a = RTTI_OBJ_TO_DATA(xzarray_t, obj);
|
||||||
size_t delta = va_arg(ap, size_t);
|
xzarray_params_t* params = va_arg(ap, xzarray_params_t*);
|
||||||
destroy_fn_t killer = va_arg(ap, destroy_fn_t);
|
|
||||||
|
|
||||||
if (delta < 1) {
|
if ((params == NULL) || (params->delta < 1)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
a->count = 0;
|
a->count = 0;
|
||||||
a->caps = 0;
|
a->caps = 0;
|
||||||
a->delta = delta;
|
a->delta = params->delta;
|
||||||
a->data = NULL;
|
a->data = NULL;
|
||||||
a->pos = 0;
|
a->pos = 0;
|
||||||
a->killer = killer;
|
a->killer = params->datakiller;
|
||||||
|
|
||||||
mylock_init(&(priv->lock));
|
mylock_init(&(priv->lock));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue