1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
#ifndef SERVICE_H
#define SERVICE_H
#include <vumodule.h>
#include <hashtable.h>
/* each module define a service.
services are registered in the hashtable (he key is the module name */
struct vuht_entry_t;
#if __STDC_VERSION__ >= 202000L
typedef long (*syscall_t)(...);
#else
typedef long (*syscall_t)();
#endif
struct vu_service_t {
// pointer to a static structure named "vu_module" defined in the module
// this structure defines the name and a short description of the module
// the presence of such a structure is used as a test (that the module
// has been designed for vuos).
struct vu_module_t *mod;
// modules are loaded as dynamic library plug-ins.
// this is the handle returned by dl_open
void *dlhandle;
// the hash table pointer of the service itself
struct vuht_entry_t *service_ht;
// private data of the module (modules can use this pointer as they please.
void *private;
// table of vu_syscalls implementation.
syscall_t module_syscall[];
};
struct vuht_entry_t *vu_mod_getht(void);
/* A static thread variable records the module hash table element chosen by the hypervisor,
so that the module can access it */
void vu_mod_setht(struct vuht_entry_t *ht);
/* hash table and epoch wrapper:
* set the ht and epoch to run a service_syscall and then
* restore the previous value.
* usage:
* VU_HTWRAP(ht, ret_value = service_syscall(ht, __VU_xxxx)(arg0, arg1...));
*/
#define VU_HTWRAP(HT, X) \
do { \
struct vuht_entry_t *__sht = vu_mod_getht(); \
epoch_t __e = get_vepoch(); \
vu_mod_setht(HT); \
set_vepoch(vuht_get_vepoch(HT)); \
(X); \
set_vepoch(__e); \
vu_mod_setht(__sht); \
} while(0)
/* inline function: it is here for performance.
it returns the pointer of the syscall implementation....
an example of this inline usage is:
retval = service_syscall(ht, __VU_read)(fd, buf, buflen);
*/
__attribute__((always_inline))
static inline syscall_t service_syscall(struct vuht_entry_t *ht, int vu_syscall_number) {
struct vu_service_t *service = vuht_get_service(ht);
return service->module_syscall[vu_syscall_number];
}
/* inline function: it is here for performance.
it returns the flags of the module */
__attribute__((always_inline))
static inline uint64_t service_getflags(struct vuht_entry_t *ht) {
return ht ? vuht_get_service(ht)->mod->flags : 0;
}
#endif
|