forked from lei.chen/myxce
use nix build & meson & zlog
This commit is contained in:
parent
0123623742
commit
346768a144
60 changed files with 13739 additions and 0 deletions
37
src/default.nix
Normal file
37
src/default.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
pkgs,
|
||||
myCommitId,
|
||||
...
|
||||
}:
|
||||
let
|
||||
xce = pkgs.callPackage ./xce.nix {
|
||||
inherit pkgs myCommitId;
|
||||
withDebug = false;
|
||||
withAsan = false;
|
||||
withoutDb = false;
|
||||
};
|
||||
xce_withoutdb = pkgs.callPackage ./xce.nix {
|
||||
inherit pkgs myCommitId;
|
||||
withDebug = false;
|
||||
withAsan = false;
|
||||
withoutDb = true;
|
||||
};
|
||||
xce_withoutdb_debug = pkgs.callPackage ./xce.nix {
|
||||
inherit pkgs myCommitId;
|
||||
withDebug = true;
|
||||
withAsan = true;
|
||||
withoutDb = true;
|
||||
};
|
||||
xce_debug = pkgs.callPackage ./xce.nix {
|
||||
inherit pkgs myCommitId;
|
||||
withDebug = true;
|
||||
withAsan = true;
|
||||
withoutDb = false;
|
||||
};
|
||||
in
|
||||
{
|
||||
xce = xce;
|
||||
xce_debug = xce_debug;
|
||||
xce_withoutdb = xce_withoutdb;
|
||||
xce_withoutdb_debug = xce_withoutdb_debug;
|
||||
}
|
||||
97
src/flake.lock
generated
Normal file
97
src/flake.lock
generated
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1761907660,
|
||||
"narHash": "sha256-kJ8lIZsiPOmbkJypG+B5sReDXSD1KGu2VEPNqhRa/ew=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2fb006b87f04c4d3bdf08cfdbc7fab9c13d94a15",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1755615617,
|
||||
"narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "20075955deac2583bb12f07151c2df830ef346b4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"xbuild": "xbuild"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xbuild": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762160937,
|
||||
"narHash": "sha256-L0wBnhZxneDKm9ym7XroRexjuio62sVV0xi5sgAMiaA=",
|
||||
"owner": "shen390s",
|
||||
"repo": "my-nix-channel",
|
||||
"rev": "3eb8b50d886f197ec5b842aadb022b026c9b2bfd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "shen390s",
|
||||
"ref": "master",
|
||||
"repo": "my-nix-channel",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
38
src/flake.nix
Normal file
38
src/flake.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
description = "Flake for NEXA xce";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||
xbuild.url = "github:shen390s/my-nix-channel?ref=master";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, xbuild, flake-utils }:
|
||||
let
|
||||
supportedSystems = [ "x86_64-linux" ];
|
||||
myCommitId =
|
||||
if builtins.hasAttr "shortRev" self
|
||||
then self.shortRev
|
||||
else self.dirtyShortRev;
|
||||
in
|
||||
flake-utils.lib.eachSystem supportedSystems (
|
||||
system: let
|
||||
mypkgs = xbuild.packages.${system};
|
||||
overlays = [
|
||||
(final: prev: prev // mypkgs)
|
||||
];
|
||||
pkgs = import nixpkgs { inherit overlays system;};
|
||||
xpkgs = import ./default.nix {
|
||||
inherit pkgs myCommitId;
|
||||
};
|
||||
in rec {
|
||||
packages = pkgs // xpkgs;
|
||||
defaultPackage = xpkgs.xce_withoutdb_debug;
|
||||
devShells.default = pkgs.mkShell {
|
||||
nativeBuildInputs = xpkgs.xce.nativeBuildInputs;
|
||||
};
|
||||
|
||||
devShell = self.devShells.${system}.default;
|
||||
}
|
||||
);
|
||||
}
|
||||
81
src/include/client.h
Normal file
81
src/include/client.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#if !defined(_CLIENT_H_)
|
||||
|
||||
#define _CLIENT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "netio.h"
|
||||
#include "request.h"
|
||||
#include "xce/types.h"
|
||||
#include "xceapi.h"
|
||||
|
||||
typedef int (*xce_request_handler_t)(xce_request_t*);
|
||||
typedef void* xcecli_ctx_t;
|
||||
|
||||
#define N_MAX_MASTERS (3)
|
||||
|
||||
typedef struct {
|
||||
int nmasters;
|
||||
char* masters[N_MAX_MASTERS];
|
||||
int master_ports[N_MAX_MASTERS];
|
||||
char* from;
|
||||
char* key;
|
||||
} xce_client_config_t;
|
||||
|
||||
#define xcecli_jobfinish(ctx, finish) \
|
||||
xcecli_notify_jobfinish(ctx, finish)
|
||||
|
||||
extern int xcecli_ctx_init(xcecli_ctx_t*, xce_client_config_t*);
|
||||
extern void xcecli_ctx_fini(xcecli_ctx_t);
|
||||
extern int xcecli_set_handler(xcecli_ctx_t, xce_request_handler_t);
|
||||
extern int xcecli_start(xcecli_ctx_t);
|
||||
extern int xcecli_stop(xcecli_ctx_t);
|
||||
extern int xcecli_wakeup(xcecli_ctx_t, int);
|
||||
extern int xcecli_hello(xcecli_ctx_t, char*);
|
||||
extern int xcecli_shutdown(xcecli_ctx_t);
|
||||
extern int xcecli_reslist(xcecli_ctx_t, xce_resource_t***);
|
||||
extern int xcecli_join(xcecli_ctx_t, int, hostattrs_t*);
|
||||
extern int xcecli_workerlist(xcecli_ctx_t, xce_worker_t***);
|
||||
extern int xcecli_jobdispatch(xcecli_ctx_t, xce_job_dispatch_t*);
|
||||
extern int xcecli_joblist(xcecli_ctx_t, xce_job_t***);
|
||||
extern int xcecli_clusterconf(xcecli_ctx_t, xce_clusterconf_t**);
|
||||
extern int xcecli_notify_jobfinish(xcecli_ctx_t, xce_jobfinish_t*);
|
||||
extern int xcecli_notify_jobstart(xcecli_ctx_t, job_pidinfo_t*);
|
||||
extern int xcecli_notify_jobfail(xcecli_ctx_t c, job_failinfo_t*);
|
||||
extern int xcecli_notify_jobstop(xcecli_ctx_t, uint64_t);
|
||||
extern int xcecli_notify_jobresume(xcecli_ctx_t, uint64_t);
|
||||
extern int xcecli_notify_jobpostdone(xcecli_ctx_t, uint64_t);
|
||||
extern int xcecli_jobsubmit(xcecli_ctx_t, xce_job_submit_t*,
|
||||
uint64_t*);
|
||||
extern int xcecli_update_resvals(xcecli_ctx_t, int, xce_resval_t**);
|
||||
extern int xcecli_resval(xcecli_ctx_t, char*,
|
||||
char*, xce_resval_t***);
|
||||
extern int xcecli_update_jusage(xcecli_ctx_t, uint64_t, int, int*,
|
||||
int, int*, int, xce_rusage_t**);
|
||||
extern int xcecli_notify(xcecli_ctx_t, xce_notify_data_t*);
|
||||
extern int xcecli_jobctrl(xcecli_ctx_t, xce_jobctrl_t*);
|
||||
extern int xcecli_notify_jobchkpt(xcecli_ctx_t, uint64_t, char*);
|
||||
extern int xcecli_queuectrl(xcecli_ctx_t, xce_queuectrl_t*);
|
||||
extern int xcecli_runtask(xcecli_ctx_t, xce_taskrun_t*);
|
||||
extern int xcecli_notify_taskstart(xcecli_ctx_t, xce_task_pidinfo_t*);
|
||||
extern int xcecli_notify_taskfail(xcecli_ctx_t, xce_task_failinfo_t*);
|
||||
extern int xcecli_notify_taskfinish(xcecli_ctx_t, xce_task_finish_t*);
|
||||
extern endpoint_t* xcecli_get_my_endpoint(xcecli_ctx_t);
|
||||
extern xce_peerinfo_t* xcecli_get_myinfo(xcecli_ctx_t);
|
||||
extern void xcecli_block_tasks(xcecli_ctx_t);
|
||||
extern void xcecli_unblock_tasks(xcecli_ctx_t);
|
||||
|
||||
#define xcecli_free_ress(nres, ress) \
|
||||
xce_free_ress(nres, ress)
|
||||
#define xcecli_free_workers(nworkers, workers) \
|
||||
xce_free_workers(nworkers, workers)
|
||||
#define xcecli_free_jobs(njobs, jobs) \
|
||||
xce_free_jobs(njobs, jobs)
|
||||
#define xcecli_free_queues(nqueues, queues) \
|
||||
xce_free_queues(nqueues, queues)
|
||||
#define xcecli_free_groups(ngroups, groups) \
|
||||
xce_free_groups(ngroups, groups)
|
||||
#define xcecli_free_clusterconf(conf) \
|
||||
xce_free_clusterconf(conf)
|
||||
|
||||
#endif
|
||||
58
src/include/clusterconfig.h
Normal file
58
src/include/clusterconfig.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#if !defined(_CLUSTERCONFIG_H_)
|
||||
|
||||
#define _CLUSTERCONFIG_H_ 1
|
||||
|
||||
#include "xce/types.h"
|
||||
|
||||
typedef struct {
|
||||
int nhash_slots;
|
||||
int delta;
|
||||
} hash_zarray_config_t;
|
||||
|
||||
typedef hash_zarray_config_t jobmgr_config_t;
|
||||
|
||||
typedef hash_zarray_config_t workermgr_config_t;
|
||||
typedef hash_zarray_config_t qmgr_config_t;
|
||||
|
||||
typedef struct {
|
||||
int nhash_slots;
|
||||
int delta;
|
||||
int inst_delta;
|
||||
} resmgr_config_t;
|
||||
|
||||
typedef hash_zarray_config_t xstrings_config_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* host;
|
||||
int port;
|
||||
} master_candidate_t;
|
||||
|
||||
typedef struct {
|
||||
char* clustername;
|
||||
int port;
|
||||
int ncandidates;
|
||||
master_candidate_t** candidates;
|
||||
int heartbeat_interval;
|
||||
int inactive_heartbeat_count;
|
||||
int fetch_job_interval;
|
||||
int netio_timeout;
|
||||
int vcpus;
|
||||
int nres;
|
||||
xce_resource_t** resources;
|
||||
int nqueues;
|
||||
xce_queue_t** queues;
|
||||
int nugroups;
|
||||
xce_group_t** ugroups;
|
||||
int nhgroups;
|
||||
xce_group_t** hgroups;
|
||||
int nhconfigs;
|
||||
xce_hostconfig_t** hconfigs;
|
||||
jobmgr_config_t* jobmgr;
|
||||
workermgr_config_t* workermgr;
|
||||
qmgr_config_t* qmgr;
|
||||
resmgr_config_t* resmgr;
|
||||
xstrings_config_t* xstrings;
|
||||
} cluster_config_t;
|
||||
|
||||
#endif
|
||||
20
src/include/config.h
Normal file
20
src/include/config.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#if !defined(_CONFIG_H_)
|
||||
|
||||
#define _CONFIG_H_
|
||||
|
||||
#define BUG_EMAIL "rshen@shenrs.eu"
|
||||
#define XCE_MAXNAME_LEN (64)
|
||||
#define XCE_MAXHOSTNAME_LEN (256) /* hostname suggest to 256 */
|
||||
#define XCE_MAXDESC_LEN (4096) /* enlarge to 4096 */
|
||||
#define XCE_MAXKEY_LEN (256)
|
||||
#define XCE_MAXMODEL_LEN (32)
|
||||
#define XCE_MAXTYPE_LEN (32)
|
||||
|
||||
#define XCE_WORKER_HTAB_SIZE (673)
|
||||
#define XCE_JOB_HTAB_SIZE (5009)
|
||||
|
||||
#define XCE_MAXPATH_LEN (4096) /* enlarge to 4096 */
|
||||
#define XCE_MAXCMD_LEN (4096)
|
||||
#define XCE_MAX_ERRMSG_LEN (4096)
|
||||
|
||||
#endif
|
||||
28
src/include/dataq.h
Normal file
28
src/include/dataq.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#if !defined(_DATAQ_H_)
|
||||
|
||||
#define _DATAQ_H_ 1
|
||||
|
||||
#include "mylock.h"
|
||||
|
||||
typedef struct _data_item {
|
||||
struct _data_item* next;
|
||||
} data_item_t;
|
||||
|
||||
typedef int (*data_item_match_fn_t)(data_item_t*);
|
||||
typedef void (*data_item_killer_t)(data_item_t*);
|
||||
|
||||
typedef struct {
|
||||
data_item_t* head;
|
||||
data_item_t* tail;
|
||||
data_item_killer_t killer;
|
||||
mylock_t lock;
|
||||
} dataq_t;
|
||||
|
||||
#define DATAQ_EMPTY(q) ((q)->head == NULL)
|
||||
|
||||
extern int dataq_init(dataq_t*, data_item_killer_t);
|
||||
extern data_item_t* dataq_deq(dataq_t*, data_item_match_fn_t);
|
||||
extern int dataq_enq(dataq_t*, data_item_t*);
|
||||
extern void dataq_fini(dataq_t*);
|
||||
|
||||
#endif
|
||||
30
src/include/hook.h
Normal file
30
src/include/hook.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#if !defined(__HOOK_H__)
|
||||
|
||||
#define __HOOK_H__ 1
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "xlist.h"
|
||||
|
||||
#define HOOK_BEFORE_EVENT (0)
|
||||
#define HOOK_AFTER_EVENT (1)
|
||||
|
||||
typedef int (*hook_fn_t)(int, int, int, void*, va_list);
|
||||
typedef struct {
|
||||
hook_fn_t fn;
|
||||
void* data;
|
||||
} hook_item_t;
|
||||
|
||||
typedef struct {
|
||||
int maxtypes;
|
||||
xlist_t* hooks;
|
||||
} hooksys_t;
|
||||
|
||||
extern int xce_hook_init(hooksys_t*, int);
|
||||
extern int xce_add_hook(hooksys_t*, int,
|
||||
hook_fn_t, void*);
|
||||
extern int xce_run_hooks(hooksys_t*, int, int, int, ...);
|
||||
extern void xce_hook_fini(hooksys_t*);
|
||||
|
||||
#endif
|
||||
44
src/include/htab.h
Normal file
44
src/include/htab.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#if !defined(_HTAB_H_)
|
||||
|
||||
#define _HTAB_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mylock.h"
|
||||
|
||||
typedef unsigned int (*hash_key_hash_fn_t)(void*);
|
||||
typedef int (*hash_key_cmp_fn_t)(void*, void*);
|
||||
typedef void* (*hash_key_copy_fn_t)(void*);
|
||||
typedef void (*hash_key_free_fn_t)(void*);
|
||||
|
||||
typedef struct {
|
||||
hash_key_hash_fn_t hash;
|
||||
hash_key_cmp_fn_t cmp;
|
||||
hash_key_copy_fn_t copy;
|
||||
hash_key_free_fn_t free;
|
||||
} hash_key_fn_t;
|
||||
|
||||
typedef struct _hent {
|
||||
struct _hent* next;
|
||||
void* key;
|
||||
int64_t data;
|
||||
} hent_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
int nslots;
|
||||
hash_key_fn_t fn;
|
||||
hent_t** slots;
|
||||
} htab_t;
|
||||
|
||||
extern hash_key_fn_t string_hash_key;
|
||||
extern hash_key_fn_t int_hash_key;
|
||||
|
||||
extern int ht_init(htab_t*, int,
|
||||
hash_key_fn_t);
|
||||
extern void ht_fini(htab_t*);
|
||||
extern hent_t* ht_get(htab_t*, void*);
|
||||
extern hent_t* ht_add(htab_t*, void*);
|
||||
extern int ht_del(htab_t*, void*);
|
||||
|
||||
#endif
|
||||
26
src/include/kvmgr.h
Normal file
26
src/include/kvmgr.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#if !defined(__KVMGR_H__)
|
||||
|
||||
#define __KVMGR_H__ 1
|
||||
|
||||
#include "htab.h"
|
||||
#include "mylock.h"
|
||||
#include "xlist.h"
|
||||
#include "zarray.h"
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
htab_t htab;
|
||||
zarray_t data;
|
||||
} kvmgr_t;
|
||||
|
||||
extern int kvmgr_init(kvmgr_t*, hash_key_fn_t,
|
||||
int, int,
|
||||
zarray_item_killer_t);
|
||||
extern void kvmgr_fini(kvmgr_t*);
|
||||
extern void* kvmgr_lock(kvmgr_t*, void*, int);
|
||||
extern int32_t kvmgr_add(kvmgr_t*, void*, void*);
|
||||
extern void kvmgr_del(kvmgr_t*, void*);
|
||||
extern int kvmgr_publish(kvmgr_t*, xlist_action_fn_t, void*);
|
||||
extern int kvmgr_iter(kvmgr_t*, xlist_t*, void*);
|
||||
|
||||
#endif
|
||||
38
src/include/mylock.h
Normal file
38
src/include/mylock.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#if !defined(_MYLOCK_H_)
|
||||
|
||||
#define _MYLOCK_H_ 1
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_mutex_t mylock_t;
|
||||
typedef pthread_rwlock_t my_rwlock_t;
|
||||
|
||||
typedef struct {
|
||||
int ncap;
|
||||
int head;
|
||||
int len;
|
||||
int isize;
|
||||
void* data;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t condget;
|
||||
pthread_cond_t condput;
|
||||
} cbuf_t;
|
||||
|
||||
extern int mylock_init(mylock_t*);
|
||||
extern void mylock_fini(mylock_t*);
|
||||
extern int mylock_try(mylock_t*);
|
||||
extern int mylock_lock(mylock_t*);
|
||||
extern int mylock_unlock(mylock_t*);
|
||||
|
||||
extern int my_rwlock_init(my_rwlock_t*);
|
||||
extern void my_rwlock_fini(my_rwlock_t*);
|
||||
extern int my_rwlock_rlock(my_rwlock_t*);
|
||||
extern int my_rwlock_wlock(my_rwlock_t*);
|
||||
extern int my_rwlock_unlock(my_rwlock_t*);
|
||||
|
||||
extern int cbuf_init(cbuf_t*, int, int);
|
||||
extern void cbuf_fini(cbuf_t*);
|
||||
extern int cbuf_put(cbuf_t*, void*);
|
||||
extern int cbuf_tryput(cbuf_t*, void*);
|
||||
extern int cbuf_get(cbuf_t*, void*);
|
||||
#endif
|
||||
73
src/include/netio.h
Normal file
73
src/include/netio.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#if !defined(_NETIO_H_)
|
||||
|
||||
#define _NETIO_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "dataq.h"
|
||||
#include "mylock.h"
|
||||
|
||||
typedef int (*msghandler_t)(struct epoll_event*);
|
||||
|
||||
#define IO_MON_INPUT (0x01)
|
||||
#define IO_MON_OUTPUT (0x02)
|
||||
|
||||
typedef struct {
|
||||
uint16_t sz;
|
||||
char* data;
|
||||
} io_packet_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
int epoll_fd;
|
||||
struct epoll_event ev;
|
||||
pthread_t worker;
|
||||
} iomgr_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
iomgr_t* iomgr;
|
||||
int fd;
|
||||
int idx;
|
||||
int flags;
|
||||
unsigned int busy : 1;
|
||||
unsigned int needfree : 1;
|
||||
uint32_t refcount;
|
||||
dataq_t outq;
|
||||
uint64_t seq;
|
||||
msghandler_t handler;
|
||||
void* owner;
|
||||
void* data;
|
||||
} endpoint_t;
|
||||
|
||||
extern int netio_write(int, char*, int);
|
||||
extern int netio_read(int, char*, int);
|
||||
extern int write_packet(int, io_packet_t*);
|
||||
extern int alloc_packet(io_packet_t*);
|
||||
extern int read_packet(int, io_packet_t*);
|
||||
extern void free_packet(io_packet_t*);
|
||||
|
||||
extern endpoint_t* endpoint_get(void);
|
||||
extern int endpoint_init(endpoint_t*, int, int, int, int);
|
||||
extern int endpoint_connect(endpoint_t*, char*, int);
|
||||
extern int endpoint_accept(endpoint_t*, endpoint_t*);
|
||||
extern int endpoint_set_handler(endpoint_t*, msghandler_t, void*);
|
||||
extern int endpoint_enq(endpoint_t*, data_item_t*);
|
||||
extern data_item_t* endpoint_deq(endpoint_t*);
|
||||
extern endpoint_t* endpoint_ref(endpoint_t*);
|
||||
extern void endpoint_deref(endpoint_t*);
|
||||
extern uint64_t endpoint_getseq(endpoint_t*);
|
||||
extern void endpoint_block_tasks(endpoint_t*);
|
||||
extern void endpoint_unblock_tasks(endpoint_t*);
|
||||
extern int endpoint_is_task_blocked(endpoint_t*);
|
||||
|
||||
extern int iomgr_init(iomgr_t*);
|
||||
extern int iomgr_monitor(iomgr_t*, endpoint_t*);
|
||||
extern int iomgr_unmonitor(iomgr_t*, endpoint_t*);
|
||||
extern int iomgr_start(iomgr_t*);
|
||||
extern int iomgr_fini(iomgr_t*);
|
||||
extern int iomgr_stop(iomgr_t*);
|
||||
#endif
|
||||
78
src/include/objmgr.h
Normal file
78
src/include/objmgr.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#if !defined(__OBJMGR_H__)
|
||||
|
||||
#define __OBJMGR_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "htab.h"
|
||||
#include "mylock.h"
|
||||
#include "zarray.h"
|
||||
|
||||
#define OBJ_MAGIC (0x4a424f58)
|
||||
|
||||
#define OBJREF_NOP (0) /* ref obj without lock, \
|
||||
* just keep object alive */
|
||||
#define OBJREF_READ (1) /* ref obj with read lock */
|
||||
#define OBJREF_UPDATE (2) /* ref obj with write lock */
|
||||
|
||||
typedef void* (*obj_create_fn_t)(void*, void*,
|
||||
va_list);
|
||||
typedef void (*obj_fini_fn_t)(void*);
|
||||
typedef void (*objtype_fini_fn_t)(void*);
|
||||
|
||||
typedef struct {
|
||||
char* type; /* name of type */
|
||||
mylock_t lock;
|
||||
obj_create_fn_t fn_create; /* function to initialize object */
|
||||
obj_fini_fn_t fn_fini; /* function to finalize obj */
|
||||
objtype_fini_fn_t fn_type_fini; /* function to finalize typeinfo */
|
||||
void* typedata; /* extra information for type */
|
||||
} objtype_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t nref;
|
||||
my_rwlock_t rwlock;
|
||||
mylock_t lock;
|
||||
objtype_t* type;
|
||||
int32_t exdata;
|
||||
uint32_t nread : 28;
|
||||
uint32_t nwrite : 4;
|
||||
} myobj_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
htab_t names;
|
||||
zarray_t types;
|
||||
} objmgr_t;
|
||||
|
||||
#define MYOBJ_TO_OBJ(type, myobj) \
|
||||
((type)(((char*)myobj) + sizeof(myobj_t)))
|
||||
|
||||
#define TO_MYOBJ(obj) \
|
||||
((myobj_t*)(((char*)obj) - sizeof(myobj_t)))
|
||||
|
||||
#define DEREF_OBJ(obj) \
|
||||
if ((obj) != NULL) { \
|
||||
obj_deref(obj); \
|
||||
(obj) = NULL; \
|
||||
}
|
||||
|
||||
extern int objmgr_init(objmgr_t*);
|
||||
extern void objmgr_fini(objmgr_t*);
|
||||
extern int objmgr_register(objmgr_t*, objtype_t*);
|
||||
extern int obj_init(objmgr_t*, objtype_t*, int32_t, myobj_t*);
|
||||
extern void* create_obj_by_typeid(objmgr_t*, int, ...);
|
||||
extern void* create_obj_by_typename(objmgr_t*, char*, ...);
|
||||
extern void* obj_ref(void*, int);
|
||||
extern void obj_deref(void*);
|
||||
extern int typeid_of_name(objmgr_t*, char*);
|
||||
extern objmgr_t* objmgr_get_default();
|
||||
extern int objmgr_set_default(objmgr_t*);
|
||||
extern myobj_t* obj_alloc(size_t);
|
||||
|
||||
#endif
|
||||
9
src/include/objs.h
Normal file
9
src/include/objs.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#if !defined(_OBJS_H_)
|
||||
|
||||
#define _OBJS_H_ 1
|
||||
|
||||
#include "xce/types.h"
|
||||
|
||||
job_pidinfo_t *new_job_pidinfo(job_pidinfo_t *);
|
||||
|
||||
#endif
|
||||
82
src/include/request.h
Normal file
82
src/include/request.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#if !defined(_REQUEST_H_)
|
||||
|
||||
#define _REQUEST_H_ 1
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "netio.h"
|
||||
#include "typemap.h"
|
||||
#include "utils.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
typedef struct {
|
||||
int wait;
|
||||
} reqbar_t;
|
||||
|
||||
typedef struct {
|
||||
data_item_t link;
|
||||
endpoint_t* ep;
|
||||
xce_peerinfo_t* from;
|
||||
io_packet_t pkt;
|
||||
struct capn c;
|
||||
struct Request rq;
|
||||
uint32_t nrefs;
|
||||
} ioctx_t;
|
||||
|
||||
#define ITPTR_TO_IOCTX(p) \
|
||||
((ioctx_t*)(((char*)p) - offsetof(ioctx_t, link)))
|
||||
|
||||
typedef int (*xce_check_fn_t)(void*);
|
||||
|
||||
extern ioctx_t* ioctx_alloc(endpoint_t*, xce_peerinfo_t*);
|
||||
extern int ioctx_ref(ioctx_t*);
|
||||
extern void ioctx_deref(ioctx_t*, int);
|
||||
extern int ioctx_flush(ioctx_t*, int);
|
||||
extern int ioctx_encode(ioctx_t*, xce_request_t*);
|
||||
extern int ioctx_decode(ioctx_t*, xce_request_t*);
|
||||
|
||||
extern int xce_reply(endpoint_t*, xce_peerinfo_t*, xce_reply_t*);
|
||||
extern int xce_hello_req(ioctx_t*, char*);
|
||||
extern int xce_nop_req(ioctx_t*);
|
||||
extern int xce_shutdown_req(ioctx_t*);
|
||||
extern void init_reply_by_req(xce_reply_t*, xce_request_t*);
|
||||
extern int xce_join_req(ioctx_t*, int, hostattrs_t*);
|
||||
extern int xce_pushconfig_req(endpoint_t*,
|
||||
xce_peerinfo_t*,
|
||||
xce_configdata_t*);
|
||||
extern int xce_push_data_req(endpoint_t*, xce_peerinfo_t*,
|
||||
xce_data_t*, xce_check_fn_t,
|
||||
void*, int);
|
||||
|
||||
extern int xce_workerlist_req(ioctx_t*, xce_peerinfo_t*);
|
||||
extern int xce_reply_workerlist(endpoint_t*, uint64_t, int,
|
||||
xce_peerinfo_t*, xce_workerlist_t*);
|
||||
extern int xce_jobdispatch_req(ioctx_t*, xce_job_dispatch_t*);
|
||||
extern int xce_jobsubmit_req(ioctx_t*, xce_job_submit_t*);
|
||||
extern int xce_reply_jobdispatch(endpoint_t*, uint64_t, int32_t,
|
||||
xce_peerinfo_t*);
|
||||
extern int xce_reply_jobid(endpoint_t*, int,
|
||||
uint64_t, uint64_t,
|
||||
xce_peerinfo_t*);
|
||||
extern int xce_joblist_req(ioctx_t*, xce_peerinfo_t*);
|
||||
extern int xce_reply_joblist(endpoint_t*, uint64_t, int,
|
||||
xce_peerinfo_t*, xce_job_list_t*);
|
||||
extern int xce_startjob_req(ioctx_t*, xce_job_exec_t*);
|
||||
extern int xce_clusterconf_req(ioctx_t*);
|
||||
extern int xce_reply_clusterconf(endpoint_t*, uint64_t, int,
|
||||
xce_peerinfo_t*,
|
||||
xce_clusterconf_t*);
|
||||
extern int xce_get_req(ioctx_t*, xce_get_t*);
|
||||
extern int xce_reply_get(endpoint_t*, xce_peerinfo_t*,
|
||||
xce_reply_t*, xce_check_fn_t,
|
||||
void*, int);
|
||||
extern int xce_notify_req(ioctx_t*, xce_notify_data_t*);
|
||||
extern int extract_data(dataset_t*, xce_data_t*);
|
||||
extern int xce_update_req(ioctx_t*, xce_update_data_t*);
|
||||
extern int xce_jobctrl_req(ioctx_t*, xce_jobctrl_t*);
|
||||
extern int xce_queuectrl_req(ioctx_t*, xce_queuectrl_t*);
|
||||
extern int xce_runtask_req(ioctx_t* , xce_taskrun_t *) ;
|
||||
|
||||
#endif
|
||||
192
src/include/typemap.h
Normal file
192
src/include/typemap.h
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
#if !defined(_TYPEMAP_H_)
|
||||
|
||||
#define _TYPEMAP_H_ 1
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xce/types.h"
|
||||
|
||||
typedef struct {
|
||||
char* resname;
|
||||
char* hostname;
|
||||
} xce_reskey_t;
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
uint64_t jobid;
|
||||
char* wname;
|
||||
xce_reskey_t* reskey;
|
||||
} condition;
|
||||
} xce_match_t;
|
||||
|
||||
typedef struct {
|
||||
int table;
|
||||
int nrows;
|
||||
void* rows;
|
||||
} dataset_t;
|
||||
|
||||
typedef struct {
|
||||
int role;
|
||||
int data_which;
|
||||
union {
|
||||
hostattrs_t* attrs;
|
||||
} data;
|
||||
} xce_joindata_t;
|
||||
|
||||
typedef struct {
|
||||
char* clustername;
|
||||
int n_confvars;
|
||||
xce_config_t** confvars;
|
||||
int n_resources;
|
||||
xce_resource_t** resources;
|
||||
int n_queues;
|
||||
xce_queue_t** queues;
|
||||
int n_ugroups;
|
||||
xce_group_t** ugroups;
|
||||
int n_hgroups;
|
||||
xce_group_t** hgroups;
|
||||
int nresvals;
|
||||
xce_val_with_idx_t** resvals;
|
||||
} xce_conf4sched_t;
|
||||
|
||||
typedef struct {
|
||||
char* clustername;
|
||||
int n_confvars;
|
||||
xce_config_t** confvars;
|
||||
} xce_conf4worker_t;
|
||||
|
||||
typedef struct {
|
||||
int data_which;
|
||||
union {
|
||||
xce_conf4sched_t* conf4sched;
|
||||
xce_conf4worker_t* conf4worker;
|
||||
} data;
|
||||
} xce_configdata_t;
|
||||
|
||||
typedef struct {
|
||||
int n_total;
|
||||
int pos;
|
||||
int count;
|
||||
xce_job_t** jobs;
|
||||
} xce_jobs_data_t;
|
||||
|
||||
typedef struct {
|
||||
int n_total;
|
||||
int pos;
|
||||
int count;
|
||||
xce_worker_t** workers;
|
||||
} xce_workers_data_t;
|
||||
|
||||
typedef struct {
|
||||
int n_total;
|
||||
int pos;
|
||||
int count;
|
||||
xce_resource_t** resources;
|
||||
} xce_resource_data_t;
|
||||
|
||||
typedef struct {
|
||||
int n_total;
|
||||
int pos;
|
||||
int count;
|
||||
xce_resval_t** vals;
|
||||
} xce_resval_data_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_resval_t** vals;
|
||||
} xce_resval_list_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
int npids;
|
||||
int* pids;
|
||||
int npgids;
|
||||
int* pgids;
|
||||
int count;
|
||||
xce_rusage_t** usages;
|
||||
} xce_job_rusages_t;
|
||||
|
||||
typedef struct {
|
||||
int table;
|
||||
union {
|
||||
xce_jobs_data_t* jobs;
|
||||
xce_workers_data_t* workers;
|
||||
xce_resource_data_t* resources;
|
||||
xce_resval_data_t* resvals;
|
||||
} data;
|
||||
} xce_data_t;
|
||||
|
||||
typedef struct {
|
||||
int table;
|
||||
xce_match_t* condition;
|
||||
} xce_get_t;
|
||||
|
||||
typedef struct {
|
||||
int event;
|
||||
union {
|
||||
job_pidinfo_t* pidinfo;
|
||||
job_failinfo_t* failinfo;
|
||||
job_failinfo_t* dispatchfail;
|
||||
xce_jobfinish_t* finishinfo;
|
||||
uint64_t sched_start_job;
|
||||
uint64_t sched_exit_job;
|
||||
uint64_t sched_fail_job;
|
||||
xce_job_t* sched_update_job;
|
||||
xce_resval_list_t* sched_update_resvals;
|
||||
uint64_t stopped_job;
|
||||
uint64_t resumed_job;
|
||||
xce_ckptinfo_t* ckptinfo;
|
||||
xce_queue_t* sched_update_queue;
|
||||
xce_task_pidinfo_t* taskinfo;
|
||||
xce_task_failinfo_t* taskfailinfo;
|
||||
xce_task_finish_t* taskfinish;
|
||||
uint64_t pdone_job;
|
||||
} data;
|
||||
} xce_notify_data_t;
|
||||
|
||||
typedef struct {
|
||||
int table;
|
||||
union {
|
||||
xce_resval_list_t* resvals;
|
||||
xce_job_rusages_t* jobrusages;
|
||||
} data;
|
||||
} xce_update_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t seq;
|
||||
uint32_t opcode;
|
||||
int32_t status;
|
||||
int data_which;
|
||||
union {
|
||||
char* debugmsg;
|
||||
uint64_t jobid;
|
||||
xce_data_t* getdata;
|
||||
xce_clusterconf_t* clusterconf;
|
||||
} data;
|
||||
} xce_reply_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t opcode;
|
||||
uint64_t seq;
|
||||
xce_peerinfo_t* from;
|
||||
int body_which;
|
||||
union {
|
||||
xce_reply_t* replymsg;
|
||||
char* hellomsg;
|
||||
xce_joindata_t* joinmsg;
|
||||
xce_configdata_t* configpushmsg;
|
||||
xce_data_t* pushmsg;
|
||||
xce_get_t* getmsg;
|
||||
dataset_t* datamsg;
|
||||
xce_job_dispatch_t* dispatchmsg;
|
||||
xce_job_exec_t* jobstartmsg;
|
||||
xce_notify_data_t* notifymsg;
|
||||
xce_job_submit_t* jobsubmsg;
|
||||
xce_update_data_t* updatemsg;
|
||||
xce_jobctrl_t* jobctrlmsg;
|
||||
xce_queuectrl_t* queuectrlmsg;
|
||||
xce_taskrun_t* runtaskmsg;
|
||||
} body;
|
||||
} xce_request_t;
|
||||
|
||||
#endif
|
||||
94
src/include/utils.h
Normal file
94
src/include/utils.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#if !defined(_UTILS_H_)
|
||||
|
||||
#define _UTILS_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <capnp_c.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "controller.capnp.h"
|
||||
#include "xce/errnox.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
#define xce_use(x) (void)(x)
|
||||
|
||||
#define float_near_zero (0.000001)
|
||||
|
||||
#define float_equal(a, b) (fabs((a) - (b)) < float_near_zero)
|
||||
|
||||
#define STR(x) _STR(x)
|
||||
#define _STR(x) #x
|
||||
|
||||
#define MK_VERSION(ver, commit) ver commit
|
||||
|
||||
#ifndef FREEUP
|
||||
#define FREEUP(p) \
|
||||
if ((p) != NULL) { \
|
||||
free(p); \
|
||||
(p) = NULL; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define N_EL_ARRAY(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#define PTR_STEP(p, delta) \
|
||||
((void*)(((char*)p) + (delta)))
|
||||
|
||||
#define N_EL_ARRAY(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#define PTR_STEP(p, delta) \
|
||||
((void*)(((char*)p) + (delta)))
|
||||
|
||||
/* move the owner ship of pointer from src to dst */
|
||||
#define MOVE_PTR(dst, src) \
|
||||
do { \
|
||||
(dst) = (src); \
|
||||
(src) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define NULLSTR(p) (((p) == NULL) || (strlen(p) == 0))
|
||||
|
||||
#define SET_ERROR(code) \
|
||||
do { \
|
||||
set_error((char*)__FILE__, \
|
||||
(char*)__func__, \
|
||||
__LINE__, \
|
||||
(code)); \
|
||||
} while (0)
|
||||
|
||||
#define PERROR(s) xce_perror(s)
|
||||
|
||||
typedef struct {
|
||||
char* file;
|
||||
char* func;
|
||||
int line;
|
||||
int code;
|
||||
} ectx_t;
|
||||
|
||||
#define TRACE(...)
|
||||
#define WARN(...)
|
||||
|
||||
extern capn_text chars_to_text(const char*);
|
||||
extern int parse_argv(char*, char***);
|
||||
extern void free_argv(char**, int);
|
||||
extern void freeup_kvs(int, xce_kv_t*);
|
||||
extern int mylog_init(char*, char*, char*, int, int);
|
||||
extern void mylog_fini(void);
|
||||
extern int mylog_setlevel(char*);
|
||||
extern void set_error(char*, char*, int, int);
|
||||
extern ectx_t* get_ectx(void);
|
||||
extern int xce_vprintf(const char*, va_list);
|
||||
extern int xce_strerror_r(int, char*, size_t);
|
||||
extern void xce_perror(const char*);
|
||||
extern char* frame_symbol(int);
|
||||
extern int copy_int_list(int**, int*, int);
|
||||
extern int copy_strlist(xce_strlist_t*, xce_strlist_t);
|
||||
extern void free_timewindow_config(xce_timewindow_config_t*);
|
||||
extern xce_timewindow_config_t* dup_timewindow_config(xce_timewindow_config_t*);
|
||||
extern void free_resource_thresholds(xce_res_threshold_t**, int);
|
||||
extern xce_res_threshold_t** dup_resource_thresholds(xce_res_threshold_t**, int);
|
||||
extern void free_resval_with_idx_list(xce_val_with_idx_t***, int);
|
||||
extern void free_strlist(xce_strlist_t*);
|
||||
|
||||
#endif
|
||||
61
src/include/vtaskmgr.h
Normal file
61
src/include/vtaskmgr.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#if !defined(_VTASKMGR_H_)
|
||||
|
||||
#define _VTASKMGR_H_ 1
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "dataq.h"
|
||||
#include "mylock.h"
|
||||
#include "netio.h"
|
||||
#include "request.h"
|
||||
|
||||
typedef int (*vtask_func_t)(void*);
|
||||
|
||||
typedef struct {
|
||||
void* owner;
|
||||
ioctx_t ctx;
|
||||
int vcpu;
|
||||
vtask_func_t entry;
|
||||
} vtask_t;
|
||||
|
||||
#define ITPTR_TO_VTASK(p) \
|
||||
((vtask_t*)(((char*)p) - offsetof(ioctx_t, link) - offsetof(vtask_t, ctx)))
|
||||
|
||||
typedef enum {
|
||||
VCPU_IDLE = 0,
|
||||
VCPU_BUSY,
|
||||
VCPU_ERR
|
||||
} vcpu_state_t;
|
||||
|
||||
typedef struct {
|
||||
int cpuid;
|
||||
vcpu_state_t state;
|
||||
void* owner;
|
||||
cbuf_t wbuf;
|
||||
vtask_t* task;
|
||||
pthread_t vcpu;
|
||||
} vcpu_t;
|
||||
|
||||
typedef struct {
|
||||
int n_vcpus;
|
||||
pthread_t dispatcher;
|
||||
vcpu_t* vcpus;
|
||||
cbuf_t wbuf;
|
||||
cbuf_t wtbuf; /* used to wake up vtaskmgr to check tasks */
|
||||
dataq_t taskq;
|
||||
} vtaskmgr_t;
|
||||
|
||||
extern vtask_t* vtask_alloc();
|
||||
extern int vtask_init(vtask_t*, vtask_func_t, endpoint_t*);
|
||||
extern void vtask_fini(vtask_t*);
|
||||
|
||||
extern int vtask_enq(vtaskmgr_t*, vtask_t*);
|
||||
|
||||
extern int vtaskmgr_init(vtaskmgr_t*, int);
|
||||
extern int vtaskmgr_start(vtaskmgr_t*);
|
||||
extern void vtaskmgr_fini(vtaskmgr_t*);
|
||||
extern void vtaskmgr_wait(vtaskmgr_t *);
|
||||
extern void vtaskmgr_wakeup(vtaskmgr_t *);
|
||||
|
||||
#endif
|
||||
168
src/include/xce/cluster_def.h
Normal file
168
src/include/xce/cluster_def.h
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#ifndef XCE_CLUSTER_DEF_H
|
||||
#define XCE_CLUSTER_DEF_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hook.h"
|
||||
#include "htab.h"
|
||||
#include "kvmgr.h"
|
||||
#include "myconf.h"
|
||||
#include "mylock.h"
|
||||
#include "netio.h"
|
||||
#include "objmgr.h"
|
||||
#include "vtaskmgr.h"
|
||||
#include "xce/types.h"
|
||||
#include "xlist.h"
|
||||
#include "zarray.h"
|
||||
|
||||
#define N_CONTROLLER_MAX (16)
|
||||
|
||||
enum {
|
||||
XCE_CONTROLLER_HOOK_JOB = 0,
|
||||
XCE_CONTROLLER_HOOK_WORKER,
|
||||
XCE_CONTROLLER_HOOK_SCHEDULER,
|
||||
XCE_CONTROLLER_HOOK_CLUSTER,
|
||||
XCE_CONTROLLER_HOOK_RESOURCE,
|
||||
XCE_CONTROLLER_HOOK_CTRL_REQ,
|
||||
XCE_CONTROLLER_HOOK_QUEUE,
|
||||
XCE_CONTROLLER_HOOK_USERGROUP,
|
||||
XCE_CONTROLLER_HOOK_HOSTGROUP,
|
||||
XCE_CONTROLLER_HOOK_MAX /* keep this as the max */
|
||||
};
|
||||
|
||||
enum {
|
||||
HOOK_DETAIL_JOB_NEW = 0,
|
||||
HOOK_DETAIL_JOB_START,
|
||||
HOOK_DETAIL_JOB_EXIT,
|
||||
HOOK_DETAIL_JOB_FAIL,
|
||||
HOOK_DETAIL_JOB_UPDATE,
|
||||
HOOK_DETAIL_JOB_CKPT,
|
||||
HOOK_DETAIL_WORKER_JOIN,
|
||||
HOOK_DETAIL_WORKER_DEAD,
|
||||
HOOK_DETAIL_WORKER_UPDATE,
|
||||
HOOK_DETAIL_SCHEDULER_JOIN,
|
||||
HOOK_DETAIL_SCHEDULER_DEAD,
|
||||
HOOK_DETAIL_CLUSTER_INIT,
|
||||
HOOK_DETAIL_DB_INIT,
|
||||
HOOK_DETAIL_CLUSTER_SHUTDOWN,
|
||||
HOOK_DETAIL_DB_SHUTDOWN,
|
||||
HOOK_DETAIL_RESOURCE_UPDATE,
|
||||
HOOK_DETAIL_RESOURCE_LOC_UPDATE,
|
||||
HOOK_DETAIL_CTRL_REQ_FINISH,
|
||||
HOOK_DETAIL_QUEUE_UPDATE,
|
||||
HOOK_DETAIL_USERGROUP_UPDATE,
|
||||
HOOK_DETAIL_HOSTGROUP_UPDATE
|
||||
};
|
||||
|
||||
#define XCE_NS_CONFIG (0)
|
||||
#define XCE_NS_UGROUP (1)
|
||||
#define XCE_NS_HGROUP (2)
|
||||
#define XCE_NS_MAX (2)
|
||||
|
||||
typedef struct {
|
||||
int role;
|
||||
union {
|
||||
int idx;
|
||||
} u;
|
||||
} ep_private_t;
|
||||
|
||||
typedef struct {
|
||||
endpoint_t* ep;
|
||||
} controller_t;
|
||||
|
||||
typedef struct {
|
||||
} metrics_t;
|
||||
|
||||
typedef struct {
|
||||
xce_queue_t queue;
|
||||
} queue_t;
|
||||
|
||||
typedef struct {
|
||||
xce_job_t job;
|
||||
} job_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
htab_t htab;
|
||||
zarray_t jobs;
|
||||
} jobmgr_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
htab_t htab;
|
||||
int nshared;
|
||||
int nunshared;
|
||||
zarray_t defs;
|
||||
zarray_t sharedinst;
|
||||
} resmgr_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
htab_t htab;
|
||||
zarray_t workers;
|
||||
} workermgr_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
htab_t htab;
|
||||
zarray_t queues;
|
||||
} qmgr_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
endpoint_t* ep;
|
||||
} scheduler_t;
|
||||
|
||||
typedef struct {
|
||||
DBPool* db_pool;
|
||||
DBHandle* db_handle;
|
||||
pthread_t fetch_thread;
|
||||
int64_t fetch_job_pos;
|
||||
int fetch_job_interval;
|
||||
int running;
|
||||
mylock_t db_lock;
|
||||
} db_ctx_t;
|
||||
|
||||
typedef struct {
|
||||
pthread_t thread;
|
||||
int runing;
|
||||
int interval;
|
||||
} ctrlreq_ctx_t;
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
ctrlreq_ctx_t ctrlreq_ctx;
|
||||
} ctrl_req_mgr_t;
|
||||
|
||||
typedef struct {
|
||||
myconf_t* myconf;
|
||||
xce_peerinfo_t* myhost;
|
||||
hooksys_t hooksys;
|
||||
iomgr_t iomgr;
|
||||
objmgr_t objmgr;
|
||||
zarray_t endpoints;
|
||||
endpoint_t ep;
|
||||
zarray_t configs;
|
||||
controller_t controllers[N_CONTROLLER_MAX];
|
||||
int myidx;
|
||||
int master;
|
||||
int ncontrollers;
|
||||
scheduler_t sched;
|
||||
jobmgr_t jobmgr;
|
||||
resmgr_t resmgr;
|
||||
workermgr_t workermgr;
|
||||
qmgr_t qmgr;
|
||||
kvmgr_t configmgr;
|
||||
kvmgr_t ugmgr;
|
||||
kvmgr_t hgmgr;
|
||||
vtaskmgr_t vtaskmgr;
|
||||
cbuf_t wbuf;
|
||||
int running;
|
||||
db_ctx_t dbctx;
|
||||
ctrl_req_mgr_t ctrl_req_mgr;
|
||||
} cluster_t;
|
||||
|
||||
#endif /* XCE_CLUSTER_DEF_H */
|
||||
26
src/include/xce/errnox.h
Normal file
26
src/include/xce/errnox.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#if !defined(__XCE_ERRNOX_H__)
|
||||
|
||||
#define __XCE_ERRNOX_H__ 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define XCE_ERRNO_BASE (10001)
|
||||
|
||||
enum {
|
||||
E_XCE_BAD_JOB = XCE_ERRNO_BASE,
|
||||
E_XCE_BAD_WORKER,
|
||||
E_XCE_DUP_JOB,
|
||||
E_XCE_DUP_WORKER,
|
||||
E_XCE_BAD_OPCODE,
|
||||
E_XCE_BAD_ROLE,
|
||||
E_XCE_BAD_RES,
|
||||
E_XCE_BAD_QUEUE,
|
||||
E_XCE_BAD_GROUP,
|
||||
E_XCE_INTERNAL,
|
||||
E_XCE_MAX
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
619
src/include/xce/types.h
Normal file
619
src/include/xce/types.h
Normal file
|
|
@ -0,0 +1,619 @@
|
|||
#if !defined(_XCE_TYPES_H_)
|
||||
|
||||
#define _XCE_TYPES_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "xlist.h"
|
||||
#include "zarray.h"
|
||||
|
||||
#define XCE_VAL_STRING (0)
|
||||
#define XCE_VAL_NUMERIC (1)
|
||||
#define XCE_VAL_BOOLEAN (2)
|
||||
|
||||
typedef enum {
|
||||
XCE_ORD_INCR = 0,
|
||||
XCE_ORD_DECR,
|
||||
XCE_ORD_NA
|
||||
} xce_order_t;
|
||||
|
||||
typedef struct {
|
||||
int which;
|
||||
union {
|
||||
int32_t ivalue32;
|
||||
uint32_t uvalue32;
|
||||
int64_t ivalue64;
|
||||
uint64_t uvalue64;
|
||||
char* svalue;
|
||||
double fvalue;
|
||||
int bvalue;
|
||||
} u;
|
||||
} xce_val_t;
|
||||
|
||||
typedef struct {
|
||||
int idx;
|
||||
xce_val_t* val;
|
||||
} xce_val_with_idx_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* host;
|
||||
xce_val_t* val;
|
||||
} xce_resval_t;
|
||||
|
||||
typedef struct {
|
||||
int field;
|
||||
xce_val_t value;
|
||||
} xce_kv_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_kv_t* vals;
|
||||
} xce_kv_list_t;
|
||||
|
||||
typedef struct {
|
||||
int day; /* 1 - 7 (Mon to Sun, 0 unspecified) */
|
||||
int hour; /* 0 - 23 */
|
||||
int min; /* 0 - 59 */
|
||||
} xce_timewindow_time_t;
|
||||
|
||||
typedef struct {
|
||||
char* tz;
|
||||
xce_timewindow_time_t* open;
|
||||
xce_timewindow_time_t* close;
|
||||
} xce_timewindow_seg_config_t;
|
||||
|
||||
typedef struct {
|
||||
int nsegs;
|
||||
xce_timewindow_seg_config_t** segs;
|
||||
} xce_timewindow_config_t;
|
||||
|
||||
#define XCE_RESF_BUILTIN (0x01)
|
||||
#define XCE_RESF_DYNAMIC (0x02)
|
||||
#define XCE_RESF_GLOBAL (0x04)
|
||||
#define XCE_RESF_SHARED (0x08)
|
||||
#define XCE_RESF_EXTERNAL (0x10)
|
||||
#define XCE_RESF_RELEASE (0x20)
|
||||
#define XCE_RESF_DEFAULT_HOST (0x40)
|
||||
#define XCE_RESF_CONSUMABLE (0x80)
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
void* data;
|
||||
} xce_list_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
int* data;
|
||||
} xce_intlist_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
char** data;
|
||||
} xce_strlist_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* key;
|
||||
} xce_peerinfo_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* value;
|
||||
} xce_config_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_config_t** configs;
|
||||
} xce_configlist_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
xce_strlist_t members;
|
||||
xce_strlist_t ex_members;
|
||||
} xce_group_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_group_t** groups;
|
||||
} xce_grouplist_t;
|
||||
|
||||
typedef struct {
|
||||
xce_val_t* value;
|
||||
int nhosts;
|
||||
char** hosts;
|
||||
} res_distribution_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* desc;
|
||||
int idx;
|
||||
int valtype;
|
||||
xce_order_t ordtype;
|
||||
int flags;
|
||||
int interval;
|
||||
time_t last_report;
|
||||
int ndistributions;
|
||||
res_distribution_t** distributions;
|
||||
xce_val_t* hbased_defined;
|
||||
} xce_resource_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_resource_t** res;
|
||||
} xce_reslist_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
double sched;
|
||||
double stop;
|
||||
} xce_res_threshold_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* hostmodel;
|
||||
char* hosttype;
|
||||
int mxj;
|
||||
int nresources;
|
||||
xce_config_t** resources;
|
||||
int nthresholds;
|
||||
xce_res_threshold_t** thresholds;
|
||||
xce_timewindow_config_t* dispatchwindow;
|
||||
} xce_hostconfig_t;
|
||||
|
||||
#define XCE_WORKER_UNAVAIL (0x00010000)
|
||||
#define XCE_WORKER_LOCKEDU (0x00020000)
|
||||
#define XCE_WORKER_LOCKEDW (0x00040000)
|
||||
#define XCE_WORKER_BUSY (0x00080000)
|
||||
#define XCE_WORKER_CLOSED (0x00100000)
|
||||
|
||||
#define IS_WORKER_UNAVAIL(status) \
|
||||
(((status) & XCE_WORKER_UNAVAIL) != 0)
|
||||
#define IS_WORKER_LOCKEDU(status) \
|
||||
(((status) & XCE_WORKER_LOCKEDU) != 0)
|
||||
#define IS_WORKER_LOCKEDW(status) \
|
||||
(((status) & XCE_WORKER_LOCKEDW) != 0)
|
||||
#define IS_WORKER_LOCKED(status) \
|
||||
(IS_WORKER_LOCKEDU(status) || IS_WORKER_LOCKEDW(status))
|
||||
#define IS_WORKER_BUSY(status) \
|
||||
(((status) & XCE_WORKER_BUSY) != 0)
|
||||
|
||||
typedef struct {
|
||||
char* hosttype;
|
||||
char* hostmodel;
|
||||
double cpufactor;
|
||||
int maxcpus;
|
||||
double maxmem;
|
||||
double maxswap;
|
||||
double maxtmp;
|
||||
int ndisks;
|
||||
} hostattrs_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
} xce_timerange_t;
|
||||
|
||||
typedef struct {
|
||||
int nsegs;
|
||||
xce_timerange_t* ranges;
|
||||
} xce_timewindow_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
hostattrs_t* attrs;
|
||||
uint32_t status;
|
||||
zarray_t resvals;
|
||||
time_t dead_since;
|
||||
int64_t pending_ctrl;
|
||||
xce_timewindow_config_t* dispatch_window_config;
|
||||
int nthresholds;
|
||||
xce_res_threshold_t** thresholds;
|
||||
/* following two vars used to push resource values to sched */
|
||||
int nresvals_to_sched;
|
||||
xce_val_with_idx_t** resvals_to_sched;
|
||||
} xce_worker_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_worker_t** workers;
|
||||
} xce_workerlist_t;
|
||||
|
||||
typedef struct {
|
||||
char* host;
|
||||
int nranks;
|
||||
} xce_host_launch_t;
|
||||
|
||||
typedef struct {
|
||||
int nhosts;
|
||||
xce_host_launch_t** hosts;
|
||||
} xce_launch_t;
|
||||
|
||||
typedef struct {
|
||||
char* exechome;
|
||||
char* execcwd;
|
||||
char* execuser;
|
||||
char* cmdline;
|
||||
char* exdata;
|
||||
char* launch_type;
|
||||
char* q_pre_exec;
|
||||
char* q_post_exec;
|
||||
char* job_pre_exec;
|
||||
char* job_post_exec;
|
||||
} job_startinfo_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
int npids;
|
||||
unsigned int* pids;
|
||||
int npgids;
|
||||
unsigned int* pgids;
|
||||
char* exdata;
|
||||
} job_pidinfo_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
uint32_t stage;
|
||||
int code;
|
||||
char* detail;
|
||||
} job_failinfo_t;
|
||||
|
||||
typedef struct {
|
||||
char* resname;
|
||||
char* reserve;
|
||||
uint32_t instid;
|
||||
double value;
|
||||
uint64_t from;
|
||||
int64_t duration;
|
||||
} xce_alloc_t;
|
||||
|
||||
typedef struct {
|
||||
char* host;
|
||||
int nallocs;
|
||||
xce_alloc_t** allocs;
|
||||
} xce_host_alloc_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
int nhosts;
|
||||
xce_host_alloc_t** allocs;
|
||||
} xce_job_alloc_t;
|
||||
|
||||
typedef struct {
|
||||
int njobs;
|
||||
xce_job_alloc_t** allocs;
|
||||
} xce_job_dispatch_t;
|
||||
|
||||
typedef struct {
|
||||
char* queue;
|
||||
char* user;
|
||||
char* cmdline;
|
||||
char* resreq;
|
||||
char* exdata;
|
||||
char* pre_exec;
|
||||
char* post_exec;
|
||||
uint32_t mintasks;
|
||||
uint32_t maxtasks;
|
||||
} xce_job_submit_t;
|
||||
|
||||
typedef struct {
|
||||
int exitcode;
|
||||
} job_exitinfo_t;
|
||||
|
||||
#define JOB_STAT_NULL 0x00 /**< NULL. */
|
||||
#define JOB_STAT_PEND 0x01 /**< Job is submitted. */
|
||||
#define JOB_STAT_RUN 0x02 /**< Job is running. */
|
||||
#define JOB_STAT_EXIT 0x04 /**< Job is exit. */
|
||||
#define JOB_STAT_DONE 0x08 /**< Job is done. */
|
||||
#define JOB_STAT_PSUSP 0x10 /**< Job is pending and suspend*/
|
||||
#define JOB_STAT_USUSP 0x20 /**< Job is user suspend*/
|
||||
#define JOB_STAT_SSUSP 0x40 /**< Job is system suspend*/
|
||||
|
||||
#define JOB_STAT_PDONE (0x80) /**< Post job process done successfully */
|
||||
#define JOB_STAT_PERR (0x100) /**< Post job process has error */
|
||||
#define JOB_STAT_WAIT (0x200) /**< Chunk job waiting its turn to exec */
|
||||
#define JOB_STAT_RUNKWN 0x8000 /* Flag : Job status is UNKWN caused by losting contact with remote cluster */
|
||||
#define JOB_STAT_UNKWN 0x10000 /**< The worker on the host on which the \
|
||||
* job is processed has lost contact with controller */
|
||||
#define JOB_STAT_PROV (0x20000) /**< this state shows that the job is dispatched to a standby \
|
||||
* power saved host, and this host is \
|
||||
* being waken up or started up */
|
||||
#define JOB_STAT_ERR (0x40000) /**ERROR */
|
||||
|
||||
#define JOB_EXEC_STAGE_Q_PRE_EXEC (0)
|
||||
#define JOB_EXEC_STAGE_PRE_EXEC (1)
|
||||
#define JOB_EXEC_STAGE_MAIN (2)
|
||||
#define JOB_EXEC_STAGE_POST_EXEC (3)
|
||||
#define JOB_EXEC_STAGE_Q_POST_EXEC (4)
|
||||
|
||||
#define QUEUE_STAT_OPEN 0x00 /**< OPEN. */
|
||||
#define QUEUE_STAT_CLOSED 0x01 /**< The queue is closed */
|
||||
#define QUEUE_STAT_INACT_WINDOW 0x02 /**< The queue inactivated due to dispatch or run windows closed */
|
||||
#define QUEUE_STAT_INACT_ADMIN 0x04 /**< The queue inactivated by admin */
|
||||
#define QUEUE_STAT_NOPERM 0x08 /**< Remote queue rejecting jobs. */
|
||||
#define QUEUE_STAT_DISC 0x10 /**< Remote queue status is disconnected. */
|
||||
#define QUEUE_STAT_FAIRSHARE_DEFAULT 0x20 /**< Fairshare queue with null user share defined*/
|
||||
|
||||
typedef enum {
|
||||
NORMAL = 0,
|
||||
TTY,
|
||||
XJOB,
|
||||
DISPLAY
|
||||
} xce_job_type;
|
||||
|
||||
typedef struct {
|
||||
char* host_name;
|
||||
int num_slots;
|
||||
} xce_job_host_slots_t;
|
||||
|
||||
typedef struct {
|
||||
int num_hosts;
|
||||
xce_job_host_slots_t* host_slots;
|
||||
} xce_job_slots_alloc_t;
|
||||
|
||||
typedef struct {
|
||||
char* host_name;
|
||||
int cpu_time;
|
||||
double mem_usage;
|
||||
} xce_host_runusage_t;
|
||||
|
||||
typedef struct {
|
||||
double max_mem;
|
||||
double avg_mem;
|
||||
double used_mem;
|
||||
int cpu_time;
|
||||
int peak_cpu_time;
|
||||
int peak_cpu_duration;
|
||||
float mem_efficiency;
|
||||
float avg_cpu_efficiency;
|
||||
float peak_cpu_efficiency;
|
||||
int num_hosts;
|
||||
xce_host_runusage_t** host_runusage;
|
||||
} xce_job_runusage_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
char* ckptinfo;
|
||||
} xce_ckptinfo_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
uint64_t array_base_id;
|
||||
int array_idx;
|
||||
char* queue;
|
||||
char* user;
|
||||
int64_t idx;
|
||||
time_t sub_time;
|
||||
time_t queue_time;
|
||||
time_t start_time;
|
||||
time_t finish_time;
|
||||
uint32_t mintasks;
|
||||
uint32_t maxtasks;
|
||||
job_pidinfo_t* pidinfo;
|
||||
job_startinfo_t* start_info;
|
||||
unsigned int state;
|
||||
char* job_name;
|
||||
char* project_name;
|
||||
char* user_group;
|
||||
char* job_description;
|
||||
char* resreq;
|
||||
xce_job_alloc_t* allocs;
|
||||
int run_time;
|
||||
xce_job_runusage_t* run_usage;
|
||||
job_exitinfo_t* exit_info;
|
||||
char* ckptinfo;
|
||||
int64_t pending_ctrl;
|
||||
} xce_job_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_job_t** data;
|
||||
} xce_job_list_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
job_startinfo_t* start_info;
|
||||
xce_launch_t* launchinfo;
|
||||
} xce_job_exec_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
job_pidinfo_t pidinfo;
|
||||
} xce_job_runinfo_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
int exit_code;
|
||||
} xce_jobfinish_t;
|
||||
|
||||
typedef struct {
|
||||
char* queue;
|
||||
uint32_t attrs;
|
||||
uint32_t status;
|
||||
int32_t priority;
|
||||
int32_t accept_interval;
|
||||
int32_t sched_delay;
|
||||
char* resreq;
|
||||
xce_group_t* users;
|
||||
xce_group_t* hosts;
|
||||
int32_t nthresholds;
|
||||
xce_res_threshold_t** thresholds;
|
||||
xce_timewindow_t* runwindow;
|
||||
xce_timewindow_t* dispatchwindow;
|
||||
xce_timewindow_config_t* runwindow_config;
|
||||
xce_timewindow_config_t* dispatchwindow_config;
|
||||
int64_t pending_ctrl;
|
||||
char* pre_exec;
|
||||
char* post_exec;
|
||||
} xce_queue_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
xce_queue_t** queues;
|
||||
} xce_queuelist_t;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
xce_reslist_t reslist;
|
||||
xce_queuelist_t qlist;
|
||||
xce_workerlist_t wlist;
|
||||
xce_grouplist_t uglist;
|
||||
xce_grouplist_t hglist;
|
||||
xce_configlist_t cfglist;
|
||||
} xce_clusterconf_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_NONE = 0,
|
||||
CONTROL_JOB,
|
||||
CONTROL_HOST,
|
||||
CONTROL_QUEUE,
|
||||
CONTROL_CLUSTER,
|
||||
CONTROL_DEBUG
|
||||
} ctrl_target_type_t;
|
||||
|
||||
typedef enum {
|
||||
JOB_DO_NONE = 0,
|
||||
JOB_STOP,
|
||||
JOB_RESUME,
|
||||
JOB_KILL,
|
||||
JOB_MIG,
|
||||
JOB_REQUEUE,
|
||||
JOB_MODIFY,
|
||||
JOB_SWITCH,
|
||||
JOB_CHKPNT,
|
||||
JOB_POST,
|
||||
JOB_READ,
|
||||
JOB_TOP,
|
||||
JOB_BOT
|
||||
} job_ctrl_type_t;
|
||||
|
||||
typedef enum {
|
||||
HOST_DO_NONE = 0,
|
||||
HOST_OPEN,
|
||||
HOST_CLOSE,
|
||||
HOST_TAG,
|
||||
HOST_UNTAG
|
||||
} host_ctrl_type_t;
|
||||
|
||||
typedef enum {
|
||||
QUEUE_DO_NONE = 0,
|
||||
QUEUE_OPEN,
|
||||
QUEUE_CLOSE,
|
||||
QUEUE_INACTIVE,
|
||||
QUEUE_ACTIVE
|
||||
} queue_ctrl_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
int signal;
|
||||
int forcekill;
|
||||
char* method;
|
||||
char* comment;
|
||||
} job_ctrl_content_t;
|
||||
|
||||
typedef struct {
|
||||
char* hostname;
|
||||
char* comment;
|
||||
} host_ctrl_content_t;
|
||||
|
||||
typedef struct {
|
||||
char* queuename;
|
||||
char* comment;
|
||||
} queue_ctrl_content_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t id;
|
||||
int target_type;
|
||||
int action_type;
|
||||
time_t request_time;
|
||||
char* user;
|
||||
void* content;
|
||||
} xce_ctrl_req_t;
|
||||
|
||||
typedef struct {
|
||||
int signo;
|
||||
int force;
|
||||
} xce_signal_t;
|
||||
|
||||
typedef struct {
|
||||
int kill;
|
||||
char* method;
|
||||
} xce_ckpt_options_t;
|
||||
|
||||
typedef struct {
|
||||
int action;
|
||||
uint64_t jobid;
|
||||
union {
|
||||
xce_signal_t* siginfo;
|
||||
xce_ckpt_options_t* ckptoption;
|
||||
} u;
|
||||
} xce_jobctrl_t;
|
||||
|
||||
typedef struct {
|
||||
int action;
|
||||
char* queue;
|
||||
} xce_queuectrl_t;
|
||||
|
||||
typedef struct {
|
||||
int action;
|
||||
char* hostname;
|
||||
} xce_hostctrl_t;
|
||||
|
||||
typedef struct {
|
||||
char* host;
|
||||
char* launch_type; /* MPI ranks or something others */
|
||||
int ntasks;
|
||||
char* exechome;
|
||||
char* execcwd;
|
||||
char* execuser;
|
||||
char* cmdline;
|
||||
char* exdata;
|
||||
} xce_taskhost_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
int nhosts;
|
||||
int clientidx;
|
||||
xce_taskhost_t** taskhosts;
|
||||
} xce_taskrun_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
char* host;
|
||||
int clientidx;
|
||||
int taskidx;
|
||||
int npids;
|
||||
unsigned int* pids;
|
||||
int npgids;
|
||||
unsigned int* pgids;
|
||||
char* exdata;
|
||||
} xce_task_pidinfo_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
char* host;
|
||||
int clientidx;
|
||||
int taskidx; /* taskidx == -1 for fail of all tasks
|
||||
* in the same host of xcecli_runtask()
|
||||
*/
|
||||
int code;
|
||||
char* detail;
|
||||
} xce_task_failinfo_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t jobid;
|
||||
char* host;
|
||||
int taskidx;
|
||||
int clientidx;
|
||||
int exit_code;
|
||||
} xce_task_finish_t;
|
||||
|
||||
typedef struct {
|
||||
char* resname;
|
||||
float value;
|
||||
} xce_rusage_t;
|
||||
|
||||
#endif
|
||||
34
src/include/xceapi.h
Normal file
34
src/include/xceapi.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#if !defined(_XCEAPI_H_)
|
||||
|
||||
#define _XCEAPI_H_ 1
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "xce/types.h"
|
||||
#include "xcectx.h"
|
||||
|
||||
extern int xce_hello(xce_ctx_t*, char*);
|
||||
extern int xce_shutdown(xce_ctx_t*);
|
||||
extern int xce_reslist(xce_ctx_t*, xce_resource_t***);
|
||||
extern int xce_join(xce_ctx_t*, int, hostattrs_t*);
|
||||
extern int xce_workerlist(xce_ctx_t*, xce_worker_t***);
|
||||
extern int xce_jobdispatch(xce_ctx_t*, xce_job_dispatch_t*);
|
||||
extern int xce_jobsubmit(xce_ctx_t*, xce_job_submit_t*,
|
||||
uint64_t*);
|
||||
extern int xce_joblist(xce_ctx_t*, xce_job_t***);
|
||||
extern int xce_clusterconf(xce_ctx_t*, xce_clusterconf_t**);
|
||||
extern int xce_push(xce_ctx_t*, xce_check_fn_t,
|
||||
void*, int, int, int, void**);
|
||||
extern int xce_update_rows(xce_ctx_t*, int, int, xlist_t*);
|
||||
extern int xce_resval(xce_ctx_t*, char*,
|
||||
char*, xce_resval_t***);
|
||||
|
||||
extern int xce_notify(xce_ctx_t*, xce_notify_data_t*);
|
||||
extern int xce_update_resvals(xce_ctx_t*, int, xce_resval_t**);
|
||||
extern int xce_jobctrl(xce_ctx_t*, xce_jobctrl_t*);
|
||||
extern int xce_queuectrl(xce_ctx_t*, xce_queuectrl_t*);
|
||||
extern int xce_runtask(xce_ctx_t*, xce_taskrun_t*);
|
||||
extern int xce_update_jusage(xce_ctx_t*, uint64_t, int,
|
||||
int*, int, int*, int, xce_rusage_t**);
|
||||
|
||||
#endif
|
||||
52
src/include/xcectx.h
Normal file
52
src/include/xcectx.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#if !defined(_XCECTX_H_)
|
||||
|
||||
#define _XCECTX_H_ 1
|
||||
|
||||
#include "netio.h"
|
||||
#include "request.h"
|
||||
#include "vtaskmgr.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
typedef enum {
|
||||
XCE_CTX_INIT = 0,
|
||||
XCE_CTX_RUN,
|
||||
XCE_CTX_DOWN,
|
||||
XCE_CTX_BUSY,
|
||||
XCE_CTX_ERR
|
||||
} xce_ctx_state_t;
|
||||
|
||||
typedef int (*xce_request_handler_t)(xce_request_t*);
|
||||
|
||||
typedef struct {
|
||||
xce_ctx_state_t state;
|
||||
xce_peerinfo_t myinfo;
|
||||
iomgr_t iomgr;
|
||||
vtaskmgr_t vtaskmgr;
|
||||
endpoint_t* ep;
|
||||
xce_request_handler_t handler;
|
||||
cbuf_t wbuf;
|
||||
dataset_t* dataset;
|
||||
|
||||
struct {
|
||||
union {
|
||||
char* debugmsg;
|
||||
dataset_t* get;
|
||||
uint64_t jobid;
|
||||
xce_clusterconf_t* clusterconf;
|
||||
} u;
|
||||
} reply;
|
||||
} xce_ctx_t;
|
||||
|
||||
extern int xce_ctx_init(xce_ctx_t*, char*, char*);
|
||||
extern void xce_ctx_fini(xce_ctx_t*);
|
||||
extern int xce_ctx_set_handler(xce_ctx_t*,
|
||||
xce_request_handler_t);
|
||||
extern int xce_ctx_start(xce_ctx_t*);
|
||||
extern int xce_ctx_stop(xce_ctx_t*);
|
||||
extern int xce_wakeup(xce_ctx_t*, int);
|
||||
extern int xce_try_wakeup(xce_ctx_t*, int);
|
||||
extern int xce_ctx_set_endpoint(xce_ctx_t*, endpoint_t*);
|
||||
extern void xce_block_tasks(xce_ctx_t*);
|
||||
extern void xce_unblock_tasks(xce_ctx_t*);
|
||||
|
||||
#endif
|
||||
21
src/include/xlist.h
Normal file
21
src/include/xlist.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#if !defined(__XLIST_H__)
|
||||
|
||||
#define __XLIST_H__ 1
|
||||
|
||||
typedef int (*xlist_iter_fn_t)(void*, void*);
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
int caps;
|
||||
int delta;
|
||||
void** data;
|
||||
} xlist_t;
|
||||
|
||||
typedef int (*xlist_action_fn_t)(xlist_t*, void*);
|
||||
|
||||
extern int xlist_init(xlist_t*, int);
|
||||
extern int xlist_store(xlist_t*, void*);
|
||||
extern void xlist_clear(xlist_t*);
|
||||
extern int xlist_iter(xlist_t*, xlist_iter_fn_t, void*);
|
||||
extern void xlist_fini(xlist_t*);
|
||||
#endif
|
||||
25
src/include/xstring.h
Normal file
25
src/include/xstring.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#if !defined(__XSTRING_H__)
|
||||
|
||||
#define __XSTRING_H__ 1
|
||||
|
||||
#include "objmgr.h"
|
||||
|
||||
typedef struct {
|
||||
htab_t tab;
|
||||
zarray_t strings;
|
||||
} xstring_typedata_t;
|
||||
|
||||
#define XSTRING_OBJ_TYPE_HTAB(obj) \
|
||||
(((xstring_typedata_t *)obj->type->typedata)->tab)
|
||||
#define XSTRING_OBJ_TYPE_STRINGS(obj) \
|
||||
(((xstring_typedata_t *)obj->type->typedata)->strings)
|
||||
|
||||
#define XSTRING_TYPE_HTAB(type) \
|
||||
(((xstring_typedata_t *)type->typedata)->tab)
|
||||
|
||||
#define XSTRING_TYPE_STRINGS(type) \
|
||||
(((xstring_typedata_t *)type->typedata)->strings)
|
||||
|
||||
extern int register_xstring(objmgr_t*, int,int);
|
||||
|
||||
#endif
|
||||
32
src/include/zarray.h
Normal file
32
src/include/zarray.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#if !defined(_ZARRAY_H_)
|
||||
|
||||
#define _ZARRAY_H_ 1
|
||||
|
||||
#include "mylock.h"
|
||||
#include "xlist.h"
|
||||
|
||||
typedef void (*zarray_item_killer_t)(void*);
|
||||
typedef int (*zarray_iter_fn_t)(void*, void*);
|
||||
|
||||
typedef struct {
|
||||
mylock_t lock;
|
||||
int count;
|
||||
int pos;
|
||||
int caps;
|
||||
int delta;
|
||||
zarray_item_killer_t killer;
|
||||
void** data;
|
||||
} zarray_t;
|
||||
|
||||
extern int zarray_init(zarray_t*, int,
|
||||
zarray_item_killer_t);
|
||||
extern int zarray_store(zarray_t*, void*);
|
||||
extern int zarray_clear(zarray_t*, int);
|
||||
extern int zarray_iter_ex(zarray_t*, xlist_t*, void*);
|
||||
extern int zarray_iter(zarray_t*, zarray_iter_fn_t, void*);
|
||||
extern int zarray_del(zarray_t*, int);
|
||||
extern int zarray_put(zarray_t*, int, void*);
|
||||
extern void* zarray_get(zarray_t*, int);
|
||||
extern void zarray_fini(zarray_t*);
|
||||
|
||||
#endif
|
||||
629
src/lib/client.c
Normal file
629
src/lib/client.c
Normal file
|
|
@ -0,0 +1,629 @@
|
|||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "controller.capnp.h"
|
||||
#include "mylock.h"
|
||||
|
||||
#include "request.h"
|
||||
#include "xce/types.h"
|
||||
#include "xceapi.h"
|
||||
#include "xcectx.h"
|
||||
#include "xlist.h"
|
||||
|
||||
typedef enum {
|
||||
API_CTX_INIT = 0,
|
||||
API_CTX_RUN,
|
||||
API_CTX_DOWN,
|
||||
API_CTX_ERR
|
||||
} api_ctx_state_t;
|
||||
|
||||
typedef struct {
|
||||
xce_client_config_t* conf;
|
||||
endpoint_t ep;
|
||||
xce_ctx_t ctx;
|
||||
} api_ctx_t;
|
||||
|
||||
int xcecli_ctx_init(xcecli_ctx_t* c,
|
||||
xce_client_config_t* cfg)
|
||||
{
|
||||
api_ctx_t* ctx;
|
||||
int rc;
|
||||
|
||||
if ((c == NULL) || (cfg == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cfg->nmasters < 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx = (api_ctx_t*)calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctx->conf = cfg;
|
||||
rc = xce_ctx_init(&(ctx->ctx),
|
||||
ctx->conf->from,
|
||||
ctx->conf->key);
|
||||
if (rc < 0) {
|
||||
free(ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
endpoint_init(&(ctx->ep), AF_INET,
|
||||
SOCK_STREAM, 0, 0);
|
||||
|
||||
xce_ctx_set_endpoint(&(ctx->ctx), &(ctx->ep));
|
||||
|
||||
*c = (void*)ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xcecli_ctx_fini(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xce_ctx_fini(&(ctx->ctx));
|
||||
endpoint_deref(&(ctx->ep));
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int xcecli_set_handler(xcecli_ctx_t c,
|
||||
xce_request_handler_t handler)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if ((c == NULL) || (handler == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_ctx_set_handler(&(ctx->ctx), handler);
|
||||
}
|
||||
|
||||
int xcecli_wakeup(xcecli_ctx_t c,
|
||||
int status)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_wakeup(&(ctx->ctx), status);
|
||||
}
|
||||
|
||||
int xcecli_try_wakeup(xcecli_ctx_t c,
|
||||
int status)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_try_wakeup(&(ctx->ctx), status);
|
||||
}
|
||||
|
||||
int xcecli_start(xcecli_ctx_t c)
|
||||
{
|
||||
int rc;
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = endpoint_connect(&(ctx->ep),
|
||||
ctx->conf->masters[0],
|
||||
ctx->conf->master_ports[0]);
|
||||
if (rc < 0) {
|
||||
endpoint_deref(&(ctx->ep));
|
||||
return rc;
|
||||
}
|
||||
|
||||
return xce_ctx_start(&(ctx->ctx));
|
||||
}
|
||||
|
||||
int xcecli_stop(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
xce_ctx_stop(&(ctx->ctx));
|
||||
endpoint_deref(&(ctx->ep));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
endpoint_t* xcecli_get_my_endpoint(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &(ctx->ep);
|
||||
}
|
||||
|
||||
xce_peerinfo_t* xcecli_get_myinfo(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &(ctx->ctx.myinfo);
|
||||
}
|
||||
|
||||
int xcecli_hello(xcecli_ctx_t c,
|
||||
char* msg)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_hello(&(ctx->ctx), msg);
|
||||
}
|
||||
|
||||
int xcecli_shutdown(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_shutdown(&(ctx->ctx));
|
||||
}
|
||||
|
||||
int xcecli_reslist(xcecli_ctx_t c,
|
||||
xce_resource_t*** res)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_reslist(&(ctx->ctx), res);
|
||||
}
|
||||
|
||||
int xcecli_join(xcecli_ctx_t c,
|
||||
int role,
|
||||
hostattrs_t* attrs)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_join(&(ctx->ctx), role, attrs);
|
||||
}
|
||||
|
||||
int xcecli_workerlist(xcecli_ctx_t c,
|
||||
xce_worker_t*** workers)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_workerlist(&(ctx->ctx), workers);
|
||||
}
|
||||
|
||||
int xcecli_jobdispatch(xcecli_ctx_t c,
|
||||
xce_job_dispatch_t* info)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_jobdispatch(&(ctx->ctx), info);
|
||||
}
|
||||
|
||||
int xcecli_jobsubmit(xcecli_ctx_t c,
|
||||
xce_job_submit_t* submit,
|
||||
uint64_t* jobid)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_jobsubmit(&(ctx->ctx), submit, jobid);
|
||||
}
|
||||
|
||||
int xcecli_joblist(xcecli_ctx_t c,
|
||||
xce_job_t*** jobs)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_joblist(&(ctx->ctx), jobs);
|
||||
}
|
||||
|
||||
int xcecli_clusterconf(xcecli_ctx_t c,
|
||||
xce_clusterconf_t** conf)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_clusterconf(&(ctx->ctx), conf);
|
||||
}
|
||||
|
||||
int xcecli_notify_jobfinish(xcecli_ctx_t c,
|
||||
xce_jobfinish_t* jfinish)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_jobFinishInfo,
|
||||
.data = {
|
||||
.finishinfo = jfinish
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (jfinish == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_update_resvals(xcecli_ctx_t c,
|
||||
int nres,
|
||||
xce_resval_t** vals)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (vals == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xce_update_resvals(&(ctx->ctx), nres, vals);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xcecli_update_jusage(xcecli_ctx_t c,
|
||||
uint64_t jobid,
|
||||
int npids,
|
||||
int* pids,
|
||||
int npgids,
|
||||
int* pgids,
|
||||
int nusage,
|
||||
xce_rusage_t** usages)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (jobid == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xce_update_jusage(&(ctx->ctx), jobid,
|
||||
npids, pids, npgids, pgids,
|
||||
nusage, usages);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xcecli_resval(xcecli_ctx_t c,
|
||||
char* host,
|
||||
char* res,
|
||||
xce_resval_t*** val)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (res == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_resval(&(ctx->ctx), host, res, val);
|
||||
}
|
||||
|
||||
int xcecli_notify(xcecli_ctx_t c,
|
||||
xce_notify_data_t* data)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_notify(&(ctx->ctx), data);
|
||||
}
|
||||
|
||||
int xcecli_notify_jobstart(xcecli_ctx_t c,
|
||||
job_pidinfo_t* pidinfo)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_jobPidInfo,
|
||||
.data = {
|
||||
.pidinfo = pidinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (pidinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_notify_jobfail(xcecli_ctx_t c,
|
||||
job_failinfo_t* failinfo)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_jobFailInfo,
|
||||
.data = {
|
||||
.failinfo = failinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (failinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_jobctrl(xcecli_ctx_t c,
|
||||
xce_jobctrl_t* ctrlinfo)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (ctrlinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xce_jobctrl(&(ctx->ctx), ctrlinfo);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xcecli_notify_jobstop(xcecli_ctx_t c,
|
||||
uint64_t jobid)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_stoppedJob,
|
||||
.data = {
|
||||
.stopped_job = jobid
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (jobid == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_notify_jobresume(xcecli_ctx_t c,
|
||||
uint64_t jobid)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_resumedJob,
|
||||
.data = {
|
||||
.resumed_job = jobid
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (jobid == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_notify_jobchkpt(xcecli_ctx_t c,
|
||||
uint64_t jobid,
|
||||
char* info)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_ckptinfo_t ckptinfo = {
|
||||
.jobid = jobid,
|
||||
.ckptinfo = info
|
||||
};
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_ckptinfo,
|
||||
.data = {
|
||||
.ckptinfo = &ckptinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (jobid == 0) || (info == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_notify_jobpostdone(xcecli_ctx_t c,
|
||||
uint64_t jobid)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_postDoneJob,
|
||||
.data = {
|
||||
.pdone_job = jobid
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (jobid == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_queuectrl(xcecli_ctx_t c,
|
||||
xce_queuectrl_t* ctrlinfo)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (ctrlinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xce_queuectrl(&(ctx->ctx), ctrlinfo);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xcecli_runtask(xcecli_ctx_t c,
|
||||
xce_taskrun_t* info)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (info == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info->clientidx = -1; /* this field will be used by
|
||||
* controller to trace back
|
||||
* client
|
||||
*/
|
||||
rc = xce_runtask(&(ctx->ctx), info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xcecli_notify_taskstart(xcecli_ctx_t c,
|
||||
xce_task_pidinfo_t* pidinfo)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_taskPidInfo,
|
||||
.data = {
|
||||
.taskinfo = pidinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (pidinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_notify_taskfail(xcecli_ctx_t c,
|
||||
xce_task_failinfo_t* failinfo)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_taskFailInfo,
|
||||
.data = {
|
||||
.taskfailinfo = failinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (failinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
int xcecli_notify_taskfinish(xcecli_ctx_t c,
|
||||
xce_task_finish_t* info)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t data = {
|
||||
.event = NotifyData_data_taskFinish,
|
||||
.data = {
|
||||
.taskfinish = info
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((c == NULL) || (info == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xcecli_notify(ctx, &data);
|
||||
}
|
||||
|
||||
void xcecli_block_tasks(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
if (c == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xce_block_tasks(&(ctx->ctx));
|
||||
}
|
||||
|
||||
void xcecli_unblock_tasks(xcecli_ctx_t c)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
||||
if (c == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xce_unblock_tasks(&(ctx->ctx));
|
||||
}
|
||||
119
src/lib/dataq.c
Normal file
119
src/lib/dataq.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "dataq.h"
|
||||
|
||||
int dataq_init(dataq_t* q,
|
||||
data_item_killer_t killer)
|
||||
{
|
||||
q->head = q->tail = NULL;
|
||||
q->killer = killer;
|
||||
mylock_init(&(q->lock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static data_item_t* dataq_deq_head(dataq_t* q)
|
||||
{
|
||||
if (q->head != NULL) {
|
||||
data_item_t* b = NULL;
|
||||
b = q->head;
|
||||
q->head = b->next;
|
||||
b->next = NULL;
|
||||
if (q->head == NULL) {
|
||||
q->tail = NULL;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static data_item_t* dataq_deq_first_match(dataq_t* q,
|
||||
data_item_match_fn_t f)
|
||||
{
|
||||
data_item_t* prev = NULL;
|
||||
data_item_t* curr = q->head;
|
||||
|
||||
while (curr != NULL) {
|
||||
if ((*f)(curr)) { // Found the item to remove
|
||||
if (prev == NULL) {
|
||||
// Removing the head item
|
||||
q->head = curr->next;
|
||||
if (q->head == NULL) {
|
||||
// Queue became empty after removing head
|
||||
q->tail = NULL;
|
||||
}
|
||||
// else: tail remains unchanged (it wasn't the head)
|
||||
} else {
|
||||
// Removing an item after prev (middle or tail)
|
||||
prev->next = curr->next;
|
||||
if (curr == q->tail) { // Check if we are removing the tail
|
||||
// We removed the tail item, prev is the new tail
|
||||
q->tail = prev;
|
||||
}
|
||||
// else: tail remains unchanged (it was further down the list)
|
||||
}
|
||||
curr->next = NULL; // Isolate the removed item
|
||||
return curr; // Return the removed item
|
||||
}
|
||||
// Move to the next item
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data_item_t* dataq_deq(dataq_t* q,
|
||||
data_item_match_fn_t f)
|
||||
{
|
||||
data_item_t* b = NULL;
|
||||
|
||||
mylock_lock(&(q->lock));
|
||||
if (f == NULL) {
|
||||
b = dataq_deq_head(q);
|
||||
} else {
|
||||
b = dataq_deq_first_match(q, f);
|
||||
}
|
||||
|
||||
mylock_unlock(&(q->lock));
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
int dataq_enq(dataq_t* q, data_item_t* b)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
b->next = NULL;
|
||||
|
||||
mylock_lock(&(q->lock));
|
||||
if (q->tail != NULL) {
|
||||
q->tail->next = b;
|
||||
}
|
||||
|
||||
if (q->head == NULL) {
|
||||
q->head = b;
|
||||
}
|
||||
|
||||
q->tail = b;
|
||||
mylock_unlock(&(q->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void dataq_fini(dataq_t* q)
|
||||
{
|
||||
data_item_t* it;
|
||||
while ((it = dataq_deq_head(q)) != NULL) {
|
||||
if (q->killer != NULL) {
|
||||
(q->killer)(it);
|
||||
}
|
||||
// Note: dataq_deq_head already isolates 'it' (it->next = NULL)
|
||||
}
|
||||
|
||||
q->head = q->tail = NULL; // Explicitly set just in case.
|
||||
q->killer = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
136
src/lib/hook.c
Normal file
136
src/lib/hook.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hook.h"
|
||||
#include "utils.h"
|
||||
|
||||
int xce_hook_init(hooksys_t* s,
|
||||
int maxtypes)
|
||||
{
|
||||
int i;
|
||||
if ((s == NULL) || (maxtypes <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s->maxtypes = 0;
|
||||
s->hooks = (xlist_t*)calloc(maxtypes, sizeof(xlist_t));
|
||||
if (s->hooks == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
s->maxtypes = maxtypes;
|
||||
for (i = 0; i < s->maxtypes; i++) {
|
||||
xlist_init(&(s->hooks[i]), 8);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_add_hook(hooksys_t* s,
|
||||
int typ,
|
||||
hook_fn_t fn,
|
||||
void* data)
|
||||
{
|
||||
hook_item_t* it;
|
||||
|
||||
if (s == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fn == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((typ < 0) || (typ >= s->maxtypes)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
it = (hook_item_t*)calloc(1, sizeof(*it));
|
||||
if (it == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
it->fn = fn;
|
||||
it->data = data;
|
||||
|
||||
xlist_store(&(s->hooks[typ]), it);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HOOK_BEFORE_EVENT returns
|
||||
* negative value will cause
|
||||
* fail
|
||||
*/
|
||||
int xce_run_hooks(hooksys_t* s,
|
||||
int type,
|
||||
int situation,
|
||||
int detail,
|
||||
...)
|
||||
{
|
||||
xlist_t* l;
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
if (s == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((type < 0) || (type >= s->maxtypes)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
l = &(s->hooks[type]);
|
||||
|
||||
for (i = 0; i < l->count; i++) {
|
||||
hook_item_t* it = l->data[i];
|
||||
va_list ap;
|
||||
|
||||
if (it == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
va_start(ap, detail);
|
||||
rc = (*(it->fn))(type, situation, detail,
|
||||
it->data, ap);
|
||||
va_end(ap);
|
||||
|
||||
if ((situation == HOOK_BEFORE_EVENT) && (rc < 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int free_hook_item(void *data1,
|
||||
void *data2) {
|
||||
if (data1 == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
free(data1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xce_hook_fini(hooksys_t* s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->hooks == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < s->maxtypes; i++) {
|
||||
xlist_iter(&(s->hooks[i]),
|
||||
(xlist_iter_fn_t)free_hook_item,
|
||||
NULL);
|
||||
xlist_fini(&(s->hooks[i]));
|
||||
}
|
||||
|
||||
FREEUP(s->hooks);
|
||||
}
|
||||
215
src/lib/htab.c
Normal file
215
src/lib/htab.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "htab.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define HASH_KEY_HASH(t, key) \
|
||||
(((t)->fn.hash != NULL) ? ((t)->fn.hash)(key) : (unsigned long)key)
|
||||
|
||||
#define HASH_KEY_CMP(t, k1, k2) \
|
||||
(((t)->fn.cmp != NULL) ? ((t)->fn.cmp)((k1), (k2)) : ((k1) != (k2)))
|
||||
|
||||
#define HASH_KEY_COPY(t, key) \
|
||||
(((t)->fn.copy != NULL) ? ((t)->fn.copy)(key) : (key))
|
||||
|
||||
#define HASH_KEY_FREE(t, key) \
|
||||
do { \
|
||||
if (((t)->fn.free != NULL) && ((key) != NULL)) { \
|
||||
(t)->fn.free(key); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static unsigned int hash_code(const char* key)
|
||||
{
|
||||
unsigned int hc = 5381;
|
||||
int c;
|
||||
|
||||
while ((c = *key++)) {
|
||||
hc = ((hc << 5) + hc) + c;
|
||||
}
|
||||
|
||||
return hc;
|
||||
}
|
||||
|
||||
static unsigned int string_hash(void* data)
|
||||
{
|
||||
return hash_code((const char*)data);
|
||||
}
|
||||
|
||||
static int string_cmp(void* d1,
|
||||
void* d2)
|
||||
{
|
||||
return (int)strcmp((char*)d1, (char*)d2);
|
||||
}
|
||||
|
||||
static void* string_dup(void* data)
|
||||
{
|
||||
return (void*)strdup((char*)data);
|
||||
}
|
||||
|
||||
static void string_free(void* data)
|
||||
{
|
||||
if (data != NULL) {
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
hash_key_fn_t string_hash_key = {
|
||||
.hash = (hash_key_hash_fn_t)string_hash,
|
||||
.cmp = (hash_key_cmp_fn_t)string_cmp,
|
||||
.copy = (hash_key_copy_fn_t)string_dup,
|
||||
.free = (hash_key_free_fn_t)string_free
|
||||
};
|
||||
|
||||
hash_key_fn_t int_hash_key = {
|
||||
.hash = NULL,
|
||||
.cmp = NULL,
|
||||
.copy = NULL,
|
||||
.free = NULL
|
||||
};
|
||||
|
||||
int ht_init(htab_t* t,
|
||||
int nslots,
|
||||
hash_key_fn_t fn)
|
||||
{
|
||||
if ((t == NULL) || (nslots <= 1)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_init(&(t->lock));
|
||||
t->slots = (hent_t**)calloc(nslots, sizeof(hent_t*));
|
||||
if (t->slots == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
t->nslots = nslots;
|
||||
t->fn = fn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ht_fini(htab_t* t)
|
||||
{
|
||||
int i;
|
||||
hent_t* e;
|
||||
|
||||
if (t == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < t->nslots; i++) {
|
||||
while ((e = t->slots[i]) != NULL) {
|
||||
t->slots[i] = e->next;
|
||||
e->next = NULL;
|
||||
HASH_KEY_FREE(t, e->key);
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
|
||||
free(t->slots);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
hent_t* ht_get(htab_t* t,
|
||||
void* key)
|
||||
{
|
||||
unsigned int hc;
|
||||
hent_t* e;
|
||||
|
||||
if (t == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hc = HASH_KEY_HASH(t, key) % (t->nslots);
|
||||
|
||||
mylock_lock(&(t->lock));
|
||||
e = t->slots[hc];
|
||||
|
||||
while (e != NULL) {
|
||||
if (HASH_KEY_CMP(t, e->key, key) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
e = e->next;
|
||||
}
|
||||
mylock_unlock(&(t->lock));
|
||||
return e;
|
||||
}
|
||||
|
||||
hent_t* ht_add(htab_t* t,
|
||||
void* key)
|
||||
{
|
||||
unsigned int hc;
|
||||
hent_t* e;
|
||||
|
||||
if ((t == NULL) || (key == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e = ht_get(t, key);
|
||||
if (e != NULL) {
|
||||
return e;
|
||||
}
|
||||
|
||||
e = (hent_t*)calloc(1, sizeof(*e));
|
||||
if (e == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e->key = HASH_KEY_COPY(t, key);
|
||||
if (e->key == NULL) {
|
||||
free(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e->data = -1;
|
||||
|
||||
hc = HASH_KEY_HASH(t, key) % (t->nslots);
|
||||
mylock_init(&(t->lock));
|
||||
e->next = t->slots[hc];
|
||||
t->slots[hc] = e;
|
||||
mylock_unlock(&(t->lock));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
int ht_del(htab_t* t,
|
||||
void* key)
|
||||
{
|
||||
unsigned int hc;
|
||||
hent_t** e;
|
||||
int deleted = 0;
|
||||
|
||||
if ((t == NULL) || (key == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hc = HASH_KEY_HASH(t, key) % (t->nslots);
|
||||
mylock_init(&(t->lock));
|
||||
e = &(t->slots[hc]);
|
||||
while ((*e) != NULL) {
|
||||
if (HASH_KEY_CMP(t, (*e)->key, key) == 0) {
|
||||
hent_t* e1 = *e;
|
||||
|
||||
*e = e1->next;
|
||||
HASH_KEY_FREE(t, e1->key);
|
||||
free(e1);
|
||||
deleted = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
e = &((*e)->next);
|
||||
}
|
||||
|
||||
mylock_unlock(&(t->lock));
|
||||
|
||||
if (deleted) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
211
src/lib/kvmgr.c
Normal file
211
src/lib/kvmgr.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "htab.h"
|
||||
#include "kvmgr.h"
|
||||
#include "objmgr.h"
|
||||
#include "utils.h"
|
||||
#include "xce/types.h"
|
||||
#include "zarray.h"
|
||||
|
||||
int kvmgr_init(kvmgr_t* mgr,
|
||||
hash_key_fn_t keyfn,
|
||||
int nslots,
|
||||
int delta,
|
||||
zarray_item_killer_t killer)
|
||||
{
|
||||
ht_init(&(mgr->htab), nslots, keyfn);
|
||||
zarray_init(&(mgr->data), delta, killer);
|
||||
mylock_init(&(mgr->lock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvmgr_fini(kvmgr_t* mgr)
|
||||
{
|
||||
ht_fini(&(mgr->htab));
|
||||
zarray_fini(&(mgr->data));
|
||||
mylock_fini(&(mgr->lock));
|
||||
}
|
||||
|
||||
static void* kvmgr_lock_(kvmgr_t* mgr,
|
||||
void* key,
|
||||
int op)
|
||||
{
|
||||
hent_t* e = NULL;
|
||||
int32_t idx;
|
||||
void* ptr;
|
||||
|
||||
e = ht_get(&(mgr->htab), key);
|
||||
if (e == NULL) {
|
||||
SET_ERROR(ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idx = e->data;
|
||||
if (idx < 0) {
|
||||
SET_ERROR(ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = (void*)zarray_get(&(mgr->data), idx);
|
||||
|
||||
return obj_ref(ptr, op);
|
||||
}
|
||||
|
||||
void* kvmgr_lock(kvmgr_t* mgr,
|
||||
void* key,
|
||||
int op)
|
||||
{
|
||||
void* ptr = NULL;
|
||||
|
||||
if (mgr == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
if ((op != OBJREF_NOP) &&
|
||||
(op != OBJREF_READ) &&
|
||||
(op != OBJREF_UPDATE)) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
ptr = kvmgr_lock_(mgr, key, op);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int32_t kvmgr_add_(kvmgr_t* mgr,
|
||||
void* key,
|
||||
void* p)
|
||||
{
|
||||
hent_t* e = NULL;
|
||||
int idx;
|
||||
|
||||
e = ht_get(&(mgr->htab), key);
|
||||
if (e != NULL) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
idx = zarray_store(&(mgr->data), p);
|
||||
if (idx < 0) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
e = ht_add(&(mgr->htab),
|
||||
(void*)key);
|
||||
if (e == NULL) {
|
||||
zarray_del(&(mgr->data), idx);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
e->data = idx;
|
||||
return idx;
|
||||
}
|
||||
|
||||
int32_t kvmgr_add(kvmgr_t* mgr,
|
||||
void* key,
|
||||
void* p)
|
||||
{
|
||||
int32_t idx;
|
||||
|
||||
if ((mgr == NULL) || (p == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
idx = kvmgr_add_(mgr, key, p);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static void kvmgr_del_(kvmgr_t* mgr,
|
||||
void* key)
|
||||
{
|
||||
hent_t* e = NULL;
|
||||
int idx;
|
||||
|
||||
e = ht_get(&(mgr->htab), key);
|
||||
if (e == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
idx = e->data;
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
zarray_del(&(mgr->data), idx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void kvmgr_del(kvmgr_t* mgr,
|
||||
void* key)
|
||||
{
|
||||
if (mgr == NULL) {
|
||||
return;
|
||||
}
|
||||
mylock_lock(&(mgr->lock));
|
||||
kvmgr_del_(mgr, key);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
}
|
||||
|
||||
static int add_config_(xlist_t* l, void* data)
|
||||
{
|
||||
xce_config_t* config;
|
||||
|
||||
if (data == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config = (xce_config_t*)obj_ref(data, OBJREF_READ);
|
||||
return xlist_store(l, config);
|
||||
}
|
||||
|
||||
int kvmgr_publish(kvmgr_t* mgr,
|
||||
xlist_action_fn_t fn,
|
||||
void* arg)
|
||||
{
|
||||
xlist_t l;
|
||||
int rc = 0;
|
||||
int i;
|
||||
|
||||
xlist_init(&l, 128);
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
zarray_iter(&(mgr->data),
|
||||
(zarray_iter_fn_t)add_config_,
|
||||
&l);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
rc = (*fn)(&l, arg);
|
||||
|
||||
for (i = 0; i < l.count; i++) {
|
||||
xce_config_t* config = l.data[i];
|
||||
|
||||
DEREF_OBJ(config);
|
||||
}
|
||||
|
||||
xlist_fini(&l);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int kvmgr_iter(kvmgr_t* mgr,
|
||||
xlist_t* l,
|
||||
void* arg)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
rc = zarray_iter_ex(&(mgr->data), l, arg);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
69
src/lib/meson.build
Normal file
69
src/lib/meson.build
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
capnp = find_program('capnp')
|
||||
|
||||
gen_srcs = custom_target(
|
||||
'controllercapnp.[ch]',
|
||||
output:['controller.capnp.c', 'controller.capnp.h'],
|
||||
input: '../schema/controller.capnp',
|
||||
command: [capnp, 'compile','-o' ,'c:lib', '-I', '../schema','--src-prefix', '../schema', '@INPUT@']
|
||||
)
|
||||
|
||||
libxce_src = [ gen_srcs[0],
|
||||
'client.c',
|
||||
'dataq.c',
|
||||
'hook.c',
|
||||
'htab.c',
|
||||
'kvmgr.c',
|
||||
'mylock.c',
|
||||
'netio.c',
|
||||
'objmgr.c',
|
||||
'request.c',
|
||||
'threshold.c',
|
||||
'utils.c',
|
||||
'vtaskmgr.c',
|
||||
'window.c',
|
||||
'xceapi.c',
|
||||
'xcectx.c',
|
||||
'xlist.c',
|
||||
'xstring.c',
|
||||
'zarray.c'
|
||||
]
|
||||
|
||||
incdir = include_directories('../include')
|
||||
build_inc = include_directories('.')
|
||||
|
||||
capnpc_c_prog = find_program('capnpc-c')
|
||||
|
||||
# debug('capnpc_c_prog %s\n', capnpc_c_prog)
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
c_capnproto_dep = dependency('c-capnproto')
|
||||
zlog_dep = dependency('zlog')
|
||||
unity_dep = dependency('unity')
|
||||
|
||||
libxce_deps = [c_capnproto_dep, zlog_dep, thread_dep]
|
||||
|
||||
libxce = static_library('xce',
|
||||
libxce_src,
|
||||
include_directories: [incdir, build_inc],
|
||||
dependencies: libxce_deps,
|
||||
install: true)
|
||||
|
||||
libxce_dep = declare_dependency(link_with: libxce)
|
||||
|
||||
libxce_test_src = ['testsuite/test.c',
|
||||
'testsuite/test_error.c',
|
||||
'testsuite/test_htab.c',
|
||||
'testsuite/test_htab_int.c',
|
||||
'testsuite/test_utils.c',
|
||||
'testsuite/test_xstring.c',
|
||||
'testsuite/test_zarray.c'
|
||||
]
|
||||
|
||||
libxce_test_deps = [libxce_deps, unity_dep, libxce_dep]
|
||||
libxce_test = executable('xcelib_test',
|
||||
libxce_test_src,
|
||||
include_directories: [incdir, build_inc],
|
||||
dependencies: libxce_test_deps,
|
||||
install: true)
|
||||
|
||||
test('libxce test', libxce_test)
|
||||
212
src/lib/mylock.c
Normal file
212
src/lib/mylock.c
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mylock.h"
|
||||
|
||||
int mylock_init(mylock_t* l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_mutex_init(l, NULL);
|
||||
}
|
||||
|
||||
void mylock_fini(mylock_t* l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(l);
|
||||
}
|
||||
int mylock_try(mylock_t* l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_mutex_trylock(l);
|
||||
}
|
||||
|
||||
int mylock_lock(mylock_t* l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_mutex_lock(l);
|
||||
}
|
||||
|
||||
int mylock_unlock(mylock_t* l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_mutex_unlock(l);
|
||||
}
|
||||
|
||||
int cbuf_init(cbuf_t* b,
|
||||
int cap,
|
||||
int isize)
|
||||
{
|
||||
if ((b == NULL) || (cap <= 0) || (isize <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
b->ncap = cap;
|
||||
b->isize = isize;
|
||||
b->data = (void*)calloc(cap, isize);
|
||||
|
||||
if (b->data == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
b->head = 0;
|
||||
b->len = 0;
|
||||
|
||||
pthread_mutex_init(&(b->mutex), NULL);
|
||||
pthread_cond_init(&(b->condget), NULL);
|
||||
pthread_cond_init(&(b->condput), NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cbuf_fini(cbuf_t* b)
|
||||
{
|
||||
if (b == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b->data != NULL) {
|
||||
free(b->data);
|
||||
b->data = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&(b->mutex));
|
||||
pthread_cond_destroy(&(b->condput));
|
||||
pthread_cond_destroy(&(b->condget));
|
||||
}
|
||||
|
||||
int cbuf_put(cbuf_t* b,
|
||||
void* it)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((b == NULL) || (it == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&(b->mutex));
|
||||
while (b->len == b->ncap) {
|
||||
pthread_cond_wait(&(b->condput),
|
||||
&(b->mutex));
|
||||
}
|
||||
|
||||
i = (b->head + b->len) % b->ncap;
|
||||
|
||||
memcpy((void*)((char*)b->data) + b->isize * i,
|
||||
it, b->isize);
|
||||
|
||||
b->len++;
|
||||
|
||||
pthread_cond_signal(&(b->condget));
|
||||
|
||||
pthread_mutex_unlock(&(b->mutex));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cbuf_tryput(cbuf_t* b,
|
||||
void* it)
|
||||
{
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
if ((b == NULL) || (it == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&(b->mutex));
|
||||
if (b->len < b->ncap) {
|
||||
i = (b->head + b->len) % b->ncap;
|
||||
|
||||
memcpy((void*)((char*)b->data) + b->isize * i,
|
||||
it, b->isize);
|
||||
|
||||
b->len++;
|
||||
|
||||
pthread_cond_signal(&(b->condget));
|
||||
} else {
|
||||
rc = -EAGAIN;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(b->mutex));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cbuf_get(cbuf_t* b,
|
||||
void* it)
|
||||
{
|
||||
if ((b == NULL) || (it == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&(b->mutex));
|
||||
while (b->len == 0) {
|
||||
pthread_cond_wait(&(b->condget),
|
||||
&(b->mutex));
|
||||
}
|
||||
|
||||
memcpy(it, (void*)((char*)b->data) + b->isize * b->head,
|
||||
b->isize);
|
||||
|
||||
b->head = (b->head + 1) % b->ncap;
|
||||
b->len--;
|
||||
|
||||
pthread_cond_signal(&(b->condput));
|
||||
|
||||
pthread_mutex_unlock(&(b->mutex));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_rwlock_init(my_rwlock_t *l) {
|
||||
if ( l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_rwlock_init(l, NULL);
|
||||
}
|
||||
|
||||
void my_rwlock_fini(my_rwlock_t *l) {
|
||||
if (l == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_rwlock_destroy(l);
|
||||
}
|
||||
|
||||
int my_rwlock_unlock(my_rwlock_t *l) {
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_rwlock_unlock(l);
|
||||
}
|
||||
|
||||
int my_rwlock_rlock(my_rwlock_t *l) {
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_rwlock_rdlock(l);
|
||||
}
|
||||
|
||||
int my_rwlock_wlock(my_rwlock_t *l) {
|
||||
if (l==NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return pthread_rwlock_wrlock(l);
|
||||
}
|
||||
687
src/lib/netio.c
Normal file
687
src/lib/netio.c
Normal file
|
|
@ -0,0 +1,687 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dataq.h"
|
||||
#include "netio.h"
|
||||
#include "request.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int iomgr_update_poll(iomgr_t*, endpoint_t*, int);
|
||||
static void endpoint_fini(endpoint_t*);
|
||||
|
||||
static int socket_create(int domain,
|
||||
int type,
|
||||
int port,
|
||||
int backlog)
|
||||
{
|
||||
int sock;
|
||||
int opt = 1;
|
||||
|
||||
if ((domain < 0) || (type < 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sock = socket(domain, type, 0);
|
||||
if (sock < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fcntl(sock, F_SETFD, (fcntl(sock, F_GETFD) | FD_CLOEXEC));
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (port > 0) {
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset((char*)&sin, 0, sizeof(sin));
|
||||
sin.sin_family = domain;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (bind(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
|
||||
int rc;
|
||||
|
||||
SET_ERROR(errno);
|
||||
|
||||
rc = -errno;
|
||||
(void)close(sock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (backlog > 0) {
|
||||
if (listen(sock, backlog) < 0) {
|
||||
int rc;
|
||||
|
||||
SET_ERROR(errno);
|
||||
|
||||
rc = -errno;
|
||||
(void)close(sock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static int socket_connect(int sock,
|
||||
char* host,
|
||||
int port)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
struct hostent* hp;
|
||||
int rc;
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
hp = gethostbyname(host);
|
||||
if (hp == NULL) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
rc = -errno;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
memcpy((char*)&server.sin_addr, (char*)hp->h_addr, (int)hp->h_length);
|
||||
|
||||
server.sin_port = htons(port);
|
||||
|
||||
rc = connect(sock, (struct sockaddr*)&server, sizeof(server));
|
||||
if (rc < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int socket_accept(int sock)
|
||||
{
|
||||
socklen_t len;
|
||||
int s;
|
||||
struct sockaddr_in from;
|
||||
|
||||
len = sizeof(from);
|
||||
s = accept(sock, (struct sockaddr*)&from, &len);
|
||||
if (s < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fcntl(s, F_SETFD, (fcntl(s, F_GETFD) | FD_CLOEXEC));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int netio_write(int fd,
|
||||
char* data,
|
||||
int sz)
|
||||
{
|
||||
int nc = 0;
|
||||
|
||||
while (sz > 0) {
|
||||
int rc;
|
||||
rc = write(fd, data + nc, sz);
|
||||
if (rc < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
sz -= rc;
|
||||
nc += rc;
|
||||
}
|
||||
|
||||
return nc;
|
||||
}
|
||||
|
||||
int netio_read(int fd,
|
||||
char* data,
|
||||
int sz)
|
||||
{
|
||||
int nc = 0;
|
||||
|
||||
while (sz > 0) {
|
||||
int rc;
|
||||
|
||||
rc = read(fd, data + nc, sz);
|
||||
if (rc < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/* network read return 0, it seems remote
|
||||
* size has tear down the connection
|
||||
*/
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
sz -= rc;
|
||||
nc += rc;
|
||||
}
|
||||
|
||||
return nc;
|
||||
}
|
||||
|
||||
int write_packet(int fd,
|
||||
io_packet_t* pkt)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = netio_write(fd, (char*)&(pkt->sz),
|
||||
sizeof(pkt->sz));
|
||||
if (rc < 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
rc = netio_write(fd, pkt->data, pkt->sz);
|
||||
if (rc < 0) {
|
||||
return -errno;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int alloc_packet(io_packet_t* pkt)
|
||||
{
|
||||
if (pkt->sz <= 0) {
|
||||
SET_ERROR(EINVAL);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pkt->data = (char*)malloc(pkt->sz);
|
||||
if (pkt->data == NULL) {
|
||||
SET_ERROR(ENOMEM);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
int read_packet(int fd,
|
||||
io_packet_t* pkt)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = netio_read(fd, (char*)&(pkt->sz),
|
||||
sizeof(pkt->sz));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = alloc_packet(pkt);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = netio_read(fd, pkt->data, pkt->sz);
|
||||
if (rc < 0) {
|
||||
free_packet(pkt);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void free_packet(io_packet_t* pkt)
|
||||
{
|
||||
if (pkt->data != NULL) {
|
||||
free(pkt->data);
|
||||
pkt->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_EPOLL_EVENTS (5)
|
||||
|
||||
static void* io_worker(void* args)
|
||||
{
|
||||
iomgr_t* iomgr = (iomgr_t*)args;
|
||||
|
||||
while (1) {
|
||||
int nfds = -1;
|
||||
int i;
|
||||
struct epoll_event events[MAX_EPOLL_EVENTS];
|
||||
|
||||
nfds = epoll_wait(iomgr->epoll_fd, events,
|
||||
MAX_EPOLL_EVENTS, -1);
|
||||
if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
perror("epoll");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
endpoint_t* p = (endpoint_t*)events[i].data.ptr;
|
||||
|
||||
if (p->handler != NULL) {
|
||||
(p->handler)(&events[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_testcancel();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int endpoint_calc_flags(endpoint_t* ep)
|
||||
{
|
||||
int flags = EPOLLIN;
|
||||
|
||||
if (ep->outq.head != NULL) {
|
||||
flags = flags | EPOLLOUT;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
endpoint_t* endpoint_get()
|
||||
{
|
||||
endpoint_t* ep;
|
||||
|
||||
ep = (endpoint_t*)calloc(1, sizeof(*ep));
|
||||
if (ep == NULL) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return ep;
|
||||
}
|
||||
|
||||
ep->fd = -1;
|
||||
ep->idx = -1;
|
||||
ep->iomgr = NULL;
|
||||
ep->busy = 0;
|
||||
ep->needfree = 1;
|
||||
|
||||
mylock_init(&(ep->lock));
|
||||
|
||||
return endpoint_ref(ep);
|
||||
}
|
||||
|
||||
static void outq_item_killer(data_item_t* it)
|
||||
{
|
||||
if (it != NULL) {
|
||||
ioctx_t* ctx = ITPTR_TO_IOCTX(it);
|
||||
ioctx_deref(ctx, 1);
|
||||
}
|
||||
}
|
||||
int endpoint_init(endpoint_t* ep,
|
||||
int domain,
|
||||
int type,
|
||||
int port,
|
||||
int backlog)
|
||||
{
|
||||
int fd = -1;
|
||||
|
||||
if (ep == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fd = socket_create(domain, type,
|
||||
port, backlog);
|
||||
if (fd < 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ep->flags = 0;
|
||||
ep->fd = fd;
|
||||
ep->owner = NULL;
|
||||
ep->data = NULL;
|
||||
ep->iomgr = NULL;
|
||||
ep->busy = 0;
|
||||
ep->needfree = 0;
|
||||
|
||||
dataq_init(&(ep->outq),
|
||||
outq_item_killer);
|
||||
mylock_init(&(ep->lock));
|
||||
|
||||
endpoint_ref(ep);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int endpoint_connect(endpoint_t* ep,
|
||||
char* host,
|
||||
int port)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
rc = socket_connect(ep->fd, host, port);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ep->flags = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int endpoint_accept(endpoint_t* ep,
|
||||
endpoint_t* ep2)
|
||||
{
|
||||
int sock = -1;
|
||||
|
||||
sock = socket_accept(ep->fd);
|
||||
if (sock < 0) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
ep2->fd = sock;
|
||||
ep2->flags = 0;
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int endpoint_set_handler(endpoint_t* ep,
|
||||
msghandler_t h,
|
||||
void* owner)
|
||||
{
|
||||
if (ep->fd < 0) {
|
||||
SET_ERROR(EINVAL);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
ep->handler = h;
|
||||
ep->owner = owner;
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int endpoint_enq(endpoint_t* ep,
|
||||
data_item_t* it)
|
||||
{
|
||||
int rc = 0;
|
||||
int flags;
|
||||
|
||||
if ((ep == NULL) || (it == NULL)) {
|
||||
SET_ERROR(EINVAL);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
rc = dataq_enq(&(ep->outq), it);
|
||||
|
||||
flags = endpoint_calc_flags(ep);
|
||||
if (flags != ep->flags) {
|
||||
if (ep->iomgr != NULL) {
|
||||
int rc1;
|
||||
|
||||
mylock_lock(&(ep->iomgr->lock));
|
||||
rc1 = iomgr_update_poll(ep->iomgr,
|
||||
ep, flags);
|
||||
mylock_unlock(&(ep->iomgr->lock));
|
||||
|
||||
if (rc1 >= 0) {
|
||||
ep->flags = flags;
|
||||
} else {
|
||||
WARN("rc1=%d < 0", rc1);
|
||||
}
|
||||
}
|
||||
}
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
data_item_t* endpoint_deq(endpoint_t* ep)
|
||||
{
|
||||
data_item_t* it = NULL;
|
||||
int flags;
|
||||
|
||||
if (ep == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
it = dataq_deq(&(ep->outq), NULL);
|
||||
flags = endpoint_calc_flags(ep);
|
||||
if (flags != ep->flags) {
|
||||
if (ep->iomgr != NULL) {
|
||||
int rc;
|
||||
|
||||
mylock_lock(&(ep->iomgr->lock));
|
||||
rc = iomgr_update_poll(ep->iomgr,
|
||||
ep, flags);
|
||||
mylock_unlock(&(ep->iomgr->lock));
|
||||
|
||||
if (rc >= 0) {
|
||||
ep->flags = flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
endpoint_t* endpoint_ref(endpoint_t* ep)
|
||||
{
|
||||
mylock_lock(&(ep->lock));
|
||||
ep->refcount++;
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
return ep;
|
||||
}
|
||||
|
||||
void endpoint_deref(endpoint_t* ep)
|
||||
{
|
||||
uint32_t refcount;
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
ep->refcount--;
|
||||
|
||||
refcount = ep->refcount;
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
if (refcount == 0) {
|
||||
endpoint_fini(ep);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t endpoint_getseq(endpoint_t* ep)
|
||||
{
|
||||
uint64_t seq;
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
seq = ep->seq++;
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
void endpoint_block_tasks(endpoint_t* ep)
|
||||
{
|
||||
TRACE("%s[%ld] block tasks for endpoint %p",
|
||||
__func__, pthread_self(), ep);
|
||||
mylock_lock(&(ep->lock));
|
||||
ep->busy = 1;
|
||||
mylock_unlock(&(ep->lock));
|
||||
}
|
||||
|
||||
void endpoint_unblock_tasks(endpoint_t* ep)
|
||||
{
|
||||
TRACE("%s[%ld] unblock tasks for endpoint %p",
|
||||
__func__, pthread_self(), ep);
|
||||
mylock_lock(&(ep->lock));
|
||||
ep->busy = 0;
|
||||
mylock_unlock(&(ep->lock));
|
||||
}
|
||||
|
||||
int endpoint_is_task_blocked(endpoint_t* ep)
|
||||
{
|
||||
int busy;
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
busy = ep->busy;
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
TRACE("%s[%ld] endpoint %p task %s",
|
||||
__func__, pthread_self(),
|
||||
ep, (busy != 0) ? "blocked" : "not blocked");
|
||||
|
||||
return (busy != 0);
|
||||
}
|
||||
|
||||
static void endpoint_fini(endpoint_t* ep)
|
||||
{
|
||||
int needfree = ep->needfree;
|
||||
|
||||
dataq_fini(&(ep->outq));
|
||||
FREEUP(ep->data);
|
||||
|
||||
if (ep->fd >= 0) {
|
||||
close(ep->fd);
|
||||
}
|
||||
|
||||
ep->flags = 0;
|
||||
ep->handler = NULL;
|
||||
ep->owner = NULL;
|
||||
|
||||
if (needfree) {
|
||||
FREEUP(ep);
|
||||
}
|
||||
}
|
||||
|
||||
int iomgr_init(iomgr_t* iomgr)
|
||||
{
|
||||
mylock_init(&(iomgr->lock));
|
||||
iomgr->epoll_fd = epoll_create1(0);
|
||||
if (iomgr->epoll_fd < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iomgr_update_poll(iomgr_t* iomgr,
|
||||
endpoint_t* ep,
|
||||
int flags)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
|
||||
ev.events = flags;
|
||||
ev.data.ptr = ep;
|
||||
|
||||
return epoll_ctl(iomgr->epoll_fd,
|
||||
EPOLL_CTL_MOD,
|
||||
ep->fd, &ev);
|
||||
}
|
||||
|
||||
int iomgr_monitor(iomgr_t* iomgr,
|
||||
endpoint_t* ep)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
int rc;
|
||||
int flags;
|
||||
|
||||
flags = EPOLLIN;
|
||||
ev.events = flags;
|
||||
ev.data.ptr = ep;
|
||||
|
||||
mylock_lock(&(ep->lock));
|
||||
ep->iomgr = iomgr;
|
||||
mylock_lock(&(iomgr->lock));
|
||||
rc = epoll_ctl(iomgr->epoll_fd, EPOLL_CTL_ADD,
|
||||
ep->fd, &ev);
|
||||
mylock_unlock(&(iomgr->lock));
|
||||
|
||||
if (rc >= 0) {
|
||||
ep->flags = flags;
|
||||
}
|
||||
|
||||
mylock_unlock(&(ep->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int iomgr_unmonitor(iomgr_t* iomgr,
|
||||
endpoint_t* ep)
|
||||
{
|
||||
int rc;
|
||||
|
||||
mylock_lock(&(iomgr->lock));
|
||||
rc = epoll_ctl(iomgr->epoll_fd, EPOLL_CTL_DEL,
|
||||
ep->fd, NULL);
|
||||
if (rc < 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
rc = -errno;
|
||||
}
|
||||
mylock_unlock(&(iomgr->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int iomgr_start(iomgr_t* iomgr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pthread_create(&(iomgr->worker), NULL, &io_worker, iomgr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int iomgr_fini(iomgr_t* iomgr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iomgr_stop(iomgr_t* iomgr)
|
||||
{
|
||||
int rc;
|
||||
void* res;
|
||||
|
||||
if (iomgr->worker == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = pthread_cancel(iomgr->worker);
|
||||
if (rc != 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
rc = pthread_join(iomgr->worker, &res);
|
||||
if (rc != 0) {
|
||||
SET_ERROR(errno);
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (res == PTHREAD_CANCELED) {
|
||||
iomgr->worker = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
322
src/lib/objmgr.c
Normal file
322
src/lib/objmgr.c
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "htab.h"
|
||||
#include "objmgr.h"
|
||||
#include "utils.h"
|
||||
#include "zarray.h"
|
||||
|
||||
static objmgr_t* objmgr_default = NULL;
|
||||
|
||||
static void objtype_killer(objtype_t* typeval)
|
||||
{
|
||||
if (typeval == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeval->fn_type_fini == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
typeval->fn_type_fini(typeval);
|
||||
}
|
||||
|
||||
int objmgr_init(objmgr_t* mgr)
|
||||
{
|
||||
if (mgr == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_init(&(mgr->lock));
|
||||
|
||||
ht_init(&(mgr->names), 32,
|
||||
string_hash_key);
|
||||
zarray_init(&(mgr->types), 32,
|
||||
(zarray_item_killer_t)objtype_killer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void objmgr_fini(objmgr_t* mgr)
|
||||
{
|
||||
if (mgr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
zarray_fini(&(mgr->types));
|
||||
ht_fini(&(mgr->names));
|
||||
|
||||
mylock_fini(&(mgr->lock));
|
||||
}
|
||||
|
||||
static int objmgr_register_internal(objmgr_t* mgr,
|
||||
objtype_t* type)
|
||||
{
|
||||
hent_t* e = NULL;
|
||||
int idx;
|
||||
|
||||
e = ht_get(&(mgr->names), (void*)type->type);
|
||||
if (e != NULL) {
|
||||
return e->data;
|
||||
}
|
||||
|
||||
e = ht_add(&(mgr->names), (void*)type->type);
|
||||
if (e == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
idx = zarray_store(&(mgr->types), type);
|
||||
if (idx < 0) {
|
||||
ht_del(&(mgr->names), (void*)type->type);
|
||||
return idx;
|
||||
}
|
||||
|
||||
e->data = idx;
|
||||
return idx;
|
||||
}
|
||||
|
||||
int obj_init(objmgr_t* mgr,
|
||||
objtype_t* type,
|
||||
int32_t exdata,
|
||||
myobj_t* obj)
|
||||
{
|
||||
obj->type = type;
|
||||
obj->nref = 1;
|
||||
obj->nread = 0;
|
||||
obj->nwrite = 0;
|
||||
obj->exdata = exdata;
|
||||
obj->magic = OBJ_MAGIC;
|
||||
|
||||
my_rwlock_init(&(obj->rwlock));
|
||||
mylock_init(&(obj->lock));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int objmgr_register(objmgr_t* mgr,
|
||||
objtype_t* type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* clang-format off */
|
||||
if ((mgr == NULL) ||
|
||||
(type == NULL) ||
|
||||
(type->type == NULL) ||
|
||||
(type->fn_create == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
mylock_init(&(type->lock));
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
rc = objmgr_register_internal(mgr, type);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void* create_obj_ex(objmgr_t* mgr,
|
||||
int type,
|
||||
va_list ap)
|
||||
{
|
||||
objtype_t* typeval = NULL;
|
||||
void* obj;
|
||||
|
||||
if ((type < 0) || (type >= mgr->types.caps)) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typeval = (objtype_t*)zarray_get(&(mgr->types), type);
|
||||
if (typeval == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = typeval->fn_create(mgr, typeval, ap);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void* create_obj_by_typeid(objmgr_t* mgr,
|
||||
int type,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
void* p = NULL;
|
||||
|
||||
va_start(ap, type);
|
||||
|
||||
p = create_obj_ex(mgr, type, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void* create_obj_by_typename(objmgr_t* mgr,
|
||||
char* type,
|
||||
...)
|
||||
{
|
||||
hent_t* e;
|
||||
va_list ap;
|
||||
void* p = NULL;
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
e = ht_get(&(mgr->names), (void*)type);
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
if (e == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (e->data < 0) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
va_start(ap, type);
|
||||
|
||||
p = create_obj_ex(mgr, e->data, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int typeid_of_name(objmgr_t* mgr,
|
||||
char* type)
|
||||
{
|
||||
hent_t* e;
|
||||
int typeid;
|
||||
|
||||
mylock_lock(&(mgr->lock));
|
||||
e = ht_get(&(mgr->names), (void*)type);
|
||||
if (e == NULL) {
|
||||
typeid = -ENOENT;
|
||||
} else {
|
||||
typeid = e->data;
|
||||
}
|
||||
mylock_unlock(&(mgr->lock));
|
||||
|
||||
return typeid;
|
||||
}
|
||||
void* obj_ref(void* obj, int op)
|
||||
{
|
||||
myobj_t* myobj;
|
||||
|
||||
if (obj == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
myobj = TO_MYOBJ(obj);
|
||||
if (myobj->magic != OBJ_MAGIC) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case OBJREF_READ:
|
||||
my_rwlock_rlock(&(myobj->rwlock));
|
||||
break;
|
||||
case OBJREF_UPDATE:
|
||||
my_rwlock_wlock(&(myobj->rwlock));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mylock_lock(&(myobj->lock));
|
||||
switch (op) {
|
||||
case OBJREF_READ:
|
||||
myobj->nread++;
|
||||
break;
|
||||
case OBJREF_UPDATE:
|
||||
myobj->nwrite++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
myobj->nref++;
|
||||
mylock_unlock(&(myobj->lock));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void obj_deref(void* obj)
|
||||
{
|
||||
myobj_t* myobj;
|
||||
int nc;
|
||||
objtype_t* typeval;
|
||||
int release_rwlock = 0;
|
||||
|
||||
if (obj == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
myobj = TO_MYOBJ(obj);
|
||||
if (myobj->magic != OBJ_MAGIC) {
|
||||
SET_ERROR(EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* the object lock should be held */
|
||||
mylock_lock(&(myobj->lock));
|
||||
myobj->nref--;
|
||||
nc = myobj->nref;
|
||||
if ((myobj->nread > 0) || (myobj->nwrite > 0)) {
|
||||
release_rwlock = 1;
|
||||
if (myobj->nread > 0) {
|
||||
myobj->nread--;
|
||||
} else {
|
||||
myobj->nwrite--;
|
||||
}
|
||||
}
|
||||
mylock_unlock(&(myobj->lock));
|
||||
|
||||
if (release_rwlock) {
|
||||
my_rwlock_unlock(&(myobj->rwlock));
|
||||
}
|
||||
|
||||
if (nc > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
typeval = myobj->type;
|
||||
if (typeval == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeval->fn_fini != NULL) {
|
||||
typeval->fn_fini(obj);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
objmgr_t* objmgr_get_default()
|
||||
{
|
||||
return objmgr_default;
|
||||
}
|
||||
|
||||
int objmgr_set_default(objmgr_t* mgr)
|
||||
{
|
||||
objmgr_default = mgr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
myobj_t *obj_alloc(size_t size) {
|
||||
myobj_t *obj;
|
||||
|
||||
if (size <= 0) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = (myobj_t *)calloc(1, sizeof(*obj) + size);
|
||||
return obj;
|
||||
}
|
||||
931
src/lib/request.c
Normal file
931
src/lib/request.c
Normal file
|
|
@ -0,0 +1,931 @@
|
|||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mylock.h"
|
||||
#include "netio.h"
|
||||
#include "request.h"
|
||||
#include "typemap.h"
|
||||
#include "utils.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
ioctx_t* ioctx_alloc(endpoint_t* ep,
|
||||
xce_peerinfo_t* peer)
|
||||
{
|
||||
ioctx_t* ctx;
|
||||
|
||||
ctx = (ioctx_t*)calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
errno = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->ep = endpoint_ref(ep);
|
||||
ctx->from = peer;
|
||||
ctx->nrefs++;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int ioctx_ref(ioctx_t* ctx)
|
||||
{
|
||||
int old = ctx->nrefs;
|
||||
|
||||
ctx->nrefs++;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static void ioctx_kill(ioctx_t* ctx,
|
||||
int free_ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
endpoint_deref(ctx->ep);
|
||||
|
||||
free_packet(&(ctx->pkt));
|
||||
capn_free(&(ctx->c));
|
||||
if (free_ctx) {
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void ioctx_deref(ioctx_t* ctx,
|
||||
int free_ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->nrefs == 0) {
|
||||
WARN("Something wrong. Have you forgotten to call ioctx_ref()?");
|
||||
return;
|
||||
}
|
||||
ctx->nrefs--;
|
||||
if (ctx->nrefs == 0) {
|
||||
ioctx_kill(ctx, free_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctx_encode(ioctx_t* ctx,
|
||||
xce_request_t* req)
|
||||
{
|
||||
struct capn_segment* cs;
|
||||
Request_ptr rp;
|
||||
int rc;
|
||||
|
||||
capn_init_malloc(&(ctx->c));
|
||||
cs = capn_root(&(ctx->c)).seg;
|
||||
|
||||
encode_Request(cs, &(ctx->rq), req);
|
||||
|
||||
cs = capn_root(&(ctx->c)).seg;
|
||||
rp = new_Request(cs);
|
||||
write_Request(&(ctx->rq), rp);
|
||||
|
||||
capn_setp(capn_root(&(ctx->c)), 0, rp.p);
|
||||
|
||||
ctx->pkt.sz = capn_size(&(ctx->c));
|
||||
rc = alloc_packet(&(ctx->pkt));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
capn_write_mem(&(ctx->c),
|
||||
(uint8_t*)ctx->pkt.data,
|
||||
ctx->pkt.sz, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ioctx_decode(ioctx_t* ctx,
|
||||
xce_request_t* req)
|
||||
{
|
||||
Request_ptr rp;
|
||||
|
||||
capn_init_mem(&(ctx->c), (const uint8_t*)ctx->pkt.data,
|
||||
ctx->pkt.sz, 0);
|
||||
rp.p = capn_getp(capn_root(&(ctx->c)), 0, 1);
|
||||
|
||||
read_Request(&(ctx->rq), rp);
|
||||
|
||||
decode_Request(req, &(ctx->rq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ioctx_flush(ioctx_t* ctx, int fd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = write_packet(fd, &(ctx->pkt));
|
||||
return rc;
|
||||
}
|
||||
|
||||
void init_reply_by_req(xce_reply_t* reply,
|
||||
xce_request_t* req)
|
||||
{
|
||||
reply->seq = req->seq;
|
||||
reply->opcode = req->opcode;
|
||||
}
|
||||
|
||||
int xce_request(ioctx_t* ctx,
|
||||
xce_request_t* req)
|
||||
{
|
||||
int rc;
|
||||
|
||||
req->seq = endpoint_getseq(ctx->ep);
|
||||
req->from = ctx->from;
|
||||
|
||||
rc = ioctx_encode(ctx, req);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
endpoint_enq(ctx->ep, &(ctx->link));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_reply_with_ctx(ioctx_t* ctx,
|
||||
xce_peerinfo_t* from,
|
||||
xce_reply_t* reply)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_reply,
|
||||
.body_which = Request_body_replymsg,
|
||||
};
|
||||
/* clang-format on */
|
||||
int rc;
|
||||
|
||||
TRACE("%s seq %lu opcode %d status %d data which %d",
|
||||
__func__, reply->seq, reply->opcode,
|
||||
reply->status, reply->data_which);
|
||||
|
||||
request.from = from;
|
||||
request.body.replymsg = reply;
|
||||
|
||||
request.seq = endpoint_getseq(ctx->ep);
|
||||
|
||||
rc = ioctx_encode(ctx, &request);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
endpoint_enq(ctx->ep, &(ctx->link));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_reply(endpoint_t* ep,
|
||||
xce_peerinfo_t* from,
|
||||
xce_reply_t* reply)
|
||||
{
|
||||
ioctx_t* ctx;
|
||||
|
||||
ctx = ioctx_alloc(ep, from);
|
||||
if (ctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return xce_reply_with_ctx(ctx, from, reply);
|
||||
}
|
||||
|
||||
int xce_nop_req(ioctx_t* ctx)
|
||||
{
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_nop,
|
||||
.body_which = Request_body_nomsg
|
||||
};
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_hello_req(ioctx_t* ctx,
|
||||
char* msg)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_hello,
|
||||
.body_which = Request_body_hellomsg,
|
||||
.body = {
|
||||
.hellomsg = msg
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((ctx == NULL) || (msg == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_join_req(ioctx_t* ctx,
|
||||
int role,
|
||||
hostattrs_t* attrs)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_joindata_t joinmsg = {
|
||||
.role = role
|
||||
};
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_join,
|
||||
.body_which = Request_body_joinmsg,
|
||||
.body = {
|
||||
.joinmsg = &joinmsg
|
||||
}
|
||||
};
|
||||
|
||||
if ((role != HostRole_client) &&
|
||||
(role != HostRole_worker) &&
|
||||
(role != HostRole_scheduler)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
if (role == HostRole_worker) {
|
||||
if (attrs == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
joinmsg.data_which = JoinData_data_attrs;
|
||||
joinmsg.data.attrs = attrs;
|
||||
}
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_shutdown_req(ioctx_t* ctx)
|
||||
{
|
||||
int rc;
|
||||
dataq_t* outq;
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_shutdown,
|
||||
.body_which = Request_body_nomsg
|
||||
};
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xce_request(ctx, &request);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
outq = &(ctx->ep->outq);
|
||||
|
||||
while (!DATAQ_EMPTY(outq)) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_pushconfig_req(endpoint_t* ep,
|
||||
xce_peerinfo_t* from,
|
||||
xce_configdata_t* config)
|
||||
{
|
||||
int rc = 0;
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_push,
|
||||
.body_which = Request_body_configpushmsg
|
||||
};
|
||||
ioctx_t* ctx = NULL;
|
||||
|
||||
if ((ep == NULL) || (config == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx = ioctx_alloc(ep, from);
|
||||
if (ctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
request.body.configpushmsg = config;
|
||||
rc = xce_request(ctx, &request);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int xce_push_req(endpoint_t* ep,
|
||||
xce_peerinfo_t* from,
|
||||
xce_data_t* data)
|
||||
{
|
||||
int rc = 0;
|
||||
ioctx_t* ctx = NULL;
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_push,
|
||||
.body_which = Request_body_pushmsg
|
||||
};
|
||||
|
||||
if ((ep == NULL) || (from == NULL) || (data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx = ioctx_alloc(ep, from);
|
||||
if (ctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
request.body.pushmsg = data;
|
||||
|
||||
rc = xce_request(ctx, &request);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xce_push_data_req(endpoint_t* ep,
|
||||
xce_peerinfo_t* from,
|
||||
xce_data_t* data,
|
||||
xce_check_fn_t checkf,
|
||||
void* checkarg,
|
||||
int pktlimit)
|
||||
{
|
||||
int nrows = 0;
|
||||
int pos = 0;
|
||||
int rc = 0;
|
||||
xce_data_t data1;
|
||||
int checkstatus = 0;
|
||||
|
||||
if ((ep == NULL) || (from == NULL) || (data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data1.table = data->table;
|
||||
switch (data->table) {
|
||||
case Data_data_schedjobs:
|
||||
nrows = data->data.jobs->n_total;
|
||||
data1.data.jobs = (xce_jobs_data_t*)calloc(1, sizeof(xce_jobs_data_t));
|
||||
if (data1.data.jobs == NULL) {
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
nrows = data->data.workers->n_total;
|
||||
data1.data.workers = (xce_workers_data_t*)calloc(1, sizeof(xce_workers_data_t));
|
||||
if (data1.data.workers == NULL) {
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (pktlimit <= 0) {
|
||||
pktlimit = nrows;
|
||||
}
|
||||
|
||||
do {
|
||||
int nc = nrows - pos;
|
||||
|
||||
if (nc > pktlimit) {
|
||||
nc = pktlimit;
|
||||
}
|
||||
|
||||
if (checkf != NULL) {
|
||||
checkstatus = (*checkf)(checkarg);
|
||||
if (checkstatus < 0) {
|
||||
nc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (data->table) {
|
||||
case Data_data_schedjobs:
|
||||
data1.data.jobs->n_total = data->data.jobs->n_total;
|
||||
data1.data.jobs->pos = pos;
|
||||
data1.data.jobs->count = nc;
|
||||
if (nc == 0) {
|
||||
data1.data.jobs->jobs = NULL;
|
||||
} else {
|
||||
data1.data.jobs->jobs = &(data->data.jobs->jobs[pos]);
|
||||
}
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
data1.data.workers->n_total = data->data.workers->n_total;
|
||||
data1.data.workers->pos = pos;
|
||||
data1.data.workers->count = nc;
|
||||
if (nc == 0) {
|
||||
data1.data.workers->workers = NULL;
|
||||
} else {
|
||||
data1.data.workers->workers = &(data->data.workers->workers[pos]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rc = xce_push_req(ep, from, &data1);
|
||||
|
||||
if (rc < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pos += nc;
|
||||
|
||||
} while ((pos < nrows) && (checkstatus >= 0));
|
||||
|
||||
switch (data->table) {
|
||||
case Data_data_schedjobs:
|
||||
FREEUP(data1.data.jobs);
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
FREEUP(data1.data.workers);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xce_get_req(ioctx_t* ctx,
|
||||
xce_get_t* get)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_get,
|
||||
.body_which = Request_body_getmsg,
|
||||
.body = {
|
||||
.getmsg = get
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_reply_get(endpoint_t* ep,
|
||||
xce_peerinfo_t* from,
|
||||
xce_reply_t* reply,
|
||||
xce_check_fn_t checkf,
|
||||
void* checkarg,
|
||||
int pktlimit)
|
||||
{
|
||||
int rc = 0;
|
||||
int nrows = 0;
|
||||
int pos = 0;
|
||||
/* clang-format off */
|
||||
xce_data_t getdata = {
|
||||
.table = reply->data.getdata->table
|
||||
};
|
||||
xce_reply_t reply1 = {
|
||||
.seq = reply->seq,
|
||||
.opcode = reply->opcode,
|
||||
.status = reply->status,
|
||||
.data_which = reply->data_which,
|
||||
.data = {
|
||||
.getdata = &getdata
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
int checkstatus = 0;
|
||||
xce_data_t* data = reply->data.getdata;
|
||||
|
||||
if ((ep == NULL) || (from == NULL) || (reply == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (getdata.table) {
|
||||
case Data_data_schedjobs:
|
||||
case Data_data_jobs:
|
||||
nrows = data->data.jobs->n_total;
|
||||
getdata.data.jobs = (xce_jobs_data_t*)calloc(1, sizeof(xce_jobs_data_t));
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
case Data_data_workers:
|
||||
nrows = data->data.workers->n_total;
|
||||
getdata.data.workers = (xce_workers_data_t*)calloc(1, sizeof(xce_workers_data_t));
|
||||
break;
|
||||
case Data_data_resources:
|
||||
nrows = data->data.resources->n_total;
|
||||
getdata.data.resources = (xce_resource_data_t*)calloc(1, sizeof(xce_resource_data_t));
|
||||
break;
|
||||
case Data_data_resvals:
|
||||
nrows = data->data.resvals->n_total;
|
||||
getdata.data.resvals = (xce_resval_data_t*)calloc(1, sizeof(xce_resval_data_t));
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
/* FIXME we need to reply no data */
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (pktlimit <= 0) {
|
||||
pktlimit = nrows;
|
||||
}
|
||||
|
||||
do {
|
||||
int nc = nrows - pos;
|
||||
|
||||
if (nc > pktlimit) {
|
||||
nc = pktlimit;
|
||||
}
|
||||
|
||||
if (checkf != NULL) {
|
||||
checkstatus = (*checkf)(checkarg);
|
||||
|
||||
if (checkstatus < 0) {
|
||||
nc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (getdata.table) {
|
||||
case Data_data_schedjobs:
|
||||
case Data_data_jobs:
|
||||
getdata.data.jobs->n_total = data->data.jobs->n_total;
|
||||
getdata.data.jobs->pos = pos;
|
||||
getdata.data.jobs->count = nc;
|
||||
if (nc == 0) {
|
||||
getdata.data.jobs->jobs = NULL;
|
||||
} else {
|
||||
getdata.data.jobs->jobs = &(data->data.jobs->jobs[pos]);
|
||||
}
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
case Data_data_workers:
|
||||
getdata.data.workers->n_total = data->data.workers->n_total;
|
||||
getdata.data.workers->pos = pos;
|
||||
getdata.data.workers->count = nc;
|
||||
if (nc == 0) {
|
||||
getdata.data.workers->workers = NULL;
|
||||
} else {
|
||||
getdata.data.workers->workers = &(data->data.workers->workers[pos]);
|
||||
}
|
||||
break;
|
||||
case Data_data_resources:
|
||||
getdata.data.resources->n_total = data->data.resources->n_total;
|
||||
getdata.data.resources->pos = pos;
|
||||
getdata.data.workers->count = nc;
|
||||
if (nc == 0) {
|
||||
getdata.data.resources->resources = NULL;
|
||||
} else {
|
||||
getdata.data.resources->resources = &(data->data.resources->resources[pos]);
|
||||
}
|
||||
break;
|
||||
case Data_data_resvals:
|
||||
getdata.data.resvals->n_total = data->data.resvals->n_total;
|
||||
getdata.data.resvals->pos = pos;
|
||||
getdata.data.resvals->count = nc;
|
||||
if (nc == 0) {
|
||||
getdata.data.resvals->vals = NULL;
|
||||
} else {
|
||||
getdata.data.resvals->vals = &(data->data.resvals->vals[pos]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* should never goes here */
|
||||
break;
|
||||
}
|
||||
|
||||
rc = xce_reply(ep, from, &reply1);
|
||||
if (rc < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pos += nc;
|
||||
} while ((pos < nrows) && (checkstatus >= 0));
|
||||
|
||||
switch (getdata.table) {
|
||||
case Data_data_schedjobs:
|
||||
case Data_data_jobs:
|
||||
FREEUP(getdata.data.jobs);
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
case Data_data_workers:
|
||||
FREEUP(getdata.data.workers);
|
||||
break;
|
||||
case Data_data_resources:
|
||||
FREEUP(getdata.data.resources);
|
||||
break;
|
||||
case Data_data_resvals:
|
||||
FREEUP(getdata.data.resvals);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int extract_data(dataset_t* dataset,
|
||||
xce_data_t* getdata)
|
||||
{
|
||||
int ntotal;
|
||||
int rc = 0;
|
||||
int pos = 0;
|
||||
int count = 0;
|
||||
|
||||
TRACE("%s ...", __func__);
|
||||
|
||||
switch (getdata->table) {
|
||||
case Data_data_schedjobs:
|
||||
case Data_data_jobs:
|
||||
if (getdata->data.jobs->count <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ntotal = getdata->data.jobs->n_total;
|
||||
pos = getdata->data.jobs->pos;
|
||||
count = getdata->data.jobs->count;
|
||||
|
||||
if (dataset->rows == NULL) {
|
||||
dataset->rows = (xce_job_t**)calloc(ntotal, sizeof(xce_job_t*));
|
||||
dataset->nrows = 0;
|
||||
}
|
||||
|
||||
memcpy((void*)(((char*)dataset->rows) + sizeof(xce_job_t*) * pos),
|
||||
getdata->data.jobs->jobs, count * sizeof(xce_job_t*));
|
||||
memset(getdata->data.jobs->jobs, 0x0, count * sizeof(xce_job_t*));
|
||||
|
||||
break;
|
||||
case Data_data_schedworkers:
|
||||
case Data_data_workers:
|
||||
if (getdata->data.workers->count <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ntotal = getdata->data.workers->n_total;
|
||||
if (dataset->rows == NULL) {
|
||||
dataset->rows = (xce_worker_t**)calloc(ntotal, sizeof(xce_worker_t*));
|
||||
dataset->nrows = 0;
|
||||
}
|
||||
pos = getdata->data.workers->pos;
|
||||
count = getdata->data.workers->count;
|
||||
|
||||
memcpy((void*)(((char*)dataset->rows) + sizeof(xce_worker_t*) * pos),
|
||||
getdata->data.workers->workers, count * sizeof(xce_worker_t*));
|
||||
memset(getdata->data.workers->workers, 0x0, count * sizeof(xce_worker_t*));
|
||||
|
||||
break;
|
||||
case Data_data_resources:
|
||||
if (getdata->data.resources->count <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ntotal = getdata->data.resources->n_total;
|
||||
if (dataset->rows == NULL) {
|
||||
dataset->rows = (xce_resource_t**)calloc(ntotal, sizeof(xce_resource_t*));
|
||||
dataset->nrows = 0;
|
||||
}
|
||||
pos = getdata->data.resources->pos;
|
||||
count = getdata->data.resources->count;
|
||||
|
||||
memcpy((void*)(((char*)dataset->rows) + sizeof(xce_resource_t*) * pos),
|
||||
getdata->data.resources->resources, count * sizeof(xce_resource_t*));
|
||||
|
||||
memset(getdata->data.resources->resources, 0x0, count * sizeof(xce_resource_t*));
|
||||
break;
|
||||
case Data_data_resvals:
|
||||
if (getdata->data.resvals->count <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ntotal = getdata->data.resvals->n_total;
|
||||
if (dataset->rows == NULL) {
|
||||
dataset->rows = (xce_resval_t**)calloc(ntotal, sizeof(xce_resval_t*));
|
||||
dataset->nrows = 0;
|
||||
}
|
||||
|
||||
pos = getdata->data.resvals->pos;
|
||||
count = getdata->data.resvals->count;
|
||||
|
||||
memcpy((void*)(((char*)dataset->rows) + sizeof(xce_resval_t*) * pos),
|
||||
getdata->data.resvals->vals, count * sizeof(xce_resval_t*));
|
||||
|
||||
memset(getdata->data.resvals->vals, 0x0, count * sizeof(xce_resval_t*));
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
dataset->nrows += count;
|
||||
if (dataset->nrows < ntotal) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xce_jobdispatch_req(ioctx_t* ctx,
|
||||
xce_job_dispatch_t* info)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_jobdispatch,
|
||||
.body_which = Request_body_dispatchmsg,
|
||||
.body = {
|
||||
.dispatchmsg = info
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
/* clang-format off */
|
||||
if ((ctx == NULL) ||
|
||||
(info == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_notify_req(ioctx_t* ctx,
|
||||
xce_notify_data_t* data)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_notify,
|
||||
.body_which = Request_body_notifymsg,
|
||||
.body = {
|
||||
.notifymsg = data
|
||||
}
|
||||
};
|
||||
/* clang-forn on */
|
||||
|
||||
if ((ctx == NULL) || (data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_jobsubmit_req(ioctx_t* ctx,
|
||||
xce_job_submit_t* submit)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_jobsub,
|
||||
.body_which = Request_body_jobsubmsg,
|
||||
.body = {
|
||||
.jobsubmsg = submit
|
||||
}
|
||||
};
|
||||
/*clang-format on*/
|
||||
|
||||
/* clang-format off */
|
||||
if ((ctx == NULL) ||
|
||||
(submit == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_startjob_req(ioctx_t* ctx,
|
||||
xce_job_exec_t* execinfo)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_startjob,
|
||||
.body_which = Request_body_jobstartmsg,
|
||||
.body = {
|
||||
.jobstartmsg = execinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_clusterconf_req(ioctx_t* ctx)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_clusterconf,
|
||||
.body_which = Request_body_nomsg
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_update_req(ioctx_t* ctx,
|
||||
xce_update_data_t* data)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_update,
|
||||
.body_which = Request_body_updatemsg,
|
||||
.body = {
|
||||
.updatemsg = data
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((ctx == NULL) || (data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_jobctrl_req(ioctx_t* ctx,
|
||||
xce_jobctrl_t* ctrinfo)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_jobcontrol,
|
||||
.body_which = Request_body_jobctrlmsg,
|
||||
.body = {
|
||||
.jobctrlmsg = ctrinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((ctx == NULL) || (ctrinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctrinfo->jobid == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (ctrinfo->action) {
|
||||
case JobControl_u_siginfo:
|
||||
break;
|
||||
case JobControl_u_ckptoption:
|
||||
if (ctrinfo->u.ckptoption->method == NULL) {
|
||||
ctrinfo->u.ckptoption->method = "default";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_queuectrl_req(ioctx_t* ctx,
|
||||
xce_queuectrl_t* ctrlinfo)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_queuecontrol,
|
||||
.body_which = Request_body_queuectrlmsg,
|
||||
.body = {
|
||||
.queuectrlmsg = ctrlinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((ctx == NULL) || (ctrlinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ctrlinfo->queue == NULL) || (strlen(ctrlinfo->queue) == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctrlinfo->action == QUEUE_DO_NONE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ctrlinfo->action < 0) || (ctrlinfo->action > QUEUE_ACTIVE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
|
||||
int xce_runtask_req(ioctx_t* ctx,
|
||||
xce_taskrun_t* runinfo)
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_request_t request = {
|
||||
.opcode = OPCode_runtasks,
|
||||
.body_which = Request_body_runtaskmsg,
|
||||
.body = {
|
||||
.runtaskmsg = runinfo
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if ((ctx == NULL) || (runinfo == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (runinfo->nhosts <= 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return xce_request(ctx, &request);
|
||||
}
|
||||
35
src/lib/testsuite/test.c
Normal file
35
src/lib/testsuite/test.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
extern void test_xstrings(void);
|
||||
extern void test_zarray(void);
|
||||
extern void test_ht_string(void);
|
||||
extern void test_ht_int(void);
|
||||
extern void test_error(void);
|
||||
extern void test_utils(void);
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
test_ht_string();
|
||||
test_ht_int();
|
||||
test_zarray();
|
||||
test_xstrings();
|
||||
test_error();
|
||||
test_utils();
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
44
src/lib/testsuite/test_error.c
Normal file
44
src/lib/testsuite/test_error.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "xce/errnox.h"
|
||||
#include "unity.h"
|
||||
#include "utils.h"
|
||||
|
||||
static void test_error_setget(void) {
|
||||
int myerrno =1;
|
||||
ectx_t *e;
|
||||
|
||||
SET_ERROR(myerrno);
|
||||
e = get_ectx();
|
||||
|
||||
TEST_ASSERT_TRUE(e != NULL);
|
||||
TEST_ASSERT_TRUE(errno == myerrno);
|
||||
TEST_ASSERT_TRUE(e->file != NULL);
|
||||
TEST_ASSERT_TRUE(e->func != NULL);
|
||||
TEST_ASSERT_TRUE(strcmp(e->file, __FILE__) == 0);
|
||||
TEST_ASSERT_TRUE(strcmp(e->func, __func__) == 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void test_strerror_r(void) {
|
||||
char errmsg1[256];
|
||||
char errmsg2[256];
|
||||
int errors[] ={ENOENT, EINVAL, E_XCE_BAD_JOB, E_XCE_BAD_WORKER, 0};
|
||||
int i;
|
||||
|
||||
for(i = 0; errors[i] != 0; i ++) {
|
||||
strerror_r(errors[i], errmsg1, sizeof(errmsg1));
|
||||
xce_strerror_r(errors[i], errmsg2, sizeof(errmsg2));
|
||||
TEST_ASSERT_TRUE(strcmp(errmsg1, errmsg2) == 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void test_error(void) {
|
||||
printf("\n>> error test\n\n");
|
||||
|
||||
RUN_TEST(test_error_setget);
|
||||
#if 0
|
||||
RUN_TEST(test_strerror_r);
|
||||
#endif
|
||||
}
|
||||
50
src/lib/testsuite/test_htab.c
Normal file
50
src/lib/testsuite/test_htab.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "htab.h"
|
||||
|
||||
static htab_t htab;
|
||||
static char *s = "Hello,world";
|
||||
|
||||
static void test_ht_add_string(void) {
|
||||
hent_t *e = NULL;
|
||||
|
||||
e = ht_add(&(htab), (void *)s);
|
||||
TEST_ASSERT_NOT_NULL(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_ht_get_string(void) {
|
||||
hent_t *e = NULL;
|
||||
|
||||
e = ht_get(&htab, (void *)s);
|
||||
TEST_ASSERT_NOT_NULL(e);
|
||||
|
||||
TEST_ASSERT_TRUE(0 == strcmp(e->key, s));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_ht_del_string(void) {
|
||||
hent_t *e = NULL;
|
||||
|
||||
ht_del(&htab, (void *)s);
|
||||
|
||||
e = ht_get(&htab, (void *)s);
|
||||
TEST_ASSERT_TRUE( e == NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void test_ht_string(void) {
|
||||
printf("\n>> htab test string\n\n");
|
||||
|
||||
ht_init(&htab, 13, string_hash_key);
|
||||
|
||||
RUN_TEST(test_ht_add_string);
|
||||
RUN_TEST(test_ht_get_string);
|
||||
RUN_TEST(test_ht_del_string);
|
||||
}
|
||||
52
src/lib/testsuite/test_htab_int.c
Normal file
52
src/lib/testsuite/test_htab_int.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "htab.h"
|
||||
|
||||
static htab_t htab;
|
||||
|
||||
uint64_t key = (uint64_t)0xfabcde6666666666;
|
||||
|
||||
static void test_ht_add_string(void) {
|
||||
hent_t *e = NULL;
|
||||
|
||||
e = ht_add(&(htab), (void *)key);
|
||||
TEST_ASSERT_NOT_NULL(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_ht_get_string(void) {
|
||||
hent_t *e = NULL;
|
||||
|
||||
e = ht_get(&htab, (void *)key);
|
||||
TEST_ASSERT_NOT_NULL(e);
|
||||
|
||||
TEST_ASSERT_TRUE((uint64_t)e->key == (uint64_t)key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_ht_del_string(void) {
|
||||
hent_t *e = NULL;
|
||||
|
||||
ht_del(&htab, (void *)key);
|
||||
|
||||
e = ht_get(&htab, (void *)key);
|
||||
TEST_ASSERT_TRUE( e == NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void test_ht_int(void) {
|
||||
printf("\n>> htab test int\n\n");
|
||||
|
||||
ht_init(&htab, 13, int_hash_key);
|
||||
|
||||
RUN_TEST(test_ht_add_string);
|
||||
RUN_TEST(test_ht_get_string);
|
||||
RUN_TEST(test_ht_del_string);
|
||||
}
|
||||
105
src/lib/testsuite/test_utils.c
Normal file
105
src/lib/testsuite/test_utils.c
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "utils.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
static void test_timewindow_config_dup()
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_timewindow_config_t win1 = {
|
||||
.nsegs = 2,
|
||||
.segs = (xce_timewindow_seg_config_t*[]) {
|
||||
&(xce_timewindow_seg_config_t) {
|
||||
.tz = "GMT-8",
|
||||
.open = &(xce_timewindow_time_t) {
|
||||
.day = 0,
|
||||
.hour = 9,
|
||||
.min = 0 },
|
||||
.close = &(xce_timewindow_time_t) {
|
||||
.day = 0,
|
||||
.hour = 17,
|
||||
.min = 59 } },
|
||||
&(xce_timewindow_seg_config_t) {
|
||||
.tz = "GMT-8",
|
||||
.open = &(xce_timewindow_time_t) {
|
||||
.day = 5,
|
||||
.hour = 21,
|
||||
.min = 0 },
|
||||
.close = &(xce_timewindow_time_t) {
|
||||
.day = 7,
|
||||
.hour = 20,
|
||||
.min = 59 } } }
|
||||
};
|
||||
/* clang-format on */
|
||||
xce_timewindow_config_t* win2 = NULL;
|
||||
|
||||
win2 = dup_timewindow_config(&win1);
|
||||
|
||||
TEST_ASSERT_TRUE(win2 != NULL);
|
||||
TEST_ASSERT_TRUE(win2->nsegs == 2);
|
||||
TEST_ASSERT_TRUE((strcmp(win2->segs[0]->tz, "GMT-8") == 0));
|
||||
TEST_ASSERT_TRUE(win2->segs[0]->open->day == 0);
|
||||
TEST_ASSERT_TRUE(win2->segs[0]->open->hour == 9);
|
||||
TEST_ASSERT_TRUE(win2->segs[0]->open->min == 0);
|
||||
TEST_ASSERT_TRUE(win2->segs[0]->close->day == 0);
|
||||
TEST_ASSERT_TRUE(win2->segs[0]->close->hour == 17);
|
||||
TEST_ASSERT_TRUE(win2->segs[0]->close->min == 59);
|
||||
|
||||
TEST_ASSERT_TRUE((strcmp(win2->segs[1]->tz, "GMT-8") == 0));
|
||||
TEST_ASSERT_TRUE(win2->segs[1]->open->day == 5);
|
||||
TEST_ASSERT_TRUE(win2->segs[1]->open->hour == 21);
|
||||
TEST_ASSERT_TRUE(win2->segs[1]->open->min == 0);
|
||||
TEST_ASSERT_TRUE(win2->segs[1]->close->day == 7);
|
||||
TEST_ASSERT_TRUE(win2->segs[1]->close->hour == 20);
|
||||
TEST_ASSERT_TRUE(win2->segs[1]->close->min == 59);
|
||||
|
||||
free_timewindow_config(win2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void test_dup_threshold()
|
||||
{
|
||||
/* clang-format off */
|
||||
xce_res_threshold_t* threshold[2] = {
|
||||
&(xce_res_threshold_t) {
|
||||
.name = "r15s",
|
||||
.sched = 1.0,
|
||||
.stop = 5.0 },
|
||||
&(xce_res_threshold_t) {
|
||||
.name = "r1m",
|
||||
.sched = 0.9,
|
||||
.stop = 4.5 }
|
||||
};
|
||||
/* clang-format on */
|
||||
xce_res_threshold_t** threshold2 = NULL;
|
||||
|
||||
threshold2 = dup_resource_thresholds(threshold, 2);
|
||||
|
||||
TEST_ASSERT_TRUE(threshold2 != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(strcmp(threshold[0]->name, threshold2[0]->name) == 0);
|
||||
TEST_ASSERT_TRUE(strcmp(threshold[1]->name, threshold2[1]->name) == 0);
|
||||
TEST_ASSERT_TRUE(float_equal(threshold[0]->sched,
|
||||
threshold2[0]->sched));
|
||||
TEST_ASSERT_TRUE(float_equal(threshold[0]->stop,
|
||||
threshold2[0]->stop));
|
||||
TEST_ASSERT_TRUE(float_equal(threshold[1]->sched,
|
||||
threshold2[1]->sched));
|
||||
TEST_ASSERT_TRUE(float_equal(threshold[1]->stop,
|
||||
threshold2[1]->stop));
|
||||
|
||||
free_resource_thresholds(threshold2, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
void test_utils(void)
|
||||
{
|
||||
printf("\n>> utils test\n\n");
|
||||
|
||||
RUN_TEST(test_timewindow_config_dup);
|
||||
RUN_TEST(test_dup_threshold);
|
||||
}
|
||||
128
src/lib/testsuite/test_xstring.c
Normal file
128
src/lib/testsuite/test_xstring.c
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "objmgr.h"
|
||||
#include "unity.h"
|
||||
#include "xstring.h"
|
||||
|
||||
void test_xstring_create(void)
|
||||
{
|
||||
objmgr_t mgr;
|
||||
char* s1 = "Hello,world";
|
||||
char* s2 = NULL;
|
||||
int rc = 0;
|
||||
myobj_t* obj;
|
||||
|
||||
objmgr_init(&mgr);
|
||||
register_xstring(&mgr,4,4);
|
||||
TEST_ASSERT_EQUAL(1, mgr.types.count);
|
||||
|
||||
s2 = create_obj_by_typename(&mgr, "xstring", s1);
|
||||
TEST_ASSERT_NOT_NULL(s2);
|
||||
obj = TO_MYOBJ(s2);
|
||||
TEST_ASSERT_EQUAL(1, XSTRING_OBJ_TYPE_STRINGS(obj).count);
|
||||
|
||||
rc = strcmp(s1, s2);
|
||||
TEST_ASSERT_EQUAL(0, rc);
|
||||
|
||||
objmgr_fini(&mgr);
|
||||
}
|
||||
|
||||
void test_xstring_ref(void)
|
||||
{
|
||||
objmgr_t mgr;
|
||||
char* s1 = NULL;
|
||||
char* s2 = NULL;
|
||||
myobj_t* obj;
|
||||
|
||||
objmgr_init(&mgr);
|
||||
register_xstring(&mgr,4,4);
|
||||
TEST_ASSERT_EQUAL(1, mgr.types.count);
|
||||
|
||||
s1 = create_obj_by_typename(&mgr, "xstring",
|
||||
"Hello,world");
|
||||
TEST_ASSERT_NOT_NULL(s1);
|
||||
|
||||
obj = TO_MYOBJ(s1);
|
||||
TEST_ASSERT_EQUAL(1, XSTRING_OBJ_TYPE_STRINGS(obj).count);
|
||||
|
||||
s2 = (char*)obj_ref(s1, OBJREF_READ);
|
||||
TEST_ASSERT_EQUAL(s1, s2);
|
||||
|
||||
TEST_ASSERT_EQUAL(2, obj->nref);
|
||||
objmgr_fini(&mgr);
|
||||
}
|
||||
|
||||
void test_xstring_deref(void)
|
||||
{
|
||||
objmgr_t mgr;
|
||||
char* s1 = "Hello,world";
|
||||
char* s2 = NULL;
|
||||
int rc = 0;
|
||||
myobj_t* obj;
|
||||
|
||||
objmgr_init(&mgr);
|
||||
register_xstring(&mgr,4,4);
|
||||
TEST_ASSERT_EQUAL(1, mgr.types.count);
|
||||
|
||||
s2 = create_obj_by_typename(&mgr, "xstring", s1);
|
||||
TEST_ASSERT_NOT_NULL(s2);
|
||||
|
||||
rc = strcmp(s1, s2);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, rc);
|
||||
if (rc == 0) {
|
||||
objtype_t *typeval;
|
||||
|
||||
obj = TO_MYOBJ(s2);
|
||||
typeval = obj->type;
|
||||
|
||||
obj_deref(s2);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, XSTRING_TYPE_STRINGS(typeval).count);
|
||||
}
|
||||
|
||||
objmgr_fini(&mgr);
|
||||
}
|
||||
|
||||
void test_xstring_share(void)
|
||||
{
|
||||
objmgr_t mgr;
|
||||
char* s1 = "Hello,world";
|
||||
char* s2 = NULL;
|
||||
char* s3 = NULL;
|
||||
int rc = 0;
|
||||
|
||||
objmgr_init(&mgr);
|
||||
register_xstring(&mgr,4,4);
|
||||
TEST_ASSERT_EQUAL(1, mgr.types.count);
|
||||
|
||||
s2 = create_obj_by_typename(&mgr, "xstring", s1);
|
||||
TEST_ASSERT_NOT_NULL(s2);
|
||||
|
||||
rc = strcmp(s1, s2);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, rc);
|
||||
s3 = create_obj_by_typename(&mgr, "xstring", s1);
|
||||
TEST_ASSERT_EQUAL(s2, s3);
|
||||
if (1) {
|
||||
myobj_t* obj;
|
||||
|
||||
obj = TO_MYOBJ(s3);
|
||||
TEST_ASSERT_EQUAL(2, obj->nref);
|
||||
}
|
||||
|
||||
objmgr_fini(&mgr);
|
||||
}
|
||||
|
||||
void test_xstrings(void)
|
||||
{
|
||||
printf("\n>> xstring test\n\n");
|
||||
RUN_TEST(test_xstring_create);
|
||||
RUN_TEST(test_xstring_ref);
|
||||
RUN_TEST(test_xstring_deref);
|
||||
RUN_TEST(test_xstring_share);
|
||||
|
||||
return;
|
||||
}
|
||||
102
src/lib/testsuite/test_zarray.c
Normal file
102
src/lib/testsuite/test_zarray.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "zarray.h"
|
||||
|
||||
static void test_zarray_create(void) {
|
||||
zarray_t array;
|
||||
|
||||
zarray_init(&array, 8, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(0,array.count);
|
||||
TEST_ASSERT_NULL(array.data);
|
||||
}
|
||||
|
||||
static void test_zarray_store(void) {
|
||||
zarray_t array;
|
||||
int idx;
|
||||
char *s1 = "hello";
|
||||
char *s2 = NULL;
|
||||
|
||||
zarray_init(&array, 8, NULL);
|
||||
idx = zarray_store(&array, (void *)s1);
|
||||
TEST_ASSERT_TRUE(idx >= 0);
|
||||
s2 = (char *)zarray_get(&array, idx);
|
||||
TEST_ASSERT_NOT_NULL(s2);
|
||||
TEST_ASSERT_EQUAL(0, strcmp(s1, s2));
|
||||
|
||||
zarray_fini(&(array));
|
||||
}
|
||||
|
||||
static void test_zarray_del(void) {
|
||||
zarray_t array;
|
||||
int idx;
|
||||
char *s1 = "hello";
|
||||
|
||||
zarray_init(&array, 8, NULL);
|
||||
idx = zarray_store(&array, (void *)s1);
|
||||
TEST_ASSERT_TRUE(idx >= 0);
|
||||
TEST_ASSERT_TRUE(array.count == 1);
|
||||
zarray_del(&array, idx);
|
||||
TEST_ASSERT_TRUE(zarray_get(&array, idx) == NULL);
|
||||
TEST_ASSERT_TRUE(array.count == 0);
|
||||
|
||||
zarray_fini(&array);
|
||||
}
|
||||
|
||||
static void test_zarray_put(void) {
|
||||
zarray_t array;
|
||||
int idx;
|
||||
char *s1 = "hello";
|
||||
char *s2 = "test";
|
||||
|
||||
zarray_init(&array, 8, NULL);
|
||||
idx = zarray_store(&array, (void *)s1);
|
||||
TEST_ASSERT_TRUE(idx >= 0);
|
||||
TEST_ASSERT_TRUE(array.count == 1);
|
||||
TEST_ASSERT_TRUE(zarray_get(&array, idx) != NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(strcmp((char *)zarray_get(&array, idx), s1) == 0);
|
||||
|
||||
zarray_put(&array, idx, (void *)s2);
|
||||
TEST_ASSERT_TRUE(zarray_get(&array, idx) != NULL);
|
||||
TEST_ASSERT_TRUE(strcmp((char *)zarray_get(&array, idx), s2) == 0);
|
||||
|
||||
zarray_fini(&array);
|
||||
}
|
||||
|
||||
static int sum_(void *arg1, void *arg2) {
|
||||
int *pv = (int *)arg1;
|
||||
int x = (int)((long)arg2);
|
||||
|
||||
(*pv) += x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_zarray_iter(void) {
|
||||
zarray_t array;
|
||||
int i;
|
||||
int val = 0;
|
||||
|
||||
zarray_init(&array, 10, NULL);
|
||||
for(i = 0; i < 10; i ++) {
|
||||
zarray_store(&array, (void *)(long)i);
|
||||
}
|
||||
|
||||
zarray_iter(&array, (zarray_iter_fn_t)sum_, &val);
|
||||
|
||||
TEST_ASSERT_TRUE(val == 45);
|
||||
|
||||
zarray_fini(&(array));
|
||||
}
|
||||
void test_zarray(void) {
|
||||
printf("\n>> zarray test\n\n");
|
||||
|
||||
RUN_TEST(test_zarray_create);
|
||||
RUN_TEST(test_zarray_store);
|
||||
RUN_TEST(test_zarray_del);
|
||||
RUN_TEST(test_zarray_put);
|
||||
RUN_TEST(test_zarray_iter);
|
||||
}
|
||||
81
src/lib/threshold.c
Normal file
81
src/lib/threshold.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "xce/errnox.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
static void kill_thresholds(xce_res_threshold_t** thresholds,
|
||||
int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (thresholds == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
for (i = 0; i < count; i++) {
|
||||
xce_res_threshold_t* it = thresholds[i];
|
||||
|
||||
if (it == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FREEUP(it->name);
|
||||
FREEUP(it);
|
||||
}
|
||||
}
|
||||
|
||||
FREEUP(thresholds);
|
||||
}
|
||||
|
||||
void free_resource_thresholds(xce_res_threshold_t** thresholds,
|
||||
int count)
|
||||
{
|
||||
kill_thresholds(thresholds, count);
|
||||
}
|
||||
|
||||
xce_res_threshold_t** dup_resource_thresholds(xce_res_threshold_t** src,
|
||||
int count)
|
||||
{
|
||||
xce_res_threshold_t** thresholds = NULL;
|
||||
int i;
|
||||
|
||||
if ((src == NULL) || (count <= 0)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thresholds = (xce_res_threshold_t**)calloc(count, sizeof(xce_res_threshold_t*));
|
||||
if (thresholds == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
xce_res_threshold_t* it = (xce_res_threshold_t*)calloc(1, sizeof(*it));
|
||||
|
||||
if (it == NULL) {
|
||||
kill_thresholds(thresholds, i);
|
||||
errno = ENOMEM;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thresholds[i] = it;
|
||||
|
||||
it->name = strdup(src[i]->name);
|
||||
if (it->name == NULL) {
|
||||
kill_thresholds(thresholds, i + 1);
|
||||
errno = ENOMEM;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
it->sched = src[i]->sched;
|
||||
it->stop = src[i]->stop;
|
||||
}
|
||||
|
||||
return thresholds;
|
||||
}
|
||||
371
src/lib/utils.c
Executable file
371
src/lib/utils.c
Executable file
|
|
@ -0,0 +1,371 @@
|
|||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(__GLIBC__) && (__GLIBC__ == 2 && __GLIBC_MINOR__ < 28)
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include <threads.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "controller.capnp.h"
|
||||
#include <capnp_c.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "xce/errnox.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
static capn_text chars_to_text_internal(const char* chars)
|
||||
{
|
||||
capn_text data = {
|
||||
.len = strlen(chars),
|
||||
.str = chars,
|
||||
.seg = NULL,
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
capn_text chars_to_text(const char* chars)
|
||||
{
|
||||
if (chars == NULL) {
|
||||
chars = "";
|
||||
}
|
||||
|
||||
return chars_to_text_internal(chars);
|
||||
}
|
||||
|
||||
#define ARGV_INCR_DELTA (16)
|
||||
|
||||
#define FILL_ARGV(rc, argv, argc, maxargc, delta, s) \
|
||||
do { \
|
||||
(rc) = 0; \
|
||||
char* s1; \
|
||||
if (((argc) >= (maxargc))) { \
|
||||
char** p; \
|
||||
int nc, i; \
|
||||
nc = (maxargc) + (delta); \
|
||||
p = (char**)realloc((argv), nc * sizeof(char*)); \
|
||||
if (p == NULL) { \
|
||||
(rc) = -ENOMEM; \
|
||||
break; \
|
||||
} \
|
||||
for (i = (maxargc); i < nc; i++) { \
|
||||
p[i] = NULL; \
|
||||
} \
|
||||
(argv) = p; \
|
||||
(maxargc) = nc; \
|
||||
} \
|
||||
s1 = strdup(s); \
|
||||
if (s1 == NULL) { \
|
||||
(rc) = -ENOMEM; \
|
||||
break; \
|
||||
} \
|
||||
(argv)[argc] = s1; \
|
||||
(argc)++; \
|
||||
} while (0)
|
||||
|
||||
#define FREE_ARGV(argv, argc) \
|
||||
do { \
|
||||
int i; \
|
||||
if ((argv) == NULL) { \
|
||||
break; \
|
||||
} \
|
||||
for (i = 0; i < (argc); i++) { \
|
||||
if ((argv)[i] != NULL) { \
|
||||
free((argv)[i]); \
|
||||
(argv)[i] = NULL; \
|
||||
} \
|
||||
} \
|
||||
free(argv); \
|
||||
} while (0)
|
||||
|
||||
int parse_argv(char* input,
|
||||
char*** argv)
|
||||
{
|
||||
int max_argc = 0;
|
||||
char* arg = NULL;
|
||||
int i = 0;
|
||||
int in_quotes = 0;
|
||||
char quote_char = 0;
|
||||
int argc = 0;
|
||||
int rc = 0;
|
||||
|
||||
rc = 0;
|
||||
arg = (char*)malloc(strlen(input) + 1);
|
||||
if (arg == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*argv = NULL;
|
||||
while (*input) {
|
||||
if (in_quotes) {
|
||||
if (*input == quote_char) {
|
||||
in_quotes = 0;
|
||||
} else if (*input == '\\') {
|
||||
input++;
|
||||
if (*input) {
|
||||
arg[i++] = *input;
|
||||
}
|
||||
} else {
|
||||
arg[i++] = *input;
|
||||
}
|
||||
} else {
|
||||
if (isspace(*input)) {
|
||||
if (i > 0) {
|
||||
arg[i] = '\0';
|
||||
FILL_ARGV(rc, *argv, argc, max_argc,
|
||||
ARGV_INCR_DELTA, arg);
|
||||
if (rc < 0) {
|
||||
FREE_ARGV(*argv, argc);
|
||||
free(arg);
|
||||
return rc;
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
} else if ((*input == '"') || (*input == '\'')) {
|
||||
in_quotes = 1;
|
||||
quote_char = *input;
|
||||
} else if (*input == '\\') {
|
||||
input++;
|
||||
if (*input) {
|
||||
arg[i++] = *input;
|
||||
}
|
||||
} else {
|
||||
arg[i++] = *input;
|
||||
}
|
||||
}
|
||||
input++;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
arg[i] = '\0';
|
||||
FILL_ARGV(rc, *argv, argc, max_argc,
|
||||
ARGV_INCR_DELTA, arg);
|
||||
if (rc < 0) {
|
||||
FREE_ARGV(*argv, argc);
|
||||
free(arg);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
free(arg);
|
||||
return argc;
|
||||
}
|
||||
|
||||
void free_argv(char** argv, int argc)
|
||||
{
|
||||
FREE_ARGV(argv, argc);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void freeup_kvs(int count,
|
||||
xce_kv_t* vals)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vals == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (vals[i].value.which != XceFieldValue_data_svalue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FREEUP(vals[i].value.u.svalue);
|
||||
}
|
||||
|
||||
FREEUP(vals);
|
||||
}
|
||||
#endif
|
||||
|
||||
char* frame_symbol(int k)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
void* array[k + 1];
|
||||
size_t size = backtrace(array, k + 1);
|
||||
char** symbols = backtrace_symbols(array, size);
|
||||
char* s = NULL;
|
||||
|
||||
if (symbols == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = strdup(symbols[MIN(size - 1, k)]);
|
||||
free(symbols);
|
||||
return s;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xce_vprintf(const char* fmt, va_list ap)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* FIXME: */
|
||||
return rc;
|
||||
}
|
||||
|
||||
static _Thread_local ectx_t ectx;
|
||||
|
||||
void set_error(char* file,
|
||||
char* func,
|
||||
int line,
|
||||
int code)
|
||||
{
|
||||
ectx.file = file;
|
||||
ectx.func = func;
|
||||
ectx.line = line;
|
||||
ectx.code = code;
|
||||
errno = code;
|
||||
}
|
||||
|
||||
ectx_t* get_ectx()
|
||||
{
|
||||
return &ectx;
|
||||
}
|
||||
|
||||
static char* xce_err_str[] = {
|
||||
"invalid job",
|
||||
"invalid worker",
|
||||
"duplicated jobs",
|
||||
"duplicated workers",
|
||||
"bad opcode",
|
||||
"unknown role",
|
||||
"unknown resource",
|
||||
"unknown queue",
|
||||
"unknown group",
|
||||
"internal error",
|
||||
NULL
|
||||
};
|
||||
|
||||
int xce_strerror_r(int errnum,
|
||||
char* buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
if (errnum < XCE_ERRNO_BASE) {
|
||||
return strerror_r(errnum, buf, bufsize);
|
||||
}
|
||||
|
||||
if (errnum >= E_XCE_MAX) {
|
||||
strncpy(buf, "unknown error", bufsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(buf, xce_err_str[errnum - XCE_ERRNO_BASE],
|
||||
bufsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_int_list(int** dst,
|
||||
int* src,
|
||||
int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
FREEUP(*dst);
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*dst = (int*)calloc(count, sizeof(int));
|
||||
if ((*dst) == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
(*dst)[i] = (int)src[i];
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int copy_strlist(xce_strlist_t* dst,
|
||||
xce_strlist_t src)
|
||||
{
|
||||
if (!dst) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < dst->count; i++) {
|
||||
FREEUP(dst->data[i]);
|
||||
}
|
||||
FREEUP(dst->data);
|
||||
dst->count = src.count;
|
||||
if (dst->count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dst->data = (char**)calloc(dst->count, sizeof(char*));
|
||||
if (dst->data == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (int i = 0; i < src.count; i++) {
|
||||
if (src.data[i]) {
|
||||
dst->data[i] = strndup(src.data[i], strlen(src.data[i]));
|
||||
if (dst->data[i] == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void free_resval_with_idx_list(xce_val_with_idx_t*** vals,
|
||||
int count)
|
||||
{
|
||||
xce_val_with_idx_t** resvals = *vals;
|
||||
int i;
|
||||
|
||||
if (resvals == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
xce_val_with_idx_t* val = resvals[i];
|
||||
|
||||
if (val == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val->val->which == Value_u_svalue) {
|
||||
FREEUP(val->val->u.svalue);
|
||||
}
|
||||
|
||||
FREEUP(val->val);
|
||||
FREEUP(val);
|
||||
}
|
||||
|
||||
FREEUP(resvals);
|
||||
*vals = NULL;
|
||||
}
|
||||
|
||||
void free_strlist(xce_strlist_t *l) {
|
||||
int i;
|
||||
|
||||
if ( l == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((l->count <= 0) || (l->data == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < l->count; i ++) {
|
||||
FREEUP(l->data[i]);
|
||||
}
|
||||
|
||||
FREEUP(l->data);
|
||||
}
|
||||
362
src/lib/vtaskmgr.c
Normal file
362
src/lib/vtaskmgr.c
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mylock.h"
|
||||
#include "netio.h"
|
||||
#include "utils.h"
|
||||
#include "vtaskmgr.h"
|
||||
|
||||
static int bind_vtask(vtask_t*, vcpu_t*);
|
||||
|
||||
vtask_t* vtask_alloc()
|
||||
{
|
||||
vtask_t* task;
|
||||
|
||||
task = calloc(1, sizeof(*task));
|
||||
return task;
|
||||
}
|
||||
|
||||
int vtask_init(vtask_t* task,
|
||||
vtask_func_t entry,
|
||||
endpoint_t* ep)
|
||||
{
|
||||
int rc;
|
||||
|
||||
task->entry = entry;
|
||||
task->vcpu = -1;
|
||||
task->ctx.ep = endpoint_ref(ep);
|
||||
|
||||
rc = read_packet(ep->fd, &(task->ctx.pkt));
|
||||
if (rc < 0) {
|
||||
free_packet(&(task->ctx.pkt));
|
||||
endpoint_deref(task->ctx.ep);
|
||||
task->ctx.ep = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void vtask_fini(vtask_t* task)
|
||||
{
|
||||
if (task == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ioctx_deref(&(task->ctx), 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void vcpu_idle(vcpu_t* vcpu)
|
||||
{
|
||||
vtaskmgr_t* vtaskmgr = (vtaskmgr_t*)vcpu->owner;
|
||||
|
||||
vcpu->task = NULL;
|
||||
cbuf_put(&(vtaskmgr->wbuf),
|
||||
(void*)&(vcpu->cpuid));
|
||||
cbuf_get(&(vcpu->wbuf),
|
||||
(void*)&(vcpu->task));
|
||||
return;
|
||||
}
|
||||
|
||||
void run_task(vtask_t* task)
|
||||
{
|
||||
vtaskmgr_t *vtaskmgr;
|
||||
|
||||
if (task->entry != NULL) {
|
||||
(task->entry)(task);
|
||||
}
|
||||
|
||||
endpoint_unblock_tasks(task->ctx.ep);
|
||||
vtaskmgr = (vtaskmgr_t *)task->owner;
|
||||
if (vtaskmgr != NULL) {
|
||||
/* wake up dispatcher */
|
||||
vtaskmgr_wakeup(vtaskmgr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void* vcpu_entry(void* arg)
|
||||
{
|
||||
vcpu_t* my = (vcpu_t*)arg;
|
||||
|
||||
while (1) {
|
||||
if (my->task != NULL) {
|
||||
vtask_t* t = my->task;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
|
||||
my->task = NULL;
|
||||
run_task(t);
|
||||
vtask_fini(t);
|
||||
free(t);
|
||||
my->state = VCPU_IDLE;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
} else {
|
||||
vcpu_idle(my);
|
||||
}
|
||||
pthread_testcancel();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vcpu_init(vcpu_t* vcpu,
|
||||
int cpuid,
|
||||
void* owner)
|
||||
{
|
||||
vcpu->state = VCPU_IDLE;
|
||||
vcpu->vcpu = 0;
|
||||
vcpu->cpuid = cpuid;
|
||||
vcpu->owner = owner;
|
||||
vcpu->task = NULL;
|
||||
cbuf_init(&(vcpu->wbuf), 1, sizeof(void*));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vcpu_start(vcpu_t* vcpu)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pthread_create(&(vcpu->vcpu), NULL,
|
||||
&vcpu_entry, vcpu);
|
||||
if (rc != 0) {
|
||||
vcpu->state = VCPU_ERR;
|
||||
return -errno;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void vcpu_fini(vcpu_t* vcpu)
|
||||
{
|
||||
int rc;
|
||||
void* res;
|
||||
|
||||
if (vcpu->vcpu) {
|
||||
/* wakeup vcpu first */
|
||||
bind_vtask(NULL, vcpu);
|
||||
rc = pthread_cancel(vcpu->vcpu);
|
||||
if (rc != 0) {
|
||||
cbuf_fini(&(vcpu->wbuf));
|
||||
return;
|
||||
}
|
||||
|
||||
rc = pthread_join(vcpu->vcpu, &res);
|
||||
if (rc != 0) {
|
||||
cbuf_fini(&(vcpu->wbuf));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cbuf_fini(&(vcpu->wbuf));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void taskq_item_killer(data_item_t* it)
|
||||
{
|
||||
if (it != NULL) {
|
||||
vtask_t* task = ITPTR_TO_VTASK(it);
|
||||
vtask_fini(task);
|
||||
free(task);
|
||||
}
|
||||
}
|
||||
|
||||
int vtaskmgr_init(vtaskmgr_t* vtaskmgr,
|
||||
int nvcpus)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((vtaskmgr == NULL) || (nvcpus <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vtaskmgr->dispatcher = 0;
|
||||
vtaskmgr->n_vcpus = nvcpus;
|
||||
vtaskmgr->vcpus = (vcpu_t*)calloc(nvcpus,
|
||||
sizeof(vcpu_t));
|
||||
if (vtaskmgr->vcpus == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (i = 0; i < nvcpus; i++) {
|
||||
vcpu_init(&(vtaskmgr->vcpus[i]),
|
||||
i, vtaskmgr);
|
||||
}
|
||||
|
||||
cbuf_init(&(vtaskmgr->wbuf),
|
||||
nvcpus, sizeof(int));
|
||||
cbuf_init(&(vtaskmgr->wtbuf),
|
||||
1, sizeof(int));
|
||||
|
||||
dataq_init(&(vtaskmgr->taskq),
|
||||
taskq_item_killer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static vcpu_t* pick_idle_vcpu(vtaskmgr_t* vtaskmgr)
|
||||
{
|
||||
int i;
|
||||
|
||||
cbuf_get(&(vtaskmgr->wbuf), &i);
|
||||
if ((i < 0) || (i >= vtaskmgr->n_vcpus)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("%s pick idle cpu #%d",
|
||||
__func__, i);
|
||||
|
||||
return &(vtaskmgr->vcpus[i]);
|
||||
}
|
||||
|
||||
static int vtask_eligible(data_item_t* data)
|
||||
{
|
||||
vtask_t* task = ITPTR_TO_VTASK(data);
|
||||
int eligible = 0;
|
||||
|
||||
if (task->ctx.ep == NULL) {
|
||||
WARN("no endpoint for task 0x%p", task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
eligible = !(endpoint_is_task_blocked(task->ctx.ep));
|
||||
TRACE("%s vtask %p is %s",
|
||||
__func__, task,
|
||||
eligible?"eligible":"not eligible");
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
static vtask_t* pick_eligible_task(vtaskmgr_t* vtaskmgr)
|
||||
{
|
||||
data_item_t* data;
|
||||
vtask_t* task = NULL;
|
||||
|
||||
data = dataq_deq(&(vtaskmgr->taskq), vtask_eligible);
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
task = ITPTR_TO_VTASK(data);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
static int bind_vtask(vtask_t* task,
|
||||
vcpu_t* vcpu)
|
||||
{
|
||||
TRACE("binding task %p to cpu#%d\n",
|
||||
task, vcpu->cpuid);
|
||||
|
||||
if (task != NULL) {
|
||||
endpoint_block_tasks(task->ctx.ep);
|
||||
|
||||
task->vcpu = vcpu->cpuid;
|
||||
}
|
||||
|
||||
cbuf_put(&(vcpu->wbuf), (void*)&task);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* vdispatcher_entry(void* arg)
|
||||
{
|
||||
vtaskmgr_t* vtaskmgr = (vtaskmgr_t*)arg;
|
||||
vcpu_t* vcpu = NULL;
|
||||
vtask_t* task = NULL;
|
||||
|
||||
while (1) {
|
||||
pthread_testcancel();
|
||||
if (vcpu == NULL) {
|
||||
vcpu = pick_idle_vcpu(vtaskmgr);
|
||||
if (vcpu == NULL) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
task = pick_eligible_task(vtaskmgr);
|
||||
if (task != NULL) {
|
||||
bind_vtask(task, vcpu);
|
||||
vcpu = NULL;
|
||||
task = NULL;
|
||||
}
|
||||
else {
|
||||
vtaskmgr_wait(vtaskmgr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vtaskmgr_start(vtaskmgr_t* vtaskmgr)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
rc = pthread_create(&(vtaskmgr->dispatcher), NULL,
|
||||
&vdispatcher_entry, vtaskmgr);
|
||||
if (rc != 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < vtaskmgr->n_vcpus; i++) {
|
||||
vcpu_start(&(vtaskmgr->vcpus[i]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vtaskmgr_wait(vtaskmgr_t *vtaskmgr) {
|
||||
int dummy = 0;
|
||||
|
||||
cbuf_get(&(vtaskmgr->wtbuf), &dummy);
|
||||
}
|
||||
|
||||
void vtaskmgr_wakeup(vtaskmgr_t *vtaskmgr) {
|
||||
int dummy = 0;
|
||||
|
||||
cbuf_tryput(&(vtaskmgr->wtbuf), &dummy);
|
||||
}
|
||||
|
||||
void vtaskmgr_fini(vtaskmgr_t* vtaskmgr)
|
||||
{
|
||||
int i;
|
||||
void* res;
|
||||
|
||||
if (vtaskmgr->dispatcher != 0) {
|
||||
pthread_cancel(vtaskmgr->dispatcher);
|
||||
pthread_join(vtaskmgr->dispatcher, &res);
|
||||
}
|
||||
|
||||
if (vtaskmgr->vcpus != NULL) {
|
||||
for (i = 0; i < vtaskmgr->n_vcpus; i++) {
|
||||
vcpu_fini(&(vtaskmgr->vcpus[i]));
|
||||
}
|
||||
free(vtaskmgr->vcpus);
|
||||
}
|
||||
|
||||
dataq_fini(&(vtaskmgr->taskq));
|
||||
cbuf_fini(&(vtaskmgr->wtbuf));
|
||||
cbuf_fini(&(vtaskmgr->wbuf));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int vtask_enq(vtaskmgr_t* vtaskmgr,
|
||||
vtask_t* task)
|
||||
{
|
||||
int rc = 0;
|
||||
ioctx_ref(&(task->ctx));
|
||||
|
||||
rc = dataq_enq(&(vtaskmgr->taskq),
|
||||
&(task->ctx.link));
|
||||
if (rc >= 0) {
|
||||
/* wake up task dispatcher */
|
||||
task->owner = vtaskmgr;
|
||||
vtaskmgr_wakeup(vtaskmgr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
126
src/lib/window.c
Normal file
126
src/lib/window.c
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "xce/errnox.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
static void kill_timewindow_time(xce_timewindow_time_t* t)
|
||||
{
|
||||
FREEUP(t);
|
||||
}
|
||||
|
||||
static void kill_timewindow_seg_config(xce_timewindow_seg_config_t* s)
|
||||
{
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
FREEUP(s->tz);
|
||||
|
||||
kill_timewindow_time(s->open);
|
||||
kill_timewindow_time(s->close);
|
||||
FREEUP(s);
|
||||
}
|
||||
|
||||
static void kill_timewindow_config(xce_timewindow_config_t* w)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (w == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (w->segs != NULL) {
|
||||
for (i = 0; i < w->nsegs; i++) {
|
||||
xce_timewindow_seg_config_t* seg = w->segs[i];
|
||||
|
||||
kill_timewindow_seg_config(seg);
|
||||
}
|
||||
|
||||
FREEUP(w->segs);
|
||||
}
|
||||
|
||||
FREEUP(w);
|
||||
}
|
||||
|
||||
void free_timewindow_config(xce_timewindow_config_t* w)
|
||||
{
|
||||
kill_timewindow_config(w);
|
||||
}
|
||||
|
||||
static xce_timewindow_seg_config_t* dup_timewindow_seg_config(xce_timewindow_seg_config_t* src)
|
||||
{
|
||||
xce_timewindow_seg_config_t* seg = NULL;
|
||||
|
||||
if (src == NULL) {
|
||||
errno = EINVAL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seg = (xce_timewindow_seg_config_t*)calloc(1, sizeof(*seg));
|
||||
if (seg == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seg->tz = strdup(src->tz);
|
||||
if (seg->tz == NULL) {
|
||||
kill_timewindow_seg_config(seg);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seg->open = (xce_timewindow_time_t*)calloc(1, sizeof(xce_timewindow_time_t));
|
||||
seg->close = (xce_timewindow_time_t*)calloc(1, sizeof(xce_timewindow_time_t));
|
||||
if ((seg->open == NULL) || (seg->close == NULL)) {
|
||||
kill_timewindow_seg_config(seg);
|
||||
errno = ENOMEM;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(seg->open, src->open, sizeof(xce_timewindow_time_t));
|
||||
memcpy(seg->close, src->close, sizeof(xce_timewindow_time_t));
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
||||
xce_timewindow_config_t* dup_timewindow_config(xce_timewindow_config_t* src)
|
||||
{
|
||||
xce_timewindow_config_t* w;
|
||||
int i;
|
||||
|
||||
if (src == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w = (xce_timewindow_config_t*)calloc(1, sizeof(*w));
|
||||
if (w == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w->segs = (xce_timewindow_seg_config_t**)calloc(src->nsegs,
|
||||
sizeof(xce_timewindow_seg_config_t*));
|
||||
if (w->segs == NULL) {
|
||||
kill_timewindow_config(w);
|
||||
errno = ENOMEM;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < src->nsegs; i++) {
|
||||
w->segs[i] = dup_timewindow_seg_config(src->segs[i]);
|
||||
if (w->segs[i] == NULL) {
|
||||
kill_timewindow_config(w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
w->nsegs = src->nsegs;
|
||||
|
||||
return w;
|
||||
}
|
||||
667
src/lib/xceapi.c
Normal file
667
src/lib/xceapi.c
Normal file
|
|
@ -0,0 +1,667 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "xceapi.h"
|
||||
|
||||
int xce_hello(xce_ctx_t* ctx,
|
||||
char* msg)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc, status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_hello_req(ioctx, msg);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_shutdown(xce_ctx_t* ctx)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_shutdown_req(ioctx);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_get(xce_ctx_t* ctx,
|
||||
int table,
|
||||
void*** data)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
xce_match_t condition = {
|
||||
.type = MatchCondition_condition_matchall
|
||||
};
|
||||
xce_get_t get = {
|
||||
.table = table,
|
||||
.condition = &condition
|
||||
};
|
||||
dataset_t getreply = {
|
||||
.table = table,
|
||||
.nrows = 0,
|
||||
.rows = NULL
|
||||
};
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctx->reply.u.get = &getreply;
|
||||
rc = xce_get_req(ioctx, &get);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (status >= 0) {
|
||||
*data = getreply.rows;
|
||||
rc = getreply.nrows;
|
||||
} else {
|
||||
rc = status;
|
||||
}
|
||||
|
||||
ctx->reply.u.get = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xce_reslist(xce_ctx_t* ctx,
|
||||
xce_resource_t*** res)
|
||||
{
|
||||
int table = Data_data_resources;
|
||||
|
||||
return xce_get(ctx, table, (void***)res);
|
||||
}
|
||||
|
||||
int xce_resval(xce_ctx_t* ctx,
|
||||
char* host,
|
||||
char* res,
|
||||
xce_resval_t*** vals)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
/* clang-format off */
|
||||
xce_reskey_t reskey = {
|
||||
.resname = res,
|
||||
.hostname = host
|
||||
};
|
||||
xce_match_t condition = {
|
||||
.type = MatchCondition_condition_matchreskey,
|
||||
.condition = {
|
||||
.reskey = &reskey
|
||||
}
|
||||
};
|
||||
xce_get_t get = {
|
||||
.table = Data_data_resvals,
|
||||
.condition = &condition
|
||||
};
|
||||
dataset_t getreply = {
|
||||
.table = Data_data_resvals,
|
||||
.nrows = 0,
|
||||
.rows = NULL
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctx->reply.u.get = &getreply;
|
||||
rc = xce_get_req(ioctx, &get);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (status >= 0) {
|
||||
*vals = (xce_resval_t**)getreply.rows;
|
||||
rc = getreply.nrows;
|
||||
} else {
|
||||
rc = status;
|
||||
}
|
||||
|
||||
ctx->reply.u.get = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xce_join(xce_ctx_t* ctx,
|
||||
int role,
|
||||
hostattrs_t* attrs)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc, status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_join_req(ioctx, role, attrs);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_workerlist(xce_ctx_t* ctx,
|
||||
xce_worker_t*** workers)
|
||||
{
|
||||
int table = Data_data_workers;
|
||||
|
||||
return xce_get(ctx, table, (void***)workers);
|
||||
}
|
||||
|
||||
int xce_free_workers(int nworkers,
|
||||
xce_worker_t* workers)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_jobdispatch(xce_ctx_t* ctx,
|
||||
xce_job_dispatch_t* info)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc, status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_jobdispatch_req(ioctx, info);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_notify(xce_ctx_t* ctx,
|
||||
xce_notify_data_t* data)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_notify_req(ioctx, data);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xce_jobsubmit(xce_ctx_t* ctx,
|
||||
xce_job_submit_t* submit,
|
||||
uint64_t* jobid)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc, status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_jobsubmit_req(ioctx, submit);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (status >= 0) {
|
||||
*jobid = ctx->reply.u.jobid;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_joblist_ex(xce_ctx_t* ctx,
|
||||
int sched,
|
||||
xce_job_t*** jobs)
|
||||
{
|
||||
int table;
|
||||
|
||||
if (sched) {
|
||||
table = Data_data_schedjobs;
|
||||
} else {
|
||||
table = Data_data_jobs;
|
||||
}
|
||||
|
||||
return xce_get(ctx, table, (void***)jobs);
|
||||
}
|
||||
|
||||
int xce_sched_joblist(xce_ctx_t* ctx,
|
||||
xce_job_t*** jobs)
|
||||
{
|
||||
return xce_joblist_ex(ctx, 1, jobs);
|
||||
}
|
||||
|
||||
int xce_joblist(xce_ctx_t* ctx,
|
||||
xce_job_t*** jobs)
|
||||
{
|
||||
return xce_joblist_ex(ctx, 0, jobs);
|
||||
}
|
||||
|
||||
int xce_varlist(xce_ctx_t* ctx,
|
||||
xce_config_t*** vars)
|
||||
{
|
||||
#if 0
|
||||
int table = XCETables_conf;
|
||||
|
||||
return xce_get(ctx, table, (void***)vars);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_queuelist(xce_ctx_t* ctx,
|
||||
xce_queue_t*** queues)
|
||||
{
|
||||
#if 0
|
||||
int table = XCETables_queues;
|
||||
|
||||
return xce_get(ctx, table, (void***)queues);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xce_free_queues(int nqueues,
|
||||
xce_queue_t* queues)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (queues == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < nqueues; i++) {
|
||||
FREEUP(queues[i].resreq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_grouplist(xce_ctx_t* ctx,
|
||||
int group_type,
|
||||
xce_group_t*** groups)
|
||||
{
|
||||
#if 0
|
||||
int table;
|
||||
|
||||
switch (group_type) {
|
||||
case 0:
|
||||
table = XCETables_ugroups;
|
||||
break;
|
||||
default:
|
||||
table = XCETables_hgroups;
|
||||
break;
|
||||
}
|
||||
|
||||
return xce_get(ctx, table, (void***)groups);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xce_free_groups(int ngroups,
|
||||
xce_group_t* groups)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_clusterconf(xce_ctx_t* ctx,
|
||||
xce_clusterconf_t** conf)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc, status;
|
||||
|
||||
if ((ctx == NULL) || (conf == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_clusterconf_req(ioctx);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
MOVE_PTR((*conf), ctx->reply.u.clusterconf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_update_resvals(xce_ctx_t* ctx,
|
||||
int count,
|
||||
xce_resval_t** vals)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
/* clang-format off */
|
||||
xce_resval_list_t valist = {
|
||||
.count = count,
|
||||
.vals = vals
|
||||
};
|
||||
xce_update_data_t data = {
|
||||
.table = Update_data_resvals,
|
||||
.data = {
|
||||
.resvals = &valist
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_update_req(ioctx, &data);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_update_jusage(xce_ctx_t* ctx,
|
||||
uint64_t jobid,
|
||||
int npids,
|
||||
int* pids,
|
||||
int ngids,
|
||||
int* pgids,
|
||||
int nusage,
|
||||
xce_rusage_t** usages)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
/* clang-format off */
|
||||
xce_job_rusages_t rusages = {
|
||||
.jobid = jobid,
|
||||
.npids = npids,
|
||||
.pids = pids,
|
||||
.pgids = pgids,
|
||||
.count = nusage,
|
||||
.usages = usages
|
||||
};
|
||||
xce_update_data_t data = {
|
||||
.table = Update_data_jobrusages,
|
||||
.data = {
|
||||
.jobrusages = &rusages }
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_update_req(ioctx, &data);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_jobctrl(xce_ctx_t* ctx,
|
||||
xce_jobctrl_t* ctrl)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_jobctrl_req(ioctx, ctrl);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_queuectrl(xce_ctx_t* ctx,
|
||||
xce_queuectrl_t* ctrl)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_queuectrl_req(ioctx, ctrl);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xce_runtask(xce_ctx_t* ctx,
|
||||
xce_taskrun_t* runinfo)
|
||||
{
|
||||
ioctx_t* ioctx;
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state != XCE_CTX_RUN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ioctx = ioctx_alloc(ctx->ep, &(ctx->myinfo));
|
||||
if (ioctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = xce_runtask_req(ioctx, runinfo);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cbuf_get(&(ctx->wbuf), &status);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
371
src/lib/xcectx.c
Normal file
371
src/lib/xcectx.c
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "dataq.h"
|
||||
#include "mylock.h"
|
||||
#include "netio.h"
|
||||
#include "typemap.h"
|
||||
#include "utils.h"
|
||||
#include "xcectx.h"
|
||||
|
||||
static int handle_get_reply(xce_ctx_t* ctx,
|
||||
xce_reply_t* reply)
|
||||
{
|
||||
xce_data_t* getdata = reply->data.getdata;
|
||||
dataset_t* dataset = ctx->reply.u.get;
|
||||
|
||||
return extract_data(dataset, getdata);
|
||||
}
|
||||
|
||||
static int handle_sub_reply(xce_ctx_t* ctx,
|
||||
xce_reply_t* reply)
|
||||
{
|
||||
if (reply->data_which != RequestReply_data_jobid) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->reply.u.jobid = reply->data.jobid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int handle_reply(xce_ctx_t* ctx,
|
||||
xce_reply_t* reply)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (reply->status < 0) {
|
||||
return reply->status;
|
||||
}
|
||||
|
||||
switch (reply->opcode) {
|
||||
case OPCode_get:
|
||||
rc = handle_get_reply(ctx, reply);
|
||||
break;
|
||||
case OPCode_jobsub:
|
||||
rc = handle_sub_reply(ctx, reply);
|
||||
break;
|
||||
case OPCode_clusterconf:
|
||||
rc = -1;
|
||||
if (reply->data_which == RequestReply_data_clusterconf) {
|
||||
MOVE_PTR(ctx->reply.u.clusterconf,
|
||||
reply->data.clusterconf);
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = -ENOENT;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vtask_entry(vtask_t* task)
|
||||
{
|
||||
endpoint_t* ep = task->ctx.ep;
|
||||
xce_ctx_t* ctx = NULL;
|
||||
int rc = 0;
|
||||
xce_request_t request;
|
||||
|
||||
if (ep == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx = (xce_ctx_t*)ep->owner;
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = ioctx_decode(&(task->ctx), &request);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (request.opcode == OPCode_reply) {
|
||||
int need_wake = 1;
|
||||
int status = request.body.replymsg->status;
|
||||
|
||||
need_wake = handle_reply(ctx, request.body.replymsg);
|
||||
if (need_wake) {
|
||||
rc = xce_wakeup(ctx, (int)status);
|
||||
}
|
||||
} else {
|
||||
int callnext = 1;
|
||||
|
||||
if ((request.opcode == OPCode_push) && (request.body_which == Request_body_pushmsg)) {
|
||||
|
||||
if (ctx->dataset == NULL) {
|
||||
ctx->dataset = (dataset_t*)calloc(1, sizeof(dataset_t));
|
||||
ctx->dataset->table = request.body.pushmsg->table;
|
||||
}
|
||||
|
||||
callnext = extract_data(ctx->dataset,
|
||||
request.body.pushmsg);
|
||||
if (callnext) {
|
||||
FREEUP(request.body.pushmsg);
|
||||
request.body_which = Request_body_datamsg;
|
||||
MOVE_PTR(request.body.datamsg, ctx->dataset);
|
||||
}
|
||||
}
|
||||
|
||||
if (callnext) {
|
||||
rc = (ctx->handler)(&request);
|
||||
}
|
||||
}
|
||||
|
||||
free_Request(&request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int handle_input(endpoint_t* ep)
|
||||
{
|
||||
xce_ctx_t* ctx = (xce_ctx_t*)ep->owner;
|
||||
vtask_t* task;
|
||||
int rc = 0;
|
||||
|
||||
task = vtask_alloc();
|
||||
if (task == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = vtask_init(task, (vtask_func_t)&vtask_entry, ep);
|
||||
if (rc < 0) {
|
||||
SET_ERROR(-rc);
|
||||
|
||||
if (rc == -EPIPE) {
|
||||
/* connection broken */
|
||||
TRACE("broken pipe, ep %p", ep);
|
||||
}
|
||||
|
||||
FREEUP(task);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = vtask_enq(&(ctx->vtaskmgr), task);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_output(endpoint_t* ep)
|
||||
{
|
||||
data_item_t* it;
|
||||
ioctx_t* ctx;
|
||||
int rc;
|
||||
|
||||
it = endpoint_deq(ep);
|
||||
if (it == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = ITPTR_TO_IOCTX(it);
|
||||
|
||||
rc = ioctx_flush(ctx, ep->fd);
|
||||
ioctx_deref(ctx, 1);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int handle_io(struct epoll_event* p)
|
||||
{
|
||||
endpoint_t* ep = (endpoint_t*)p->data.ptr;
|
||||
int rc = 0;
|
||||
|
||||
if ((p->events & EPOLLIN) != 0) {
|
||||
rc = handle_input(ep);
|
||||
}
|
||||
|
||||
if (rc >= 0) {
|
||||
if ((p->events & EPOLLOUT) != 0) {
|
||||
rc = handle_output(ep);
|
||||
}
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
xce_ctx_t* ctx = (xce_ctx_t*)ep->owner;
|
||||
iomgr_t* iomgr = &(ctx->iomgr);
|
||||
iomgr_unmonitor(iomgr, ep);
|
||||
endpoint_deref(ep);
|
||||
|
||||
xce_try_wakeup(ctx, -EIO);
|
||||
|
||||
ctx->state = XCE_CTX_DOWN;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_ctx_init(xce_ctx_t* ctx,
|
||||
char* name,
|
||||
char* key)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (name == NULL) || (key == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(ctx, 0x0, sizeof(*ctx));
|
||||
ctx->state = XCE_CTX_ERR;
|
||||
ctx->myinfo.name = strdup(name);
|
||||
ctx->myinfo.key = strdup(key);
|
||||
|
||||
if ((ctx->myinfo.name == NULL) || (ctx->myinfo.key == NULL)) {
|
||||
FREEUP(ctx->myinfo.name);
|
||||
FREEUP(ctx->myinfo.key);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = cbuf_init(&(ctx->wbuf), 1, sizeof(int));
|
||||
if (rc < 0) {
|
||||
FREEUP(ctx->myinfo.name);
|
||||
FREEUP(ctx->myinfo.key);
|
||||
return rc;
|
||||
}
|
||||
|
||||
iomgr_init(&(ctx->iomgr));
|
||||
vtaskmgr_init(&(ctx->vtaskmgr), 4);
|
||||
|
||||
ctx->ep = NULL;
|
||||
ctx->state = XCE_CTX_INIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xce_ctx_fini(xce_ctx_t* ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xce_ctx_stop(ctx);
|
||||
|
||||
vtaskmgr_fini(&(ctx->vtaskmgr));
|
||||
iomgr_fini(&(ctx->iomgr));
|
||||
cbuf_fini(&(ctx->wbuf));
|
||||
|
||||
FREEUP(ctx->myinfo.name);
|
||||
FREEUP(ctx->myinfo.key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int xce_ctx_set_handler(xce_ctx_t* ctx,
|
||||
xce_request_handler_t handler)
|
||||
{
|
||||
if ((ctx == NULL) || (handler == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->handler = handler;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_ctx_set_endpoint(xce_ctx_t* ctx,
|
||||
endpoint_t* ep)
|
||||
{
|
||||
if ((ctx == NULL) || (ep == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->ep = ep;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_ctx_start(xce_ctx_t* ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ctx->state != XCE_CTX_INIT) || (ctx->ep == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
endpoint_set_handler(ctx->ep,
|
||||
handle_io, ctx);
|
||||
rc = iomgr_monitor(&(ctx->iomgr),
|
||||
ctx->ep);
|
||||
if (rc < 0) {
|
||||
ctx->state = XCE_CTX_ERR;
|
||||
return rc;
|
||||
}
|
||||
|
||||
iomgr_start(&(ctx->iomgr));
|
||||
vtaskmgr_start(&(ctx->vtaskmgr));
|
||||
|
||||
ctx->state = XCE_CTX_RUN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_ctx_stop(xce_ctx_t* ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->ep != NULL) {
|
||||
iomgr_unmonitor(&(ctx->iomgr),
|
||||
ctx->ep);
|
||||
ctx->ep = NULL;
|
||||
}
|
||||
iomgr_stop(&(ctx->iomgr));
|
||||
|
||||
ctx->state = XCE_CTX_DOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xce_wakeup(xce_ctx_t* ctx,
|
||||
int status)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = cbuf_tryput(&(ctx->wbuf), &status);
|
||||
if (rc == -EAGAIN) {
|
||||
/* pending data in wbuf, this is normal */
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xce_try_wakeup(xce_ctx_t* ctx,
|
||||
int status)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cbuf_tryput(&(ctx->wbuf), &status);
|
||||
}
|
||||
|
||||
void xce_block_tasks(xce_ctx_t* ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
endpoint_block_tasks(ctx->ep);
|
||||
}
|
||||
|
||||
void xce_unblock_tasks(xce_ctx_t* ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
endpoint_unblock_tasks(ctx->ep);
|
||||
vtaskmgr_wakeup(&(ctx->vtaskmgr));
|
||||
}
|
||||
99
src/lib/xlist.c
Normal file
99
src/lib/xlist.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "xlist.h"
|
||||
|
||||
int xlist_init(xlist_t* l,
|
||||
int delta)
|
||||
{
|
||||
if ((l == NULL) || (delta <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
l->delta = delta;
|
||||
l->data = NULL;
|
||||
l->count = 0;
|
||||
l->caps = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xlist_ensure(xlist_t* l)
|
||||
{
|
||||
void* p;
|
||||
int nc, i;
|
||||
|
||||
if (l->count < l->caps) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
nc = l->caps + l->delta;
|
||||
p = (void*)realloc(l->data, nc * sizeof(void*));
|
||||
if (p == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
l->data = p;
|
||||
for(i = l->caps; i < nc; i ++) {
|
||||
l->data[i] = NULL;
|
||||
}
|
||||
|
||||
l->caps = nc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xlist_store(xlist_t* l,
|
||||
void* data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (l == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xlist_ensure(l);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
l->data[l->count] = data;
|
||||
l->count++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xlist_clear(xlist_t *l) {
|
||||
if (l == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
int xlist_iter(xlist_t *l,
|
||||
xlist_iter_fn_t fn,
|
||||
void *data) {
|
||||
int i;
|
||||
|
||||
if ((l == NULL) || (fn == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for(i = 0; i < l->count; i ++) {
|
||||
(*fn)((void *)l->data[i], data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xlist_fini(xlist_t* l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
FREEUP(l->data);
|
||||
return;
|
||||
}
|
||||
147
src/lib/xstring.c
Normal file
147
src/lib/xstring.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "htab.h"
|
||||
#include "utils.h"
|
||||
#include "xstring.h"
|
||||
|
||||
static void* xstring_create(objmgr_t*, objtype_t*, va_list);
|
||||
static void xstring_fini(void*);
|
||||
static void xstring_type_fini(objtype_t*);
|
||||
|
||||
static xstring_typedata_t xstring_typedata;
|
||||
|
||||
static objtype_t xstring = {
|
||||
.type = "xstring",
|
||||
.fn_create = (obj_create_fn_t)xstring_create,
|
||||
.fn_fini = xstring_fini,
|
||||
.fn_type_fini = (objtype_fini_fn_t)xstring_type_fini,
|
||||
.typedata = &xstring_typedata
|
||||
};
|
||||
|
||||
static void xstring_obj_killer(myobj_t* obj)
|
||||
{
|
||||
if (obj == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(obj, 0x0, sizeof(*obj));
|
||||
free(obj);
|
||||
}
|
||||
|
||||
int register_xstring(objmgr_t* mgr,
|
||||
int nslots,
|
||||
int delta)
|
||||
{
|
||||
ht_init(&(xstring_typedata.tab), nslots,
|
||||
string_hash_key);
|
||||
zarray_init(&(xstring_typedata.strings), delta,
|
||||
(zarray_item_killer_t)xstring_obj_killer);
|
||||
|
||||
return objmgr_register(mgr, &xstring);
|
||||
}
|
||||
|
||||
static void* xstring_create(objmgr_t* mgr,
|
||||
objtype_t* type,
|
||||
va_list ap)
|
||||
{
|
||||
char* s = va_arg(ap, char*);
|
||||
char* p = NULL;
|
||||
myobj_t* obj = NULL;
|
||||
hent_t* e = NULL;
|
||||
xstring_typedata_t* typedata = NULL;
|
||||
int32_t idx;
|
||||
|
||||
if (s == NULL) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedata = (xstring_typedata_t*)type->typedata;
|
||||
|
||||
e = ht_get((htab_t*)&(typedata->tab), (void*)s);
|
||||
if (e != NULL) {
|
||||
idx = e->data;
|
||||
obj = (myobj_t*)zarray_get(&(typedata->strings), idx);
|
||||
|
||||
if (obj != NULL) {
|
||||
p = MYOBJ_TO_OBJ(char*, obj);
|
||||
return obj_ref(p, OBJREF_NOP);
|
||||
}
|
||||
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = (myobj_t*)calloc(1, sizeof(*obj) + strlen(s) + 1);
|
||||
if (obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idx = zarray_store(&(typedata->strings), obj);
|
||||
if (idx < 0) {
|
||||
free(obj);
|
||||
SET_ERROR(-idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj_init(mgr, type, idx, obj);
|
||||
|
||||
p = MYOBJ_TO_OBJ(char*, obj);
|
||||
|
||||
strcpy(p, s);
|
||||
|
||||
e = ht_add((htab_t*)&(typedata->tab), (void*)s);
|
||||
if (e == NULL) {
|
||||
obj_deref(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e->data = idx;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* this will ONLY be called by obj_deref() */
|
||||
static void xstring_fini(void* s)
|
||||
{
|
||||
myobj_t* myobj;
|
||||
objtype_t* typeval;
|
||||
xstring_typedata_t* typedata;
|
||||
int32_t idx;
|
||||
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
myobj = TO_MYOBJ(s);
|
||||
typeval = myobj->type;
|
||||
typedata = (xstring_typedata_t*)typeval->typedata;
|
||||
|
||||
if (typedata == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ht_del(&(typedata->tab), (void*)s);
|
||||
|
||||
idx = (int32_t)myobj->exdata;
|
||||
if (idx >= 0) {
|
||||
zarray_del(&(typedata->strings), idx);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void xstring_type_fini(objtype_t* typeval)
|
||||
{
|
||||
xstring_typedata_t* typedata = (xstring_typedata_t*)typeval->typedata;
|
||||
|
||||
if (typedata == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ht_fini(&(typedata->tab));
|
||||
zarray_fini(&(typedata->strings));
|
||||
}
|
||||
277
src/lib/zarray.c
Normal file
277
src/lib/zarray.c
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "zarray.h"
|
||||
|
||||
int zarray_init(zarray_t* array,
|
||||
int delta,
|
||||
zarray_item_killer_t killer)
|
||||
{
|
||||
if ((array == NULL) || (delta <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_init(&(array->lock));
|
||||
|
||||
array->delta = delta;
|
||||
array->data = NULL;
|
||||
array->killer = killer;
|
||||
array->count = 0;
|
||||
array->caps = 0;
|
||||
array->pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zarray_ensure_items(zarray_t* array,
|
||||
int mincap)
|
||||
{
|
||||
int nc, i;
|
||||
void* p;
|
||||
|
||||
if (mincap < array->caps) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
nc = mincap;
|
||||
if (nc < array->caps + array->delta) {
|
||||
nc = array->caps + array->delta;
|
||||
}
|
||||
|
||||
p = (void*)realloc(array->data, nc * sizeof(void*));
|
||||
if (p == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
array->data = p;
|
||||
for (i = array->caps; i < nc; i++) {
|
||||
array->data[i] = NULL;
|
||||
}
|
||||
|
||||
/* this will make we can get next free
|
||||
* location quickly
|
||||
*/
|
||||
array->pos = array->caps;
|
||||
array->caps = nc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int zarray_store(zarray_t* array,
|
||||
void* data)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
if (array == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(array->lock));
|
||||
rc = zarray_ensure_items(array, array->count + 1);
|
||||
|
||||
if (rc >= 0) {
|
||||
int idx;
|
||||
|
||||
rc = -ENOMEM;
|
||||
idx = array->pos;
|
||||
|
||||
for (i = 0; i < array->caps; i++) {
|
||||
if (array->data[idx] == NULL) {
|
||||
array->data[idx] = data;
|
||||
array->count++;
|
||||
rc = idx;
|
||||
break;
|
||||
}
|
||||
|
||||
idx++;
|
||||
if (idx >= array->caps) {
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
if (rc >= 0) {
|
||||
array->pos = (rc + 1) % array->caps;
|
||||
}
|
||||
}
|
||||
|
||||
mylock_unlock(&(array->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int zarray_clear(zarray_t* array,
|
||||
int idx)
|
||||
{
|
||||
if (array == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((idx < 0) || (idx >= array->caps)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(array->lock));
|
||||
array->data[idx] = NULL;
|
||||
mylock_unlock(&(array->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zarray_fini(zarray_t* array)
|
||||
{
|
||||
if (array == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array->data != NULL) {
|
||||
int i;
|
||||
|
||||
if (array->killer != NULL) {
|
||||
for (i = 0; i < array->caps; i++) {
|
||||
if (array->data[i] != NULL) {
|
||||
void* ptr = array->data[i];
|
||||
array->data[i] = NULL;
|
||||
(array->killer)(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(array->data);
|
||||
array->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int zarray_iter_ex(zarray_t* array,
|
||||
xlist_t* l,
|
||||
void* arg)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if ((array == NULL) || (l == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(array->lock));
|
||||
|
||||
for (j = 0; j < l->count; j++) {
|
||||
zarray_iter_fn_t f = (zarray_iter_fn_t)l->data[j];
|
||||
|
||||
if (f == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < array->caps; i++) {
|
||||
(*f)(arg, array->data[i]);
|
||||
}
|
||||
}
|
||||
mylock_unlock(&(array->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zarray_iter(zarray_t* array,
|
||||
zarray_iter_fn_t f,
|
||||
void* arg)
|
||||
{
|
||||
int rc;
|
||||
xlist_t l;
|
||||
|
||||
if ((array == NULL) || (f == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
xlist_init(&l, 2);
|
||||
xlist_store(&l, f);
|
||||
|
||||
rc = zarray_iter_ex(array, &l, arg);
|
||||
|
||||
xlist_fini(&l);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int zarray_del(zarray_t* array,
|
||||
int idx)
|
||||
{
|
||||
void* ptr = NULL;
|
||||
|
||||
if (array == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((idx < 0) && (idx >= array->caps)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mylock_lock(&(array->lock));
|
||||
ptr = array->data[idx];
|
||||
array->data[idx] = NULL;
|
||||
if (ptr != NULL) {
|
||||
array->count--;
|
||||
}
|
||||
|
||||
/* idx will be a usable position */
|
||||
array->pos = idx;
|
||||
mylock_unlock(&(array->lock));
|
||||
|
||||
if (array->killer != NULL) {
|
||||
if (ptr != NULL) {
|
||||
(array->killer)(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zarray_put(zarray_t* array,
|
||||
int idx,
|
||||
void* data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* clang-format off */
|
||||
if ((array == NULL) ||
|
||||
(idx < 0) ||
|
||||
(data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
mylock_lock(&(array->lock));
|
||||
rc = zarray_ensure_items(array, idx + 1);
|
||||
if (rc >= 0) {
|
||||
void* ptr = array->data[idx];
|
||||
array->data[idx] = data;
|
||||
rc = 0;
|
||||
if (ptr != NULL) {
|
||||
if (array->killer != NULL) {
|
||||
array->killer(ptr);
|
||||
}
|
||||
} else {
|
||||
array->count++;
|
||||
}
|
||||
}
|
||||
mylock_unlock(&(array->lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void* zarray_get(zarray_t* array,
|
||||
int idx)
|
||||
{
|
||||
void* ptr = NULL;
|
||||
|
||||
/* clang-format off */
|
||||
if ((array == NULL) ||
|
||||
(idx < 0) ||
|
||||
(idx >= array->caps)) {
|
||||
SET_ERROR(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
mylock_lock(&(array->lock));
|
||||
ptr = array->data[idx];
|
||||
mylock_unlock(&(array->lock));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
28
src/meson.build
Normal file
28
src/meson.build
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
project('xce',
|
||||
['c'],
|
||||
version: '0.0.1',
|
||||
meson_version: '>=1.5',
|
||||
default_options: [
|
||||
'c_std=gnu17',
|
||||
'c_args=-DDEBUG -O1'])
|
||||
|
||||
with_debug=false
|
||||
|
||||
if get_option('with_debug')
|
||||
# add -DWITH_DEBUG=1
|
||||
add_project_arguments('-DWITH_DEBUG=1', language: 'c')
|
||||
with_debug=true
|
||||
endif
|
||||
|
||||
if get_option('without_db')
|
||||
add_project_arguments('-DWITHOUT_DB=1', language: 'c')
|
||||
endif
|
||||
|
||||
add_project_arguments('-DVERSION_COMMIT_ID='+get_option('commit_id'), language: 'c')
|
||||
|
||||
include_dir = include_directories('include', 'include/xce')
|
||||
|
||||
subdir('lib')
|
||||
# subdir('controller')
|
||||
# subdir('worker')
|
||||
# subdir('scheduler')
|
||||
3
src/meson.options
Normal file
3
src/meson.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
option('with_debug', type: 'boolean', value: false, yield: true)
|
||||
option('without_db', type: 'boolean', value: false, yield: true)
|
||||
option('commit_id', type: 'string', value:'', yield: true)
|
||||
69
src/schema/c.capnp
Normal file
69
src/schema/c.capnp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Copyright (c) 2016 NetDEF, Inc. and contributors
|
||||
# Licensed under the MIT License:
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
@0xc0183dd65ffef0f3;
|
||||
|
||||
annotation nameinfix @0x85a8d86d736ba637 (file): Text;
|
||||
# add an infix (middle insert) for output file names
|
||||
#
|
||||
# "make" generally has implicit rules for compiling "foo.c" => "foo". This
|
||||
# is very annoying with capnp since the rule will be "foo" => "foo.c", leading
|
||||
# to a loop. $nameinfix (recommended parameter: "-gen") inserts its parameter
|
||||
# before the ".c", so the filename becomes "foo-gen.c"
|
||||
#
|
||||
# Alternatively, add this Makefile rule to disable compiling "foo.capnp.c" -> "foo.capnp":
|
||||
# %.capnp: ;
|
||||
#
|
||||
#
|
||||
# ("foo" is really "foo.capnp", so it's foo.capnp-gen.c)
|
||||
|
||||
annotation fieldgetset @0xf72bc690355d66de (file): Void;
|
||||
# generate getter & setter functions for accessing fields
|
||||
#
|
||||
# allows grabbing/putting values without de-/encoding the entire struct.
|
||||
|
||||
annotation donotinclude @0x8c99797357b357e9 (file): UInt64;
|
||||
# do not generate an include directive for an import statement for the file with
|
||||
# the given ID
|
||||
|
||||
annotation typedefto @0xcefaf27713042144 (struct, enum): Text;
|
||||
# generate a typedef for the annotated struct or enum declaration
|
||||
|
||||
annotation namespace @0xf2c035025fec7c2b (file): Text;
|
||||
# prefix structs with a name space string
|
||||
|
||||
annotation extraheader @0xbadb496d09cf4612 (file): Text;
|
||||
# add extra preprocessor directives to the header
|
||||
|
||||
annotation extendedattribute @0xd187bca5c6844c24 (file): Text;
|
||||
# add an extended attribute to each generated function
|
||||
|
||||
annotation codecgen @0xcccaac86283e2609 (file): Void;
|
||||
# generate codec(encode/decode) to each type
|
||||
|
||||
annotation mapname @0xb9edf6fc2d8972b8 (*): Text;
|
||||
# the mapped type name which will be encoded
|
||||
|
||||
annotation maplistcount @0xb6ea49eb8a9b0f9e (field): Text;
|
||||
# the mapped list count field which will be encoded
|
||||
|
||||
annotation mapuniontag @0xdce06d41858f91ac (union, struct): Text;
|
||||
# the mapped tag (which) of union
|
||||
590
src/schema/controller.capnp
Normal file
590
src/schema/controller.capnp
Normal file
|
|
@ -0,0 +1,590 @@
|
|||
@0xdefcdf6377db2e8e;
|
||||
|
||||
using C = import "/c.capnp";
|
||||
|
||||
$C.fieldgetset;
|
||||
$C.codecgen;
|
||||
$C.extraheader("#include \"clusterconfig.h\"");
|
||||
$C.extraheader("#include \"typemap.h\"");
|
||||
|
||||
enum OPCode {
|
||||
nop @0;
|
||||
reply @1;
|
||||
hello @2;
|
||||
join @3;
|
||||
shutdown @4;
|
||||
get @5;
|
||||
push @6;
|
||||
update @7;
|
||||
jobdispatch @8;
|
||||
startjob @9;
|
||||
notify @10;
|
||||
jobsub @11;
|
||||
jobstatus @12;
|
||||
jobrusage @13;
|
||||
hostcontrol @14;
|
||||
jobcontrol @15;
|
||||
newschedjobs @16;
|
||||
clusterconf @17;
|
||||
queuecontrol @18;
|
||||
runtasks @19;
|
||||
}
|
||||
|
||||
struct PeerInfo $C.mapname("xce_peerinfo_t") {
|
||||
host @0: Text $C.mapname("name");
|
||||
key @1: Text;
|
||||
}
|
||||
|
||||
struct StrList $C.mapname("xce_strlist_t") {
|
||||
data @0: List(Text) $C.mapname("data") $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct TimeWindowTime $C.mapname("xce_timewindow_time_t") {
|
||||
day @0: UInt32 $C.mapname("day");
|
||||
hour @1: UInt32 $C.mapname("hour");
|
||||
min @2: UInt32 $C.mapname("min");
|
||||
}
|
||||
|
||||
struct TimeWindowSeg $C.mapname("xce_timewindow_seg_config_t") {
|
||||
timezone @0: Text $C.mapname("tz");
|
||||
open @1: TimeWindowTime $C.mapname("open");
|
||||
close @2: TimeWindowTime $C.mapname("close");
|
||||
}
|
||||
|
||||
struct TimeWindow $C.mapname("xce_timewindow_config_t") {
|
||||
segs @0: List(TimeWindowSeg) $C.mapname("segs") $C.maplistcount("nsegs");
|
||||
}
|
||||
|
||||
struct Group $C.mapname("xce_group_t") {
|
||||
name @0: Text $C.mapname("name");
|
||||
members @1: List(Text) $C.mapname("members.data") $C.maplistcount("members.count");
|
||||
exmembers @2: List(Text) $C.mapname("ex_members.data") $C.maplistcount("ex_members.count");
|
||||
}
|
||||
|
||||
# This data structure will not be transfer in wire
|
||||
# directly, it will be assembled by multiple Data packet
|
||||
struct Dataset $C.mapname("dataset_t") {
|
||||
table @0: UInt32;
|
||||
nrows @1: UInt32;
|
||||
rows @2: Void; # do NOT change this, it's place holder
|
||||
}
|
||||
|
||||
struct ResKey $C.mapname("xce_reskey_t") {
|
||||
resname @0: Text;
|
||||
hostname @1: Text;
|
||||
}
|
||||
|
||||
struct MatchCondition $C.mapname("xce_match_t") {
|
||||
condition :union $C.mapuniontag("type") {
|
||||
matchall @0: Void;
|
||||
matchjid @1: UInt64 $C.mapname("jobid");
|
||||
matchwname @2: Text $C.mapname("wname");
|
||||
matchreskey @3: ResKey $C.mapname("reskey");
|
||||
}
|
||||
}
|
||||
|
||||
struct HostAttrs $C.mapname("hostattrs_t") {
|
||||
type @0: Text $C.mapname("hosttype");
|
||||
model @1: Text $C.mapname("hostmodel");
|
||||
cpufactor @2: Float64;
|
||||
maxcpus @3: Int32;
|
||||
maxmem @4: Float64;
|
||||
maxswap @5: Float64;
|
||||
maxtmp @6: Float64;
|
||||
ndisks @7: Int32;
|
||||
}
|
||||
|
||||
struct Worker $C.mapname("xce_worker_t"){
|
||||
name @0: Text;
|
||||
attrs @1: HostAttrs;
|
||||
status @2: UInt32;
|
||||
dispatchWindow @3: TimeWindow $C.mapname("dispatch_window_config");
|
||||
thresholds @4: List(Threshold) $C.mapname("thresholds") $C.maplistcount("nthresholds");
|
||||
resvals @5: List(ValueWithIdx) $C.mapname("resvals_to_sched") $C.maplistcount("nresvals_to_sched");
|
||||
}
|
||||
|
||||
enum HostRole {
|
||||
client @0;
|
||||
worker @1;
|
||||
scheduler @2;
|
||||
controller @3;
|
||||
}
|
||||
|
||||
struct JoinData $C.mapname("xce_joindata_t") {
|
||||
role @0: HostRole;
|
||||
data :union {
|
||||
nodata @1: Void;
|
||||
attrs @2: HostAttrs;
|
||||
}
|
||||
}
|
||||
|
||||
struct Value $C.mapname("xce_val_t"){
|
||||
u :union $C.mapuniontag("which") {
|
||||
ivalue32 @0: Int32;
|
||||
uvalue32 @1: UInt32;
|
||||
ivalue64 @2: Int64;
|
||||
uvalue64 @3: UInt64;
|
||||
svalue @4: Text;
|
||||
fvalue @5: Float64;
|
||||
bvalue @6: Bool;
|
||||
}
|
||||
}
|
||||
|
||||
struct ValueWithIdx $C.mapname("xce_val_with_idx_t") {
|
||||
idx @0: UInt32;
|
||||
val @1: Value $C.mapname("val");
|
||||
}
|
||||
|
||||
struct ConfigVar $C.mapname("xce_config_t") {
|
||||
name @0: Text;
|
||||
value @1: Text;
|
||||
}
|
||||
|
||||
struct ResourceDistribution $C.mapname("res_distribution_t") {
|
||||
value @0: Value;
|
||||
hosts @1: List(Text) $C.maplistcount("nhosts");
|
||||
}
|
||||
|
||||
struct Resource $C.mapname("xce_resource_t"){
|
||||
name @0: Text;
|
||||
desc @1: Text;
|
||||
idx @2: Int32;
|
||||
valtype @3: Int32;
|
||||
ordtype @4: Int32;
|
||||
flags @5: Int32;
|
||||
interval @6: Int32;
|
||||
lastReport @7: UInt64 $C.mapname("last_report");
|
||||
distributions @8: List(ResourceDistribution) $C.maplistcount("ndistributions");
|
||||
hostBased @9: Value $C.mapname("hbased_defined");
|
||||
}
|
||||
|
||||
struct Threshold $C.mapname("xce_res_threshold_t"){
|
||||
name @0: Text;
|
||||
sched @1: Float64;
|
||||
stop @2: Float64;
|
||||
}
|
||||
|
||||
struct QueueConf $C.mapname("xce_queue_t") {
|
||||
name @0: Text $C.mapname("queue");
|
||||
attrs @1: UInt32;
|
||||
status @2: UInt32;
|
||||
priority @3: Int32;
|
||||
acceptIntervals @4: Int32 $C.mapname("accept_interval");
|
||||
schedDelay @5: Int32 $C.mapname("sched_delay");
|
||||
resreq @6: Text;
|
||||
users @7: Group $C.mapname("users");
|
||||
hosts @8: Group $C.mapname("hosts");
|
||||
thresholds @9: List(Threshold) $C.maplistcount("nthresholds");
|
||||
preExec @10: Text $C.mapname("pre_exec");
|
||||
postExec @11: Text $C.mapname("post_exec");
|
||||
runWindow @12: TimeWindow $C.mapname("runwindow_config");
|
||||
dispatchWindow @13: TimeWindow $C.mapname("dispatchwindow_config");
|
||||
}
|
||||
|
||||
struct Conf4Sched $C.mapname("xce_conf4sched_t"){
|
||||
clustername @0: Text;
|
||||
configvars @1: List(ConfigVar) $C.mapname("confvars") $C.maplistcount("n_confvars");
|
||||
resources @2: List(Resource) $C.maplistcount("n_resources");
|
||||
queues @3: List(QueueConf) $C.maplistcount("n_queues");
|
||||
ugroups @4: List(Group) $C.maplistcount("n_ugroups");
|
||||
hgroups @5: List(Group) $C.maplistcount("n_hgroups");
|
||||
resvals @6: List(ValueWithIdx) $C.mapname("resvals") $C.maplistcount("nresvals");
|
||||
}
|
||||
|
||||
struct Conf4Worker $C.mapname("xce_conf4worker_t") {
|
||||
clustername @0: Text;
|
||||
configvars @1: List(ConfigVar) $C.mapname("confvars") $C.maplistcount("n_confvars");
|
||||
}
|
||||
|
||||
struct ConfigData $C.mapname("xce_configdata_t") {
|
||||
data :union $C.mapuniontag("data_which") {
|
||||
schedconfig @0: Conf4Sched $C.mapname("conf4sched");
|
||||
workerconfig @1: Conf4Worker $C.mapname("conf4worker");
|
||||
}
|
||||
}
|
||||
|
||||
struct JobPIDInfo $C.mapname("job_pidinfo_t"){
|
||||
jobId @0: UInt64 $C.mapname("jobid");
|
||||
pids @1: List(UInt32) $C.mapname("pids") $C.maplistcount("npids");
|
||||
pgids @2: List(UInt32) $C.mapname("pgids") $C.maplistcount("npgids");
|
||||
exdata @3: Text $C.mapname("exdata");
|
||||
}
|
||||
|
||||
struct JobFail $C.mapname("job_failinfo_t"){
|
||||
jobId @0: UInt64 $C.mapname("jobid");
|
||||
code @1: Int32 $C.mapname("code");
|
||||
desc @2: Text $C.mapname("detail");
|
||||
stage @3: UInt32 $C.mapname("stage");
|
||||
}
|
||||
|
||||
struct JobStartInfo $C.mapname("job_startinfo_t"){
|
||||
exechome @0: Text;
|
||||
execcwd @1: Text;
|
||||
execuser @2: Text;
|
||||
cmdline @3: Text;
|
||||
exdata @4: Text;
|
||||
launchtype @5: Text $C.mapname("launch_type");
|
||||
qPreExec @6: Text $C.mapname("q_pre_exec");
|
||||
qPostExec @7: Text $C.mapname("q_post_exec");
|
||||
preExec @8: Text $C.mapname("job_pre_exec");
|
||||
postExec @9: Text $C.mapname("job_post_exec");
|
||||
}
|
||||
|
||||
struct Job $C.mapname("xce_job_t"){
|
||||
jobid @0: UInt64;
|
||||
queue @1: Text;
|
||||
user @2: Text;
|
||||
idx @3: UInt64;
|
||||
subtime @4: UInt64 $C.mapname("sub_time");
|
||||
queuetime @5: UInt64 $C.mapname("queue_time");
|
||||
starttime @6: UInt64 $C.mapname("start_time");
|
||||
finishtime @7: UInt64 $C.mapname("finish_time");
|
||||
state @8: UInt32;
|
||||
jobname @9: Text $C.mapname("job_name");
|
||||
projectname @10: Text $C.mapname("project_name");
|
||||
usergroup @11: Text $C.mapname("user_group");
|
||||
desc @12: Text $C.mapname("job_description");
|
||||
resreq @13: Text;
|
||||
allocs @14: JobAlloc $C.mapname("allocs");
|
||||
runtime @15: UInt32 $C.mapname("run_time");
|
||||
pidinfo @16: JobPIDInfo;
|
||||
startinfo @17: JobStartInfo $C.mapname("start_info");
|
||||
mintasks @18: UInt32 $C.mapname("mintasks");
|
||||
maxtasks @19: UInt32 $C.mapname("maxtasks");
|
||||
}
|
||||
|
||||
struct SchedJob $C.mapname("xce_job_t"){
|
||||
jobid @0: UInt64;
|
||||
queue @1: Text;
|
||||
user @2: Text;
|
||||
idx @3: UInt64;
|
||||
subtime @4: UInt64 $C.mapname("sub_time");
|
||||
queuetime @5: UInt64 $C.mapname("queue_time");
|
||||
starttime @6: UInt64 $C.mapname("start_time");
|
||||
finishtime @7: UInt64 $C.mapname("finish_time");
|
||||
state @8: UInt32;
|
||||
jobname @9: Text $C.mapname("job_name");
|
||||
projectname @10: Text $C.mapname("project_name");
|
||||
usergroup @11: Text $C.mapname("user_group");
|
||||
resreq @12: Text;
|
||||
allocs @13: JobAlloc $C.mapname("allocs");
|
||||
runtime @14: UInt32 $C.mapname("run_time");
|
||||
mintasks @15: UInt32 $C.mapname("mintasks");
|
||||
maxtasks @16: UInt32 $C.mapname("maxtasks");
|
||||
}
|
||||
|
||||
struct JobData $C.mapname("xce_jobs_data_t") {
|
||||
ntotal @0: UInt32 $C.mapname("n_total");
|
||||
pos @1: UInt32;
|
||||
jobs @2: List(Job) $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct SchedJobData $C.mapname("xce_jobs_data_t") {
|
||||
ntotal @0: UInt32 $C.mapname("n_total");
|
||||
pos @1: UInt32;
|
||||
jobs @2: List(SchedJob) $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct WorkerData $C.mapname("xce_workers_data_t"){
|
||||
ntotal @0: UInt32 $C.mapname("n_total");
|
||||
pos @1: UInt32;
|
||||
workers @2: List(Worker) $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct ResourceData $C.mapname("xce_resource_data_t") {
|
||||
ntotal @0: UInt32 $C.mapname("n_total");
|
||||
pos @1: UInt32;
|
||||
resources @2: List(Resource) $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct ResourceVal $C.mapname("xce_resval_t") {
|
||||
name @0: Text $C.mapname("name");
|
||||
host @1: Text $C.mapname("host");
|
||||
val @2: Value $C.mapname("val");
|
||||
}
|
||||
|
||||
struct ResourceVals $C.mapname("xce_resval_data_t") {
|
||||
ntotal @0: UInt32 $C.mapname("n_total");
|
||||
pos @1: UInt32;
|
||||
vals @2: List(ResourceVal) $C.mapname("vals") $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct Data $C.mapname("xce_data_t"){
|
||||
data :union $C.mapuniontag("table") {
|
||||
schedjobs @0: SchedJobData $C.mapname("jobs");
|
||||
schedworkers @1: WorkerData $C.mapname("workers");
|
||||
jobs @2: JobData $C.mapname("jobs");
|
||||
workers @3: WorkerData $C.mapname("workers");
|
||||
resources @4: ResourceData $C.mapname("resources");
|
||||
resvals @5: ResourceVals $C.mapname("resvals");
|
||||
}
|
||||
}
|
||||
|
||||
struct Get $C.mapname("xce_get_t") {
|
||||
table @0: UInt32;
|
||||
condition @1: MatchCondition;
|
||||
}
|
||||
|
||||
struct ResValList $C.mapname("xce_resval_list_t") {
|
||||
vals @0: List(ResourceVal) $C.mapname("vals") $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct ResUsage $C.mapname("xce_rusage_t") {
|
||||
name @0: Text $C.mapname("resname");
|
||||
value @1: Float64 $C.mapname("value");
|
||||
}
|
||||
|
||||
struct JobRusages $C.mapname("xce_job_rusages_t") {
|
||||
jobid @0: UInt64 $C.mapname("jobid");
|
||||
pids @1: List(Int32) $C.mapname("pids") $C.maplistcount("npids");
|
||||
pgids @2: List(Int32) $C.mapname("pgids") $C.maplistcount("npgids");
|
||||
usages @3: List(ResUsage) $C.mapname("usages") $C.maplistcount("count");
|
||||
}
|
||||
|
||||
struct Update $C.mapname("xce_update_data_t") {
|
||||
data :union $C.mapuniontag("table") {
|
||||
nodata @0: Void;
|
||||
resvals @1: ResValList $C.mapname("resvals");
|
||||
jobrusages @2: JobRusages $C.mapname("jobrusages");
|
||||
}
|
||||
}
|
||||
|
||||
struct ResAlloc $C.mapname("xce_alloc_t"){
|
||||
name @0: Text $C.mapname("resname");
|
||||
resvId @1: Text $C.mapname("reserve");
|
||||
instid @2: UInt32;
|
||||
value @3: Float64;
|
||||
from @4: UInt64; # alloc start time
|
||||
duration @5: Int64;
|
||||
}
|
||||
|
||||
struct HostAlloc $C.mapname("xce_host_alloc_t"){
|
||||
host @0: Text;
|
||||
allocs @1: List(ResAlloc) $C.mapname("allocs") $C.maplistcount("nallocs");
|
||||
}
|
||||
|
||||
struct JobAlloc $C.mapname("xce_job_alloc_t"){
|
||||
jobid @0: UInt64;
|
||||
allocs @1: List(HostAlloc) $C.mapname("allocs") $C.maplistcount("nhosts");
|
||||
}
|
||||
|
||||
struct JobDispatch $C.mapname("xce_job_dispatch_t"){
|
||||
allocs @0: List(JobAlloc) $C.maplistcount("njobs");
|
||||
}
|
||||
|
||||
struct HostLaunch $C.mapname("xce_host_launch_t") {
|
||||
host @0: Text $C.mapname("host");
|
||||
nranks @1: UInt32 $C.mapname("nranks");
|
||||
}
|
||||
|
||||
struct JobLaunch $C.mapname("xce_launch_t") {
|
||||
hosts @0: List(HostLaunch) $C.mapname("hosts") $C.maplistcount("nhosts");
|
||||
}
|
||||
|
||||
struct JobExecInfo $C.mapname("xce_job_exec_t"){
|
||||
jobid @0: UInt64;
|
||||
startinfo @1: JobStartInfo $C.mapname("start_info");
|
||||
launchinfo @2: JobLaunch $C.mapname("launchinfo");
|
||||
}
|
||||
|
||||
struct JobFinishInfo $C.mapname("xce_jobfinish_t") {
|
||||
jobid @0: UInt64;
|
||||
code @1: Int32 $C.mapname("exit_code");
|
||||
}
|
||||
|
||||
struct TaskPidInfo $C.mapname("xce_task_pidinfo_t") {
|
||||
jobid @0: UInt64 $C.mapname("jobid");
|
||||
host @1: Text $C.mapname("host");
|
||||
taskidx @2: Int32 $C.mapname("taskidx");
|
||||
pids @3: List(UInt32) $C.mapname("pids") $C.maplistcount("npids");
|
||||
pgids @4: List(UInt32) $C.mapname("pgids") $C.maplistcount("npgids");
|
||||
exdata @5: Text $C.mapname("exdata");
|
||||
clientidx @6: UInt32 $C.mapname("clientidx");
|
||||
}
|
||||
|
||||
struct TaskFailInfo $C.mapname("xce_task_failinfo_t") {
|
||||
jobid @0: UInt64 $C.mapname("jobid");
|
||||
host @1: Text $C.mapname("host");
|
||||
taskidx @2: Int32 $C.mapname("taskidx");
|
||||
code @3: Int32 $C.mapname("code");
|
||||
detail @4: Text $C.mapname("detail");
|
||||
clientidx @5: Int32 $C.mapname("clientidx");
|
||||
}
|
||||
|
||||
struct TaskFinish $C.mapname("xce_task_finish_t") {
|
||||
jobid @0: UInt64 $C.mapname("jobid");
|
||||
host @1: Text $C.mapname("host");
|
||||
taskidx @2: UInt32 $C.mapname("taskidx");
|
||||
exitcode @3: Int32 $C.mapname("exit_code");
|
||||
clientidx @4: Int32 $C.mapname("clientidx");
|
||||
}
|
||||
|
||||
struct NotifyData $C.mapname("xce_notify_data_t"){
|
||||
data :union $C.mapuniontag("event") $C.mapname("data"){
|
||||
jobPidInfo @0: JobPIDInfo $C.mapname("pidinfo");
|
||||
jobFailInfo @1: JobFail $C.mapname("failinfo");
|
||||
jobDispatchFail @2: JobFail $C.mapname("dispatchfail");
|
||||
jobFinishInfo @3: JobFinishInfo $C.mapname("finishinfo");
|
||||
schedStartJob @4: UInt64 $C.mapname("sched_start_job");
|
||||
schedExitJob @5: UInt64 $C.mapname("sched_exit_job");
|
||||
schedFailJob @6: UInt64 $C.mapname("sched_fail_job");
|
||||
schedUpdateJob @7: SchedJob $C.mapname("sched_update_job");
|
||||
schedUpdateResvals @8: ResValList $C.mapname("sched_update_resvals");
|
||||
stoppedJob @9: UInt64 $C.mapname("stopped_job");
|
||||
resumedJob @10: UInt64 $C.mapname("resumed_job");
|
||||
ckptinfo @11: CheckpointInfo $C.mapname("ckptinfo");
|
||||
schedUpdateQueue @12: QueueConf $C.mapname("sched_update_queue");
|
||||
taskPidInfo @13: TaskPidInfo $C.mapname("taskinfo");
|
||||
taskFailInfo @14: TaskFailInfo $C.mapname("taskfailinfo");
|
||||
taskFinish @15: TaskFinish $C.mapname("taskfinish");
|
||||
postDoneJob @16: UInt64 $C.mapname("pdone_job");
|
||||
}
|
||||
}
|
||||
|
||||
struct ClusterConf $C.mapname("xce_clusterconf_t") {
|
||||
name @0: Text;
|
||||
resources @1: List(Resource) $C.mapname("reslist.res") $C.maplistcount("reslist.count");
|
||||
queues @2: List(QueueConf) $C.mapname("qlist.queues") $C.maplistcount("qlist.count");
|
||||
workers @3: List(Worker) $C.mapname("wlist.workers") $C.maplistcount("wlist.count");
|
||||
}
|
||||
|
||||
struct JobSubmit $C.mapname("xce_job_submit_t") {
|
||||
queue @0: Text;
|
||||
user @1: Text;
|
||||
cmdline @2: Text;
|
||||
resreq @3: Text;
|
||||
exdata @4: Text;
|
||||
mintasks @5: UInt32;
|
||||
maxtasks @6: UInt32;
|
||||
}
|
||||
|
||||
struct JobSignal $C.mapname("xce_signal_t") {
|
||||
signo @0: UInt32 $C.mapname("signo");
|
||||
force @1: Int32 $C.mapname("force");
|
||||
}
|
||||
|
||||
struct CheckpointOptions $C.mapname("xce_ckpt_options_t"){
|
||||
kill @0: UInt32 $C.mapname("kill");
|
||||
method @1: Text $C.mapname("method");
|
||||
}
|
||||
|
||||
struct CheckpointInfo $C.mapname("xce_ckptinfo_t") {
|
||||
jobid @0: UInt64;
|
||||
ckptinfo @1: Text;
|
||||
}
|
||||
|
||||
struct JobControl $C.mapname("xce_jobctrl_t") {
|
||||
jobid @0: UInt64 $C.mapname("jobid");
|
||||
u :union $C.mapuniontag("action") $C.mapname("u") {
|
||||
siginfo @1: JobSignal;
|
||||
ckptoption @2: CheckpointOptions;
|
||||
}
|
||||
}
|
||||
|
||||
struct QueueControl $C.mapname("xce_queuectrl_t") {
|
||||
action @0: UInt32 $C.mapname("action");
|
||||
queue @1: Text $C.mapname("queue");
|
||||
}
|
||||
|
||||
struct RequestReply $C.mapname("xce_reply_t"){
|
||||
seq @0: UInt64;
|
||||
opcode @1: OPCode;
|
||||
status @2: Int32;
|
||||
|
||||
data : union {
|
||||
nodata @3: Void;
|
||||
debugmsg @4: Text;
|
||||
getdata @5: Data;
|
||||
jobid @6: UInt64;
|
||||
clusterconf @7: ClusterConf;
|
||||
}
|
||||
}
|
||||
|
||||
struct TaskHost $C.mapname("xce_taskhost_t") {
|
||||
host @0: Text;
|
||||
ntasks @1: UInt32;
|
||||
exechome @2: Text;
|
||||
execcwd @3: Text;
|
||||
execuser @4: Text;
|
||||
cmdline @5: Text;
|
||||
exdata @6: Text;
|
||||
launchtype @7: Text $C.mapname("launch_type");
|
||||
}
|
||||
|
||||
struct RunTask $C.mapname("xce_taskrun_t") {
|
||||
clientidx @0: Int32 $C.mapname("clientidx");
|
||||
hosts @1: List(TaskHost) $C.mapname("taskhosts") $C.maplistcount("nhosts");
|
||||
jobid @2: UInt64 $C.mapname("jobid");
|
||||
}
|
||||
|
||||
struct Request $C.mapname("xce_request_t"){
|
||||
opcode @0: OPCode;
|
||||
seq @1: UInt64;
|
||||
from @2: PeerInfo;
|
||||
body : union {
|
||||
nomsg @3: Void;
|
||||
replymsg @4: RequestReply;
|
||||
hellomsg @5: Text;
|
||||
joinmsg @6: JoinData;
|
||||
configpushmsg @7: ConfigData;
|
||||
pushmsg @8: Data;
|
||||
getmsg @9: Get;
|
||||
datamsg @10: Dataset;
|
||||
dispatchmsg @11: JobDispatch;
|
||||
jobstartmsg @12: JobExecInfo;
|
||||
notifymsg @13: NotifyData;
|
||||
jobsubmsg @14: JobSubmit;
|
||||
updatemsg @15: Update;
|
||||
jobctrlmsg @16: JobControl;
|
||||
queuectrlmsg @17: QueueControl;
|
||||
runtaskmsg @18: RunTask;
|
||||
}
|
||||
}
|
||||
|
||||
struct HashZArrayConfig $C.mapname("hash_zarray_config_t") {
|
||||
nHashSlots @0: UInt32 $C.mapname("nhash_slots");
|
||||
delta @1: UInt32 $C.mapname("delta");
|
||||
}
|
||||
|
||||
struct ResmgrConfig $C.mapname("resmgr_config_t") {
|
||||
nHashSlots @0: UInt32 $C.mapname("nhash_slots");
|
||||
delta @1: UInt32 $C.mapname("delta");
|
||||
instDelta @2: UInt32 $C.mapname("inst_delta");
|
||||
}
|
||||
|
||||
struct MasterCandidate $C.mapname("master_candidate_t") {
|
||||
name @0: Text $C.mapname("name");
|
||||
host @1: Text $C.mapname("host");
|
||||
port @2: UInt32 $C.mapname("port");
|
||||
}
|
||||
|
||||
struct HostConfig $C.mapname("xce_hostconfig_t") {
|
||||
name @0: Text $C.mapname("name");
|
||||
model @1: Text $C.mapname("hostmodel");
|
||||
type @2: Text $C.mapname("hosttype");
|
||||
mxj @3: UInt32 $C.mapname("mxj");
|
||||
resources @4: List(ConfigVar) $C.mapname("resources") $C.maplistcount("nresources");
|
||||
thresholds @5: List(Threshold) $C.mapname("thresholds") $C.maplistcount("nthresholds");
|
||||
dispatchwindows @6: TimeWindow $C.mapname("dispatchwindow");
|
||||
}
|
||||
|
||||
struct ClusterConfig $C.mapname("cluster_config_t") {
|
||||
clusterName @0: Text $C.mapname("clustername");
|
||||
port @1: UInt32 $C.mapname("port");
|
||||
candidates @2: List(MasterCandidate) $C.mapname("candidates") $C.maplistcount("ncandidates");
|
||||
heartbeatInterval @3: UInt32 $C.mapname("heartbeat_interval");
|
||||
inactiveHeartbeatCount @4: UInt32 $C.mapname("inactive_heartbeat_count");
|
||||
fetchJobInterval @5: UInt32 $C.mapname("fetch_job_interval");
|
||||
netioTimeout @6: UInt32 $C.mapname("netio_timeout");
|
||||
vcpus @7: UInt32 $C.mapname("vcpus");
|
||||
resources @8: List(Resource) $C.mapname("resources") $C.maplistcount("nres");
|
||||
queues @9: List(QueueConf) $C.mapname("queues") $C.maplistcount("nqueues");
|
||||
ugroups @10: List(Group) $C.mapname("ugroups") $C.maplistcount("nugroups");
|
||||
hgroups @11: List(Group) $C.mapname("hgroups") $C.maplistcount("nhgroups");
|
||||
hostConfigs @12: List(HostConfig) $C.mapname("hconfigs") $C.maplistcount("nhconfigs");
|
||||
jobmgr @13: HashZArrayConfig;
|
||||
workermgr @14: HashZArrayConfig;
|
||||
qmgr @15: HashZArrayConfig;
|
||||
resmgr @16: ResmgrConfig;
|
||||
xstrings @17: HashZArrayConfig;
|
||||
}
|
||||
2501
src/unity/unity.c
Normal file
2501
src/unity/unity.c
Normal file
File diff suppressed because it is too large
Load diff
698
src/unity/unity.h
Normal file
698
src/unity/unity.h
Normal file
|
|
@ -0,0 +1,698 @@
|
|||
/* =========================================================================
|
||||
Unity - A Test Framework for C
|
||||
ThrowTheSwitch.org
|
||||
Copyright (c) 2007-24 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
||||
SPDX-License-Identifier: MIT
|
||||
========================================================================= */
|
||||
|
||||
#ifndef UNITY_FRAMEWORK_H
|
||||
#define UNITY_FRAMEWORK_H
|
||||
#define UNITY
|
||||
|
||||
#define UNITY_VERSION_MAJOR 2
|
||||
#define UNITY_VERSION_MINOR 6
|
||||
#define UNITY_VERSION_BUILD 0
|
||||
#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "unity_internals.h"
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Test Setup / Teardown
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
/* These functions are intended to be called before and after each test.
|
||||
* If using unity directly, these will need to be provided for each test
|
||||
* executable built. If you are using the test runner generator and/or
|
||||
* Ceedling, these are optional. */
|
||||
void setUp(void);
|
||||
void tearDown(void);
|
||||
|
||||
/* These functions are intended to be called at the beginning and end of an
|
||||
* entire test suite. suiteTearDown() is passed the number of tests that
|
||||
* failed, and its return value becomes the exit code of main(). If using
|
||||
* Unity directly, you're in charge of calling these if they are desired.
|
||||
* If using Ceedling or the test runner generator, these will be called
|
||||
* automatically if they exist. */
|
||||
void suiteSetUp(void);
|
||||
int suiteTearDown(int num_failures);
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Test Reset and Verify
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
/* These functions are intended to be called before during tests in order
|
||||
* to support complex test loops, etc. Both are NOT built into Unity. Instead
|
||||
* the test runner generator will create them. resetTest will run teardown and
|
||||
* setup again, verifying any end-of-test needs between. verifyTest will only
|
||||
* run the verification. */
|
||||
void resetTest(void);
|
||||
void verifyTest(void);
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Configuration Options
|
||||
*-------------------------------------------------------
|
||||
* All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above.
|
||||
|
||||
* Integers/longs/pointers
|
||||
* - Unity attempts to automatically discover your integer sizes
|
||||
* - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in <stdint.h>
|
||||
* - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in <limits.h>
|
||||
* - If you cannot use the automatic methods above, you can force Unity by using these options:
|
||||
* - define UNITY_SUPPORT_64
|
||||
* - set UNITY_INT_WIDTH
|
||||
* - set UNITY_LONG_WIDTH
|
||||
* - set UNITY_POINTER_WIDTH
|
||||
|
||||
* Floats
|
||||
* - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons
|
||||
* - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT
|
||||
* - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats
|
||||
* - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
|
||||
* - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default)
|
||||
* - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE
|
||||
* - define UNITY_DOUBLE_TYPE to specify something other than double
|
||||
* - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors
|
||||
|
||||
* Output
|
||||
* - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
|
||||
* - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure
|
||||
|
||||
* Optimization
|
||||
* - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge
|
||||
* - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests.
|
||||
|
||||
* Test Cases
|
||||
* - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script
|
||||
|
||||
* Parameterized Tests
|
||||
* - you'll want to create a define of TEST_CASE(...), TEST_RANGE(...) and/or TEST_MATRIX(...) which basically evaluates to nothing
|
||||
|
||||
* Tests with Arguments
|
||||
* - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity
|
||||
|
||||
*-------------------------------------------------------
|
||||
* Basic Fail and Ignore
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message))
|
||||
#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL)
|
||||
#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message))
|
||||
#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL)
|
||||
#define TEST_MESSAGE(message) UnityMessage((message), __LINE__)
|
||||
#define TEST_ONLY()
|
||||
#ifdef UNITY_INCLUDE_PRINT_FORMATTED
|
||||
#define TEST_PRINTF(message, ...) UnityPrintF(__LINE__, (message), ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails.
|
||||
* This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */
|
||||
#define TEST_PASS() TEST_ABORT()
|
||||
#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while (0)
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Build Directives
|
||||
*-------------------------------------------------------
|
||||
|
||||
* These macros do nothing, but they are useful for additional build context.
|
||||
* Tools (like Ceedling) can scan for these directives and make use of them for
|
||||
* per-test-executable #include search paths and linking. */
|
||||
|
||||
/* Add source files to a test executable's compilation and linking. Ex: TEST_SOURCE_FILE("sandwiches.c") */
|
||||
#define TEST_SOURCE_FILE(a)
|
||||
|
||||
/* Customize #include search paths for a test executable's compilation. Ex: TEST_INCLUDE_PATH("src/module_a/inc") */
|
||||
#define TEST_INCLUDE_PATH(a)
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Test Asserts (simple)
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
/* Boolean */
|
||||
#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE")
|
||||
#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE")
|
||||
#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE")
|
||||
#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE")
|
||||
#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL")
|
||||
#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL")
|
||||
#define TEST_ASSERT_EMPTY(pointer) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, " Expected Empty")
|
||||
#define TEST_ASSERT_NOT_EMPTY(pointer) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, " Expected Non-Empty")
|
||||
|
||||
/* Integers (of all sizes) */
|
||||
#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(-1), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(0), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(-1), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(0), (actual), __LINE__, NULL)
|
||||
|
||||
/* Integer Not Equal To (of all sizes) */
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
|
||||
|
||||
/* Integer Greater Than/ Less Than (of all sizes) */
|
||||
#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
|
||||
|
||||
#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
|
||||
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
|
||||
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
|
||||
|
||||
/* Integer Ranges (of all sizes) */
|
||||
#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_size_t_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
|
||||
/* Integer Array Ranges (of all sizes) */
|
||||
#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
|
||||
|
||||
|
||||
/* Structs and Strings */
|
||||
#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL)
|
||||
|
||||
/* Arrays */
|
||||
#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
|
||||
/* Arrays Compared To Single Value */
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
|
||||
/* Floating Point (If Enabled) */
|
||||
#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
|
||||
|
||||
/* Double (If Enabled) */
|
||||
#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
|
||||
|
||||
/* Shorthand */
|
||||
#ifdef UNITY_SHORTHAND_AS_OLD
|
||||
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_INT
|
||||
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_MEM
|
||||
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL)
|
||||
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_RAW
|
||||
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal")
|
||||
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_NONE
|
||||
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Test Asserts (with additional messages)
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
/* Boolean */
|
||||
#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message))
|
||||
#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message))
|
||||
#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message))
|
||||
#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message))
|
||||
#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message))
|
||||
#define TEST_ASSERT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, (message))
|
||||
|
||||
/* Integers (of all sizes) */
|
||||
#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message))
|
||||
|
||||
/* Integer Not Equal To (of all sizes) */
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
|
||||
|
||||
|
||||
/* Integer Greater Than/ Less Than (of all sizes) */
|
||||
#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message))
|
||||
|
||||
#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message))
|
||||
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
|
||||
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
|
||||
|
||||
/* Integer Ranges (of all sizes) */
|
||||
#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_size_t_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
|
||||
/* Integer Array Ranges (of all sizes) */
|
||||
#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
|
||||
|
||||
|
||||
/* Structs and Strings */
|
||||
#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message))
|
||||
|
||||
/* Arrays */
|
||||
#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
|
||||
/* Arrays Compared To Single Value*/
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, (message))
|
||||
|
||||
/* Floating Point (If Enabled) */
|
||||
#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message))
|
||||
|
||||
/* Double (If Enabled) */
|
||||
#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message))
|
||||
|
||||
/* Shorthand */
|
||||
#ifdef UNITY_SHORTHAND_AS_OLD
|
||||
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message))
|
||||
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message))
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_INT
|
||||
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
|
||||
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_MEM
|
||||
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message)
|
||||
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_RAW
|
||||
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message)
|
||||
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message)
|
||||
#endif
|
||||
#ifdef UNITY_SHORTHAND_AS_NONE
|
||||
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
|
||||
#endif
|
||||
|
||||
/* end of UNITY_FRAMEWORK_H */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
1183
src/unity/unity_internals.h
Normal file
1183
src/unity/unity_internals.h
Normal file
File diff suppressed because it is too large
Load diff
56
src/xce.nix
Normal file
56
src/xce.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
lib,
|
||||
stdenv,
|
||||
pkgs,
|
||||
myCommitId,
|
||||
withDebug? false,
|
||||
withAsan? false,
|
||||
withoutDb? false,
|
||||
...
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
|
||||
pname = "xce";
|
||||
version = "0.0.1";
|
||||
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkgs.meson
|
||||
pkgs.ninja
|
||||
pkgs.capnproto
|
||||
pkgs.pkg-config
|
||||
pkgs.cmake
|
||||
pkgs.go
|
||||
pkgs.openssl
|
||||
pkgs.libtirpc
|
||||
pkgs.readline
|
||||
pkgs.ncurses
|
||||
pkgs.capnpc
|
||||
pkgs.which
|
||||
pkgs.findutils
|
||||
pkgs.libuv
|
||||
pkgs.elogind
|
||||
pkgs.sqlite
|
||||
pkgs.hwloc
|
||||
pkgs.linux-pam
|
||||
pkgs.zlog_with_pkgconf
|
||||
pkgs.unity-test
|
||||
];
|
||||
|
||||
build-system = [ pkgs.meson ];
|
||||
|
||||
dontStrip = (withDebug || withAsan);
|
||||
separateDebugInfo = (withDebug || withAsan);
|
||||
|
||||
impureEnvVars = [ "HOME" ];
|
||||
|
||||
mesonFlags =[
|
||||
(lib.optional withDebug "-Dwith_debug=true")
|
||||
(lib.optional withAsan "-Db_sanitize=address")
|
||||
(lib.optional withoutDb "-Dwithout_db=true")
|
||||
("-Dcommit_id=" + myCommitId)
|
||||
# (lib.optional (!with_debug) "-Dbuildtype=release")
|
||||
];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue