forked from lei.chen/myxce
- add implement job related objs based on librtti
- add lock()/unlock() to job object
This commit is contained in:
parent
f582742e77
commit
532c68e6e1
13 changed files with 1136 additions and 12 deletions
|
|
@ -1008,3 +1008,4 @@ static void* xgroup_create(objmgr_t* mgr, objtype_t* typeval, va_list ap)
|
|||
}
|
||||
static void xgroup_fini(void* g) { return; }
|
||||
static void xgroup_type_fini(objtype_t* typeval) { return; }
|
||||
|
||||
|
|
|
|||
8
src/flake.lock
generated
8
src/flake.lock
generated
|
|
@ -117,11 +117,11 @@
|
|||
"xbuild": "xbuild"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771555882,
|
||||
"narHash": "sha256-kNX3V49Gq1b+QUqh0/dgW74qeRg3nE7DC6sWaSCJKsQ=",
|
||||
"lastModified": 1771560785,
|
||||
"narHash": "sha256-0iyZt6UrIyYS3gCGNuUma2l7O92LS48XAm9HPd4bEN0=",
|
||||
"ref": "master",
|
||||
"rev": "3da443cbadd0c15e4708f53d9f5abe2d3a40c2d2",
|
||||
"revCount": 16,
|
||||
"rev": "724c740909879b6b5d8851809f2aead7362bc78f",
|
||||
"revCount": 17,
|
||||
"type": "git",
|
||||
"url": "ssh://forgejo@gitea.shenrs.eu/rshen/librtti"
|
||||
},
|
||||
|
|
|
|||
13
src/include/jobj.h
Normal file
13
src/include/jobj.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#if !defined(_JOBJ_H_)
|
||||
|
||||
#define _JOBJ_H_ 1
|
||||
|
||||
#include "xce/types.h"
|
||||
|
||||
extern job_submit_data_t* makeJobsub(job_submit_data_t*);
|
||||
extern job_startinfo_t* makeJobstartinfo(job_startinfo_t*);
|
||||
extern xce_job_t* makeJob(xce_job_t*);
|
||||
extern int job_obj_init(int, int);
|
||||
extern void job_obj_fini();
|
||||
|
||||
#endif
|
||||
|
|
@ -3,10 +3,12 @@
|
|||
#define _KV_H_ 1
|
||||
|
||||
#include <rtti.h>
|
||||
|
||||
typedef void (*kv_value_kill_fn_t)(void*);
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
extern typeinfo_t kvtab_int64_type;
|
||||
extern typeinfo_t kvtab_string_type;
|
||||
extern typeinfo_t kvtab_generic_type;
|
||||
|
||||
extern int key_cmp_default(void*, void*, size_t);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#define EQUAL_STRING(s1, s2) \
|
||||
(((s1) == (s2)) \
|
||||
|| (((s1) != NULL) && ((s2) != NULL) && (strcmp((s1), (s2)) == 0)))
|
||||
|
||||
#define N_EL_ARRAY(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#define PTR_STEP(p, delta) ((void*)(((char*)p) + (delta)))
|
||||
|
||||
|
|
|
|||
612
src/lib/jobj.c
Normal file
612
src/lib/jobj.c
Normal file
|
|
@ -0,0 +1,612 @@
|
|||
#include <errno.h>
|
||||
#include <rtti.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jobj.h"
|
||||
#include "kv.h"
|
||||
#include "mylock.h"
|
||||
#include "utils.h"
|
||||
#include "xce/types.h"
|
||||
#include "xstring.h"
|
||||
|
||||
static struct {
|
||||
mylock_t lock;
|
||||
var sub_table;
|
||||
} jobsub_table;
|
||||
|
||||
static struct {
|
||||
mylock_t lock;
|
||||
var startinfo_table;
|
||||
} startinfo_table;
|
||||
|
||||
static typeinfo_t job_submit_type;
|
||||
|
||||
static void jobsub_destroy(meta_obj_t*);
|
||||
|
||||
static void jobsub_killer(var s)
|
||||
{
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
destroy_(s, (obj_destroy_fn_t)jobsub_destroy);
|
||||
}
|
||||
|
||||
static int jobsub_table_init(int nslots)
|
||||
{
|
||||
if (nslots <= 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_init(&(jobsub_table.lock));
|
||||
jobsub_table.sub_table
|
||||
= makeInstance(&kvtab_generic_type, nslots, jobsub_killer,
|
||||
sizeof(job_submit_data_t), key_cmp_default);
|
||||
if (jobsub_table.sub_table == NULL) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void jobsub_table_fini()
|
||||
{
|
||||
destroy(jobsub_table.sub_table);
|
||||
mylock_fini(&(jobsub_table.lock));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
uint64_t refcount;
|
||||
} job_submit_private_t;
|
||||
|
||||
static size_t jobsub_datasize(va_list ap)
|
||||
{
|
||||
size_t sz = sizeof(job_submit_data_t);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int jobsub_init(meta_obj_t* obj, va_list ap)
|
||||
{
|
||||
job_submit_data_t* src = va_arg(ap, job_submit_data_t*);
|
||||
job_submit_data_t* dst = RTTI_OBJ_TO_DATA(job_submit_data_t, obj);
|
||||
job_submit_private_t* priv = (job_submit_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
if (src == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dst->queue = makeString(src->queue);
|
||||
dst->user = makeString(src->user);
|
||||
dst->mintasks = src->mintasks;
|
||||
dst->maxtasks = src->maxtasks;
|
||||
if (src->start_info != NULL) {
|
||||
dst->start_info = makeJobstartinfo(src->start_info);
|
||||
if (dst->start_info == NULL) {
|
||||
jobsub_destroy(obj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
dst->start_info = NULL;
|
||||
}
|
||||
dst->job_name = makeString(src->job_name);
|
||||
dst->project_name = makeString(src->project_name);
|
||||
dst->user_group = makeString(src->user_group);
|
||||
dst->job_description = makeString(src->job_description);
|
||||
dst->resreq = makeString(src->resreq);
|
||||
|
||||
if (!(EQUAL_STRING(dst->queue, src->queue)
|
||||
&& EQUAL_STRING(dst->user, src->user)
|
||||
&& EQUAL_STRING(dst->job_name, src->job_name)
|
||||
&& EQUAL_STRING(dst->project_name, src->project_name)
|
||||
&& EQUAL_STRING(dst->user_group, src->user_group)
|
||||
&& EQUAL_STRING(dst->job_description, src->job_description)
|
||||
&& EQUAL_STRING(dst->resreq, src->resreq))) {
|
||||
jobsub_destroy(obj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mylock_init(&(priv->lock));
|
||||
priv->refcount = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void jobsub_destroy(meta_obj_t* obj)
|
||||
{
|
||||
job_submit_data_t* jobsub = RTTI_OBJ_TO_DATA(job_submit_data_t, obj);
|
||||
job_submit_private_t* priv = (job_submit_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
dereference(jobsub->queue);
|
||||
dereference(jobsub->user);
|
||||
dereference(jobsub->job_name);
|
||||
dereference(jobsub->project_name);
|
||||
dereference(jobsub->user_group);
|
||||
dereference(jobsub->job_description);
|
||||
dereference(jobsub->resreq);
|
||||
if (jobsub->start_info != NULL) {
|
||||
dereference(jobsub->start_info);
|
||||
}
|
||||
|
||||
mylock_fini(&(priv->lock));
|
||||
memset(priv, 0x0, sizeof(*priv));
|
||||
}
|
||||
|
||||
static int jobsub_reference(meta_obj_t* obj)
|
||||
{
|
||||
job_submit_private_t* priv = (job_submit_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
mylock_lock(&(priv->lock));
|
||||
priv->refcount++;
|
||||
mylock_unlock(&(priv->lock));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void jobsub_dereference(meta_obj_t* obj)
|
||||
{
|
||||
job_submit_private_t* priv = (job_submit_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
job_submit_data_t* data = RTTI_OBJ_TO_DATA(job_submit_data_t, obj);
|
||||
uint64_t count;
|
||||
|
||||
mylock_lock(&(priv->lock));
|
||||
priv->refcount--;
|
||||
count = priv->refcount;
|
||||
mylock_unlock(&(priv->lock));
|
||||
|
||||
if (count == 0) {
|
||||
mylock_lock(&(jobsub_table.lock));
|
||||
key_del(jobsub_table.sub_table, data);
|
||||
mylock_unlock(&(jobsub_table.lock));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static typeinfo_t job_submit_type
|
||||
= { .name = "job submit",
|
||||
.privateSize = sizeof(job_submit_private_t),
|
||||
.dataSize = (datasize_fn_t)jobsub_datasize,
|
||||
.init = (obj_init_fn_t)jobsub_init,
|
||||
.destroy = (obj_destroy_fn_t)NULL, /* disable destroy() */
|
||||
.interfaces
|
||||
= { .reference = &(intf_reference_t) {
|
||||
.reference = (reference_fn_t)jobsub_reference,
|
||||
.dereference = (dereference_fn_t)jobsub_dereference } } };
|
||||
|
||||
job_submit_data_t* makeJobsub(job_submit_data_t* subdata)
|
||||
{
|
||||
var jobsub = NULL;
|
||||
var jobsub1 = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (subdata == NULL) {
|
||||
errno = EINVAL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobsub = makeInstance(&job_submit_type, subdata);
|
||||
if (jobsub == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mylock_lock(&(jobsub_table.lock));
|
||||
rc = key_find(jobsub_table.sub_table, (void*)jobsub, (void**)&jobsub1);
|
||||
if (rc > 0) {
|
||||
reference(jobsub1);
|
||||
}
|
||||
mylock_unlock(&(jobsub_table.lock));
|
||||
|
||||
if (rc > 0) {
|
||||
destroy_(jobsub, (obj_destroy_fn_t)jobsub_destroy);
|
||||
return (job_submit_data_t*)jobsub1;
|
||||
}
|
||||
|
||||
mylock_lock(&(jobsub_table.lock));
|
||||
rc = key_add(jobsub_table.sub_table, (void*)jobsub, jobsub);
|
||||
mylock_unlock(&(jobsub_table.lock));
|
||||
|
||||
if (rc < 0) {
|
||||
destroy_(jobsub, (obj_destroy_fn_t)jobsub_destroy);
|
||||
jobsub = NULL;
|
||||
|
||||
errno = -rc;
|
||||
} else {
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
return jobsub;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
uint64_t refcount;
|
||||
} startinfo_private_t;
|
||||
|
||||
static void startinfo_destroy(meta_obj_t* obj)
|
||||
{
|
||||
job_startinfo_t* startinfo = RTTI_OBJ_TO_DATA(job_startinfo_t, obj);
|
||||
startinfo_private_t* priv = (startinfo_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
dereference(startinfo->exechome);
|
||||
dereference(startinfo->execcwd);
|
||||
dereference(startinfo->execuser);
|
||||
dereference(startinfo->cmdline);
|
||||
if (startinfo->exdata != NULL) {
|
||||
dereference(startinfo->exdata);
|
||||
}
|
||||
|
||||
if (startinfo->launch_type != NULL) {
|
||||
dereference(startinfo->launch_type);
|
||||
}
|
||||
|
||||
if (startinfo->q_pre_exec != NULL) {
|
||||
dereference(startinfo->q_pre_exec);
|
||||
}
|
||||
|
||||
if (startinfo->q_post_exec != NULL) {
|
||||
dereference(startinfo->q_post_exec);
|
||||
}
|
||||
|
||||
if (startinfo->job_pre_exec != NULL) {
|
||||
dereference(startinfo->job_pre_exec);
|
||||
}
|
||||
|
||||
if (startinfo->job_post_exec != NULL) {
|
||||
dereference(startinfo->job_post_exec);
|
||||
}
|
||||
|
||||
mylock_fini(&(priv->lock));
|
||||
memset(priv, 0x0, sizeof(*priv));
|
||||
return;
|
||||
}
|
||||
|
||||
static size_t startinfo_datasize(va_list ap)
|
||||
{
|
||||
size_t sz = sizeof(job_startinfo_t);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int startinfo_init(meta_obj_t* obj, va_list ap)
|
||||
{
|
||||
job_startinfo_t* src = va_arg(ap, job_startinfo_t*);
|
||||
job_startinfo_t* dst = RTTI_OBJ_TO_DATA(job_startinfo_t, obj);
|
||||
startinfo_private_t* priv = RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
if (src == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_init(&(priv->lock));
|
||||
priv->refcount = 1;
|
||||
|
||||
dst->exechome = makeString(src->exechome);
|
||||
dst->execcwd = makeString(src->execcwd);
|
||||
dst->execuser = makeString(src->execuser);
|
||||
dst->cmdline = makeString(src->cmdline);
|
||||
dst->exdata = NULL;
|
||||
if (src->exdata != NULL) {
|
||||
dst->exdata = makeString(src->exdata);
|
||||
}
|
||||
|
||||
dst->launch_type = NULL;
|
||||
if (src->launch_type != NULL) {
|
||||
dst->launch_type = makeString(src->launch_type);
|
||||
}
|
||||
|
||||
dst->q_pre_exec = NULL;
|
||||
if (src->q_pre_exec != NULL) {
|
||||
dst->q_pre_exec = makeString(src->q_pre_exec);
|
||||
}
|
||||
|
||||
dst->q_post_exec = NULL;
|
||||
if (src->q_post_exec != NULL) {
|
||||
dst->q_post_exec = makeString(src->q_post_exec);
|
||||
}
|
||||
|
||||
dst->job_pre_exec = NULL;
|
||||
if (src->job_pre_exec != NULL) {
|
||||
dst->job_pre_exec = makeString(src->job_pre_exec);
|
||||
}
|
||||
|
||||
dst->job_post_exec = NULL;
|
||||
if (src->job_post_exec != NULL) {
|
||||
dst->job_post_exec = makeString(src->job_post_exec);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int startinfo_reference(meta_obj_t* obj)
|
||||
{
|
||||
startinfo_private_t* priv = (startinfo_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
mylock_lock(&(priv->lock));
|
||||
priv->refcount++;
|
||||
mylock_unlock(&(priv->lock));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void startinfo_dereference(meta_obj_t* obj)
|
||||
{
|
||||
job_startinfo_t* startinfo = RTTI_OBJ_TO_DATA(job_startinfo_t, obj);
|
||||
startinfo_private_t* priv = (startinfo_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
uint64_t count;
|
||||
|
||||
mylock_lock(&(priv->lock));
|
||||
priv->refcount--;
|
||||
count = priv->refcount;
|
||||
mylock_unlock(&(priv->lock));
|
||||
|
||||
if (count == 0) {
|
||||
mylock_lock(&(startinfo_table.lock));
|
||||
key_del(startinfo_table.startinfo_table, startinfo);
|
||||
mylock_unlock(&(startinfo_table.lock));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static typeinfo_t job_startinfo_type
|
||||
= { .name = "job start info",
|
||||
.privateSize = sizeof(startinfo_private_t),
|
||||
.dataSize = (datasize_fn_t)startinfo_datasize,
|
||||
.init = (obj_init_fn_t)startinfo_init,
|
||||
.destroy = NULL,
|
||||
.interfaces
|
||||
= { .reference = &(intf_reference_t) {
|
||||
.reference = (reference_fn_t)startinfo_reference,
|
||||
.dereference = (dereference_fn_t)startinfo_dereference } } };
|
||||
|
||||
job_startinfo_t* makeJobstartinfo(job_startinfo_t* startinfo)
|
||||
{
|
||||
var startinfo1 = NULL;
|
||||
var startinfo2 = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (startinfo == NULL) {
|
||||
errno = EINVAL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
startinfo1 = makeInstance(&(job_startinfo_type), startinfo);
|
||||
if (startinfo1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mylock_lock(&(startinfo_table.lock));
|
||||
rc = key_find(startinfo_table.startinfo_table, (void*)startinfo1,
|
||||
(void**)&startinfo2);
|
||||
if (rc > 0) {
|
||||
reference(startinfo2);
|
||||
}
|
||||
mylock_unlock(&(startinfo_table.lock));
|
||||
|
||||
if (rc > 0) {
|
||||
destroy_(startinfo1, (obj_destroy_fn_t)startinfo_destroy);
|
||||
return (job_startinfo_t*)startinfo2;
|
||||
}
|
||||
|
||||
mylock_lock(&(startinfo_table.lock));
|
||||
rc = key_add(startinfo_table.startinfo_table, (void*)startinfo1,
|
||||
startinfo1);
|
||||
mylock_unlock(&(startinfo_table.lock));
|
||||
|
||||
if (rc < 0) {
|
||||
destroy_(startinfo1, (obj_destroy_fn_t)startinfo_destroy);
|
||||
startinfo1 = NULL;
|
||||
errno = -rc;
|
||||
} else {
|
||||
errno = 0;
|
||||
}
|
||||
return startinfo1;
|
||||
}
|
||||
|
||||
static void startinfo_killer(var s)
|
||||
{
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
destroy_(s, (obj_destroy_fn_t)startinfo_destroy);
|
||||
}
|
||||
|
||||
static int startinfo_table_init(int nslots)
|
||||
{
|
||||
if (nslots <= 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_init(&(startinfo_table.lock));
|
||||
startinfo_table.startinfo_table
|
||||
= makeInstance(&kvtab_generic_type, nslots, startinfo_killer,
|
||||
sizeof(job_startinfo_t), key_cmp_default);
|
||||
if (startinfo_table.startinfo_table == NULL) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void startinfo_table_fini()
|
||||
{
|
||||
destroy(startinfo_table.startinfo_table);
|
||||
mylock_fini(&(startinfo_table.lock));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
my_rwlock_t lock;
|
||||
uint64_t refcount;
|
||||
} job_private_t;
|
||||
|
||||
static size_t job_datasize(va_list ap)
|
||||
{
|
||||
size_t sz = sizeof(xce_job_t);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int job_init(meta_obj_t* obj, va_list ap)
|
||||
{
|
||||
xce_job_t* dst = RTTI_OBJ_TO_DATA(xce_job_t, obj);
|
||||
job_private_t* priv = (job_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
xce_job_t* src = va_arg(ap, xce_job_t*);
|
||||
|
||||
if (src->submit == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dst->jobid = src->jobid;
|
||||
dst->submit = makeJobsub(src->submit);
|
||||
dst->sub_time = src->sub_time;
|
||||
dst->queue_time = src->queue_time;
|
||||
dst->start_time = src->start_time;
|
||||
dst->finish_time = src->finish_time;
|
||||
MOVE_PTR(dst->pidinfo, src->pidinfo);
|
||||
dst->state = src->state;
|
||||
MOVE_PTR(dst->allocs, src->allocs);
|
||||
MOVE_PTR(dst->accounts, src->accounts);
|
||||
dst->run_time = src->run_time;
|
||||
MOVE_PTR(dst->run_usage, src->run_usage);
|
||||
MOVE_PTR(dst->exit_info, src->exit_info);
|
||||
dst->ckptinfo = makeString(src->ckptinfo);
|
||||
dst->pending_ctrl = src->pending_ctrl;
|
||||
MOVE_PTR(dst->pend_reasons, src->pend_reasons);
|
||||
|
||||
my_rwlock_init(&(priv->lock));
|
||||
priv->refcount = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void job_destroy(meta_obj_t* obj)
|
||||
{
|
||||
xce_job_t* j = RTTI_OBJ_TO_DATA(xce_job_t, obj);
|
||||
job_private_t* priv = (job_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
dereference(j->submit);
|
||||
dereference(j->ckptinfo);
|
||||
|
||||
/* FIXME: */
|
||||
if (j->pidinfo != NULL) { }
|
||||
|
||||
if (j->allocs != NULL) { }
|
||||
|
||||
if (j->accounts != NULL) { }
|
||||
|
||||
if (j->run_usage != NULL) { }
|
||||
|
||||
if (j->exit_info != NULL) { }
|
||||
|
||||
if (j->pend_reasons != NULL) { }
|
||||
|
||||
my_rwlock_fini(&(priv->lock));
|
||||
memset(priv, 0x0, sizeof(*priv));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int job_reference(meta_obj_t* obj)
|
||||
{
|
||||
job_private_t* priv = (job_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
my_rwlock_wlock(&(priv->lock));
|
||||
priv->refcount++;
|
||||
my_rwlock_unlock(&(priv->lock));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void job_dereference(meta_obj_t* obj)
|
||||
{
|
||||
job_private_t* priv = (job_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
xce_job_t* j = RTTI_OBJ_TO_DATA(xce_job_t, obj);
|
||||
uint64_t count;
|
||||
|
||||
my_rwlock_wlock(&(priv->lock));
|
||||
priv->refcount--;
|
||||
count = priv->refcount;
|
||||
my_rwlock_unlock(&(priv->lock));
|
||||
|
||||
if (count == 0) {
|
||||
destroy_(j, (obj_destroy_fn_t)job_destroy);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int job_lock(meta_obj_t* obj, uint64_t option)
|
||||
{
|
||||
job_private_t* priv = (job_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 job_unlock(meta_obj_t* obj)
|
||||
{
|
||||
job_private_t* priv = (job_private_t*)RTTI_OBJ_TO_PRIV(obj);
|
||||
|
||||
my_rwlock_unlock(&(priv->lock));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static typeinfo_t job_type = {
|
||||
.name = "xce job",
|
||||
.privateSize = sizeof(job_private_t),
|
||||
.dataSize = (datasize_fn_t)job_datasize,
|
||||
.init = (obj_init_fn_t)job_init,
|
||||
.destroy = NULL,
|
||||
.interfaces
|
||||
= { .reference
|
||||
= &(intf_reference_t) { .reference = (reference_fn_t)job_reference,
|
||||
.dereference
|
||||
= (dereference_fn_t)job_dereference },
|
||||
.lock = &(intf_lock_t) { .lock = (lock_fn_t)job_lock,
|
||||
.unlock = (unlock_fn_t)job_unlock } }
|
||||
};
|
||||
|
||||
xce_job_t* makeJob(xce_job_t* j)
|
||||
{
|
||||
xce_job_t* job = makeInstance(&job_type, j);
|
||||
return job;
|
||||
}
|
||||
|
||||
int job_obj_init(int n_sub_table_slots, int n_startinfo_table_slots)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = jobsub_table_init(n_sub_table_slots);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = startinfo_table_init(n_startinfo_table_slots);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void job_obj_fini(void)
|
||||
{
|
||||
jobsub_table_fini();
|
||||
startinfo_table_fini();
|
||||
}
|
||||
192
src/lib/kv.c
192
src/lib/kv.c
|
|
@ -15,9 +15,9 @@ struct kvent_ {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t nslots;
|
||||
kv_value_kill_fn_t val_killer;
|
||||
kvent_t** slots;
|
||||
uint32_t nslots;
|
||||
destroy_fn_t val_killer;
|
||||
kvent_t** slots;
|
||||
} kvtab_t;
|
||||
|
||||
static size_t kvtab_datasize(va_list ap)
|
||||
|
|
@ -28,9 +28,9 @@ 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);
|
||||
kv_value_kill_fn_t killer = va_arg(ap, kv_value_kill_fn_t);
|
||||
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);
|
||||
|
||||
if (nslots <= 1) {
|
||||
return -EINVAL;
|
||||
|
|
@ -310,3 +310,183 @@ typeinfo_t kvtab_string_type
|
|||
.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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ libxce_src = [ gen_srcs[0],
|
|||
'resreq.c',
|
||||
'bitset.c',
|
||||
'kv.c',
|
||||
'jobj.c',
|
||||
'qobj.c',
|
||||
'resobj.c',
|
||||
'wobj.c',
|
||||
]
|
||||
|
||||
incdir = include_directories('../include')
|
||||
|
|
@ -137,6 +141,7 @@ libxce_test_src = ['testsuite/test.c',
|
|||
'testsuite/test_resreq.c',
|
||||
'testsuite/test_bitset.c',
|
||||
'testsuite/test_kv.c',
|
||||
'testsuite/test_jobj.c',
|
||||
]
|
||||
|
||||
libxce_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep]
|
||||
|
|
|
|||
5
src/lib/qobj.c
Normal file
5
src/lib/qobj.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include <errno.h>
|
||||
#include <rtti.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
5
src/lib/resobj.c
Normal file
5
src/lib/resobj.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include <errno.h>
|
||||
#include <rtti.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -24,6 +24,7 @@ extern void test_xvec(void);
|
|||
extern void test_resreq(void);
|
||||
extern void test_bitset(void);
|
||||
extern void test_kv(void);
|
||||
extern void test_jobobj(void);
|
||||
|
||||
void setUp(void) { return; }
|
||||
|
||||
|
|
@ -117,6 +118,7 @@ int main(int argc, char* argv[])
|
|||
TEST(test_resreq);
|
||||
TEST(test_bitset);
|
||||
TEST(test_kv);
|
||||
TEST(test_jobobj);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
290
src/lib/testsuite/test_jobj.c
Normal file
290
src/lib/testsuite/test_jobj.c
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <unity/unity.h>
|
||||
|
||||
#include "jobj.h"
|
||||
#include "utils.h"
|
||||
#include "xstring.h"
|
||||
|
||||
static void test_startinfo_create()
|
||||
{
|
||||
int rc;
|
||||
job_startinfo_t s1 = { .exechome = "/homes/rshen",
|
||||
.execcwd = "/tmp",
|
||||
.execuser = "rshen",
|
||||
.cmdline = "sleep 3000",
|
||||
.exdata = "Hello",
|
||||
.q_pre_exec = "sleep 1",
|
||||
.q_post_exec = "sleep 10",
|
||||
.job_pre_exec = "pwd",
|
||||
.job_post_exec = "hello" };
|
||||
job_startinfo_t* s2 = NULL;
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = job_obj_init(31, 31);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
s2 = makeJobstartinfo(&s1);
|
||||
|
||||
TEST_ASSERT_TRUE(s2 != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(EQUAL_STRING(s1.exechome, s2->exechome)
|
||||
&& EQUAL_STRING(s1.execcwd, s2->execcwd)
|
||||
&& EQUAL_STRING(s1.execuser, s2->execuser)
|
||||
&& EQUAL_STRING(s1.cmdline, s2->cmdline)
|
||||
&& EQUAL_STRING(s1.exdata, s2->exdata)
|
||||
&& EQUAL_STRING(s1.q_pre_exec, s2->q_pre_exec)
|
||||
&& EQUAL_STRING(s1.q_post_exec, s2->q_post_exec)
|
||||
&& EQUAL_STRING(s1.job_pre_exec, s2->job_pre_exec)
|
||||
&& EQUAL_STRING(s1.job_post_exec, s2->job_post_exec));
|
||||
job_obj_fini();
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
||||
static void test_startinfo_share()
|
||||
{
|
||||
int rc;
|
||||
job_startinfo_t s1 = { .exechome = "/homes/rshen",
|
||||
.execcwd = "/tmp",
|
||||
.execuser = "rshen",
|
||||
.cmdline = "sleep 3000",
|
||||
.exdata = "Hello",
|
||||
.q_pre_exec = "sleep 1",
|
||||
.q_post_exec = "sleep 10",
|
||||
.job_pre_exec = "pwd",
|
||||
.job_post_exec = "hello" };
|
||||
job_startinfo_t* s2 = NULL;
|
||||
job_startinfo_t* s3 = NULL;
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = job_obj_init(31, 31);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
s2 = makeJobstartinfo(&s1);
|
||||
|
||||
TEST_ASSERT_TRUE(s2 != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(EQUAL_STRING(s1.exechome, s2->exechome)
|
||||
&& EQUAL_STRING(s1.execcwd, s2->execcwd)
|
||||
&& EQUAL_STRING(s1.execuser, s2->execuser)
|
||||
&& EQUAL_STRING(s1.cmdline, s2->cmdline)
|
||||
&& EQUAL_STRING(s1.exdata, s2->exdata)
|
||||
&& EQUAL_STRING(s1.q_pre_exec, s2->q_pre_exec)
|
||||
&& EQUAL_STRING(s1.q_post_exec, s2->q_post_exec)
|
||||
&& EQUAL_STRING(s1.job_pre_exec, s2->job_pre_exec)
|
||||
&& EQUAL_STRING(s1.job_post_exec, s2->job_post_exec));
|
||||
|
||||
s3 = makeJobstartinfo(&s1);
|
||||
TEST_ASSERT_TRUE(s2 == s3);
|
||||
|
||||
job_obj_fini();
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
||||
static void test_jobsub_create(void)
|
||||
{
|
||||
int rc;
|
||||
job_startinfo_t s1 = { .exechome = "/homes/rshen",
|
||||
.execcwd = "/tmp",
|
||||
.execuser = "rshen",
|
||||
.cmdline = "sleep 3000",
|
||||
.exdata = "Hello",
|
||||
.q_pre_exec = "sleep 1",
|
||||
.q_post_exec = "sleep 10",
|
||||
.job_pre_exec = "pwd",
|
||||
.job_post_exec = "hello" };
|
||||
job_submit_data_t jobsub1 = { .queue = "xce",
|
||||
.user = "rshen",
|
||||
.mintasks = 1,
|
||||
.maxtasks = 5,
|
||||
.start_info = &s1,
|
||||
.job_name = "J1",
|
||||
.project_name = "default",
|
||||
.user_group = NULL,
|
||||
.job_description = "no description",
|
||||
.resreq = "type == any" };
|
||||
job_submit_data_t* s2 = NULL;
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = job_obj_init(31, 31);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
s2 = makeJobsub(&jobsub1);
|
||||
|
||||
TEST_ASSERT_TRUE(s2 != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(
|
||||
EQUAL_STRING(s1.exechome, s2->start_info->exechome)
|
||||
&& EQUAL_STRING(s1.execcwd, s2->start_info->execcwd)
|
||||
&& EQUAL_STRING(s1.execuser, s2->start_info->execuser)
|
||||
&& EQUAL_STRING(s1.cmdline, s2->start_info->cmdline)
|
||||
&& EQUAL_STRING(s1.exdata, s2->start_info->exdata)
|
||||
&& EQUAL_STRING(s1.q_pre_exec, s2->start_info->q_pre_exec)
|
||||
&& EQUAL_STRING(s1.q_post_exec, s2->start_info->q_post_exec)
|
||||
&& EQUAL_STRING(s1.job_pre_exec, s2->start_info->job_pre_exec)
|
||||
&& EQUAL_STRING(s1.job_post_exec, s2->start_info->job_post_exec)
|
||||
&& EQUAL_STRING(s2->queue, "xce") && EQUAL_STRING(s2->user, "rshen")
|
||||
&& EQUAL_STRING(s2->job_name, "J1")
|
||||
&& EQUAL_STRING(s2->project_name, "default")
|
||||
&& EQUAL_STRING(s2->job_description, "no description")
|
||||
&& EQUAL_STRING(s2->resreq, "type == any") && (s2->mintasks == 1)
|
||||
&& (s2->maxtasks == 5) && (s2->user_group == NULL));
|
||||
|
||||
job_obj_fini();
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
||||
static void test_jobsub_share(void)
|
||||
{
|
||||
int rc;
|
||||
job_startinfo_t s1 = { .exechome = "/homes/rshen",
|
||||
.execcwd = "/tmp",
|
||||
.execuser = "rshen",
|
||||
.cmdline = "sleep 3000",
|
||||
.exdata = "Hello",
|
||||
.q_pre_exec = "sleep 1",
|
||||
.q_post_exec = "sleep 10",
|
||||
.job_pre_exec = "pwd",
|
||||
.job_post_exec = "hello" };
|
||||
job_submit_data_t jobsub1 = { .queue = "xce",
|
||||
.user = "rshen",
|
||||
.mintasks = 1,
|
||||
.maxtasks = 5,
|
||||
.start_info = &s1,
|
||||
.job_name = "J1",
|
||||
.project_name = "default",
|
||||
.user_group = NULL,
|
||||
.job_description = "no description",
|
||||
.resreq = "type == any" };
|
||||
job_submit_data_t* s2 = NULL;
|
||||
job_submit_data_t* s3 = NULL;
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = job_obj_init(31, 31);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
s2 = makeJobsub(&jobsub1);
|
||||
|
||||
TEST_ASSERT_TRUE(s2 != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(
|
||||
EQUAL_STRING(s1.exechome, s2->start_info->exechome)
|
||||
&& EQUAL_STRING(s1.execcwd, s2->start_info->execcwd)
|
||||
&& EQUAL_STRING(s1.execuser, s2->start_info->execuser)
|
||||
&& EQUAL_STRING(s1.cmdline, s2->start_info->cmdline)
|
||||
&& EQUAL_STRING(s1.exdata, s2->start_info->exdata)
|
||||
&& EQUAL_STRING(s1.q_pre_exec, s2->start_info->q_pre_exec)
|
||||
&& EQUAL_STRING(s1.q_post_exec, s2->start_info->q_post_exec)
|
||||
&& EQUAL_STRING(s1.job_pre_exec, s2->start_info->job_pre_exec)
|
||||
&& EQUAL_STRING(s1.job_post_exec, s2->start_info->job_post_exec)
|
||||
&& EQUAL_STRING(s2->queue, "xce") && EQUAL_STRING(s2->user, "rshen")
|
||||
&& EQUAL_STRING(s2->job_name, "J1")
|
||||
&& EQUAL_STRING(s2->project_name, "default")
|
||||
&& EQUAL_STRING(s2->job_description, "no description")
|
||||
&& EQUAL_STRING(s2->resreq, "type == any") && (s2->mintasks == 1)
|
||||
&& (s2->maxtasks == 5) && (s2->user_group == NULL));
|
||||
|
||||
s3 = makeJobsub(&jobsub1);
|
||||
|
||||
TEST_ASSERT_TRUE(s2 == s3);
|
||||
|
||||
job_obj_fini();
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
||||
static void test_job_create(void)
|
||||
{
|
||||
int rc;
|
||||
job_startinfo_t s1 = { .exechome = "/homes/rshen",
|
||||
.execcwd = "/tmp",
|
||||
.execuser = "rshen",
|
||||
.cmdline = "sleep 3000",
|
||||
.exdata = "Hello",
|
||||
.q_pre_exec = "sleep 1",
|
||||
.q_post_exec = "sleep 10",
|
||||
.job_pre_exec = "pwd",
|
||||
.job_post_exec = "hello" };
|
||||
job_submit_data_t jobsub1 = { .queue = "xce",
|
||||
.user = "rshen",
|
||||
.mintasks = 1,
|
||||
.maxtasks = 5,
|
||||
.start_info = &s1,
|
||||
.job_name = "J1",
|
||||
.project_name = "default",
|
||||
.user_group = NULL,
|
||||
.job_description = "no description",
|
||||
.resreq = "type == any" };
|
||||
xce_job_t job1 = { .submit = &jobsub1 };
|
||||
xce_job_t* j2 = NULL;
|
||||
time_t now = time(NULL);
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = job_obj_init(31, 31);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
job1.sub_time = now;
|
||||
job1.queue_time = now;
|
||||
job1.start_time = 0;
|
||||
job1.finish_time = 0;
|
||||
job1.pidinfo = NULL;
|
||||
job1.state = JOB_STAT_PEND;
|
||||
job1.allocs = NULL;
|
||||
job1.run_time = 0;
|
||||
job1.run_usage = NULL;
|
||||
job1.exit_info = NULL;
|
||||
job1.ckptinfo = NULL;
|
||||
job1.pending_ctrl = 0;
|
||||
job1.jobid = 100;
|
||||
|
||||
j2 = makeJob(&job1);
|
||||
|
||||
TEST_ASSERT_TRUE(j2 != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(
|
||||
EQUAL_STRING(s1.exechome, j2->submit->start_info->exechome)
|
||||
&& EQUAL_STRING(s1.execcwd, j2->submit->start_info->execcwd)
|
||||
&& EQUAL_STRING(s1.execuser, j2->submit->start_info->execuser)
|
||||
&& EQUAL_STRING(s1.cmdline, j2->submit->start_info->cmdline)
|
||||
&& EQUAL_STRING(s1.exdata, j2->submit->start_info->exdata)
|
||||
&& EQUAL_STRING(s1.q_pre_exec, j2->submit->start_info->q_pre_exec)
|
||||
&& EQUAL_STRING(s1.q_post_exec, j2->submit->start_info->q_post_exec)
|
||||
&& EQUAL_STRING(s1.job_pre_exec, j2->submit->start_info->job_pre_exec)
|
||||
&& EQUAL_STRING(s1.job_post_exec, j2->submit->start_info->job_post_exec)
|
||||
&& EQUAL_STRING(j2->submit->queue, "xce")
|
||||
&& EQUAL_STRING(j2->submit->user, "rshen")
|
||||
&& EQUAL_STRING(j2->submit->job_name, "J1")
|
||||
&& EQUAL_STRING(j2->submit->project_name, "default")
|
||||
&& EQUAL_STRING(j2->submit->job_description, "no description")
|
||||
&& EQUAL_STRING(j2->submit->resreq, "type == any")
|
||||
&& (j2->submit->mintasks == 1) && (j2->submit->maxtasks == 5)
|
||||
&& (j2->submit->user_group == NULL));
|
||||
|
||||
destroy(j2);
|
||||
|
||||
job_obj_fini();
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
||||
void test_jobobj(void)
|
||||
{
|
||||
printf("\n>> job obj test\n\n");
|
||||
|
||||
RUN_TEST(test_startinfo_create);
|
||||
RUN_TEST(test_startinfo_share);
|
||||
RUN_TEST(test_jobsub_create);
|
||||
RUN_TEST(test_jobsub_share);
|
||||
RUN_TEST(test_job_create);
|
||||
}
|
||||
5
src/lib/wobj.c
Normal file
5
src/lib/wobj.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include <errno.h>
|
||||
#include <rtti.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
Loading…
Add table
Add a link
Reference in a new issue