型とマクロ定義
/*
* PM Related Constants
*/
#define PM_MAX_NODE 1024 /* Maximum # of nodes */
#define PM_MAX_TYPE_LEN 64 /* Maximum type length */
#define PM_MIN_MTU 1400 /* Minimum MTU */
#define PM_MIN_FD (FD_SETSIZE / 2) /* Lower bound of PM fds */
#define PM_SUCCESS 0 /* Return for success */
/*
* PM Type
*/
#define PM_UNKNOWN "unknown"
#define PM_COMPOSITE "composite" /* Composite context */
#define PM_MYRINET "myrinet" /* Myrinet */
#define PM_MYRINET2K "myrinet2k" /* Myrinet */
#define PM_ETHERNET "ethernet" /* Ethernet */
#define PM_UDP "udp" /* UDP (obsolete) */
#define PM_SHMEM "shmem" /* Shared Memory */
#define PM_RHINET "rhinet" /* RHiNET */
#define PM_AGENT "agent" /* Agent */
/*
* PM Device Configuration
*/
typedef struct pm_device_config {
const char *type; /* Type of device */
int channels; /* Number of channels */
int contexts; /* Number of contexts */
int nodes; /* Number of nodes */
unsigned long option; /* Supported options */
} pmDeviceConfig;
/*
* PM Context Configuration
*/
typedef struct pm_context_config {
const char *type; /* Type of context */
int number; /* Context number */
int nodes; /* Number of nodes */
size_t mtu; /* Minimum MTU */
size_t size; /* Size of context */
unsigned long option; /* Supported options */
} pmContextConfig;
#define PM_OPT_MULTICAST 0x0001 /* "multicast" */
#define PM_OPT_REMOTE_WRITE 0x0002 /* "remote_write" */
#define PM_OPT_REMOTE_READ 0x0004 /* "remote_read" */
#define PM_OPT_CHECKPOINT 0x0008 /* "checkpoint" */
#define PM_OPT_MIGRATE 0x0010 /* "migrate" */
#define PM_OPT_GLOBAL_CLOCK 0x0020 /* "global_clock" */
#define PM_OPT_CONTEXT_SHARE 0x0040 /* "context_share" */
/*
* Message Queue Status
*/
typedef struct pm_message_queue_status {
int receive; /* Received messages in queue */
int send; /* Sending messages in queue */
int read; /* There are outstanding remote reads */
} pmMessageQueueStatus;
/*
* Mmap Information
*/
typedef struct pm_mmap_info {
caddr_t addr; /* Start address */
size_t length; /* Length of region */
int prot; /* Protection */
int flags; /* Flags */
off_t offset; /* Offset in file */
int fd; /* File descriptor */
} pmMmapInfo;
/*
* Locked Address Handle
*/
typedef unsigned long long pmAddrHandle;
typedef pmAddrHandle pmAddr; /* For compatibility */
/*
* PM Device
*/
typedef struct pm_device pmDevice;
typedef struct pm_context pmContext;
typedef struct pm_page_map pmPageMap;
typedef struct pm_device_ops {
int (*close)(pmDevice *);
int (*get_config)(pmDevice *, pmDeviceConfig *);
int (*get_node_list)(pmDevice *, const char ***, int *);
int (*is_reachable)(pmDevice *, const char *);
int (*open_context)(pmDevice *, int, pmContext **);
} pmDeviceOps;
struct pm_device {
pmContext *head;
pmContext *tail;
pmDeviceOps ops;
};
#define pmCloseDevice(pmd) ((*(pmd)->ops.close)(pmd))
#define pmGetDeviceConfig(pmd, cnfp) ((*(pmd)->ops.get_config)(pmd, cnfp))
#define pmGetNodeList(pmd, nodep, nnodep) \
((*(pmd)->ops.get_node_list)(pmd, nodep, nnodep))
#define pmIsReachable(pmd, node) ((*(pmd)->ops.is_reachable)(pmd, node))
#define pmOpenContext(pmd, ctx, pmcp) \
((*(pmd)->ops.open_context)(pmd, ctx, pmcp))
/*
* PM Context
*/
typedef struct pm_context_header {
pmContext *forw;
pmContext *back;
} pmContextHeader;
typedef struct pm_context_ops {
int (*reset)(pmContext *);
int (*close)(pmContext *);
int (*bind_channel)(pmContext *, int);
int (*unbind_channel)(pmContext *);
int (*associate_nodes)(pmContext *, const char **, int);
int (*get_config)(pmContext *, pmContextConfig *);
int (*control_send)(pmContext *, int);
int (*is_send_stable)(pmContext *);
int (*save)(pmContext *, caddr_t);
int (*restore)(pmContext *, caddr_t);
int (*create_attach_fd)(pmContext *, int *);
int (*close_attach_fd)(pmContext *);
int (*detach)(pmContext *);
int (*add_node)(pmContext *, int, pmContext *, int);
int (*remove_node)(pmContext *, int);
int (*extract_node)(pmContext *, int, pmContext **, int *);
int (*get_fd)(pmContext *, int *, int *);
int (*get_mtu)(pmContext *, int, size_t *);
int (*get_self)(pmContext *, int *);
int (*control_receive)(pmContext *, int);
int (*receive)(pmContext *, caddr_t *, size_t *);
int (*release_receive_buffer)(pmContext *);
int (*get_send_buffer)(pmContext *, int, caddr_t *, size_t);
int (*get_multicast_buffer)(pmContext *, int *, int, caddr_t *, size_t);
int (*truncate_buffer)(pmContext *, size_t);
int (*send)(pmContext *);
int (*is_send_done)(pmContext *);
int (*get_message_queue_status)(pmContext *, pmMessageQueueStatus *);
int (*before_select)(pmContext *);
int (*after_select)(pmContext *);
int (*mlock)(pmContext *, caddr_t, size_t, pmAddrHandle *);
int (*munlock)(pmContext *, caddr_t, size_t);
int (*write)(pmContext *, int, pmAddrHandle, pmAddrHandle, size_t);
int (*is_write_done)(pmContext *);
int (*read)(pmContext *, int, pmAddrHandle, pmAddrHandle, size_t);
int (*is_read_done)(pmContext *);
int (*set_page_map)(pmContext *, pmPageMap *);
int (*set_map)(pmContext *, caddr_t, size_t, int, pmAddrHandle);
int (*time_request)(pmContext *, int);
int (*time_wait)(pmContext *, double *);
int (*set_time_parameter)(pmContext *);
int (*set_time_offset)(pmContext *);
int (*get_time)(pmContext *, double *, double *);
int (*checkpoint)(pmContext *, void (*)(void *, int), void *);
int (*restart_sys)(pmContext *);
int (*restart_user)(pmContext *);
int (*migrate_sys)(pmContext *);
int (*migrate_user)(pmContext *);
void (*dump)(pmContext *, FILE *);
} pmContextOps;
struct pm_context {
pmContextHeader brother;
pmContext *parent;
pmContextHeader link;
pmDevice *device;
int ref_count;
int use_count;
size_t size;
pmContextOps ops;
};
#define pmResetContext(pmc) ((*(pmc)->ops.reset)(pmc))
#define pmCloseContext(pmc) ((*(pmc)->ops.close)(pmc))
#define pmBindChannel(pmc, chan) ((*(pmc)->ops.bind_channel)(pmc, chan))
#define pmUnbindChannel(pmc) ((*(pmc)->ops.unbind_channel)(pmc))
#define pmAssociateNodes(pmc, nodes, nnode) \
((*(pmc)->ops.associate_nodes)(pmc, nodes, nnode))
#define pmGetContextConfig(pmc, cnfp) ((*(pmc)->ops.get_config)(pmc, cnfp))
#define pmControlSend(pmc, enable) \
((*(pmc)->ops.control_send)(pmc, enable))
#define pmIsSendStable(pmc) ((*(pmc)->ops.is_send_stable)(pmc))
#define pmSaveContext(pmc, addr) ((*(pmc)->ops.save)(pmc, addr))
#define pmRestoreContext(pmc, addr) ((*(pmc)->ops.restore)(pmc, addr))
#define pmCreateAttachFd(pmc, fdp) \
((*(pmc)->ops.create_attach_fd)(pmc, fdp))
#define pmCloseAttachFd(pmc) ((*(pmc)->ops.close_attach_fd)(pmc))
#define pmDetachContext(pmc) ((*(pmc)->ops.detach)(pmc))
#define pmAddNode(pmc, node, member_pmc, member_node) \
((*(pmc)->ops.add_node)(pmc, node, member_pmc, member_node))
#define pmRemoveNode(pmc, node) \
((*(pmc)->ops.remove_node)(pmc, node))
#define pmExtractNode(pmc, node, member_pmcp, member_nodep) \
((*(pmc)->ops.extract_node)(pmc, node, member_pmcp, member_nodep))
#define pmGetFd(pmc, fdp, nfd) ((*(pmc)->ops.get_fd)(pmc, fdp, nfd))
#define pmGetMtu(pmc, node, mtup) ((*(pmc)->ops.get_mtu)(pmc, node, mtup))
#define pmGetSelf(pmc, selfp) ((*(pmc)->ops.get_self)(pmc, selfp))
#define pmControlReceive(pmc, enable) \
((*(pmc)->ops.control_receive)(pmc, enable))
#define pmReceive(pmc, bufp, lenp) ((*(pmc)->ops.receive)(pmc, bufp, lenp))
#define pmReleaseReceiveBuffer(pmc) \
((*(pmc)->ops.release_receive_buffer)(pmc))
#define pmGetSendBuffer(pmc, node, bufp, len) \
((*(pmc)->ops.get_send_buffer)(pmc, node, bufp, len))
#define pmGetMulticastBuffer(pmc, nodes, nnode, bufp, len) \
((*(pmc)->ops.get_multicast_buffer)(pmc, nodes, nnode, bufp, len))
#define pmTruncateBuffer(pmc, len) \
((*(pmc)->ops.truncate_buffer)(pmc, len))
#define pmSend(pmc) ((*(pmc)->ops.send)(pmc))
#define pmIsSendDone(pmc) ((*(pmc)->ops.is_send_done)(pmc))
#define pmGetMessageQueueStatus(pmc, pmsp) \
((*(pmc)->ops.get_message_queue_status)(pmc, pmsp))
#define pmBeforeSelect(pmc) ((*(pmc)->ops.before_select)(pmc))
#define pmAfterSelect(pmc) ((*(pmc)->ops.after_select)(pmc))
#define pmMLock(pmc, addr, len, pmap) \
((*(pmc)->ops.mlock)(pmc, addr, len, pmap))
#define pmMUnlock(pmc, addr, len) ((*(pmc)->ops.munlock)(pmc, addr, len))
#define pmWrite(pmc, remote, rpma, lpma, len) \
((*(pmc)->ops.write)(pmc, remote, rpma, lpma, len))
#define pmIsWriteDone(pmc) ((*(pmc)->ops.is_write_done)(pmc))
#define pmRead(pmc, remote, rpma, lpma, len) \
((*(pmc)->ops.read)(pmc, remote, rpma, lpma, len))
#define pmIsReadDone(pmc) ((*(pmc)->ops.is_read_done)(pmc))
#define pmSetPageMap(pmc, map) ((*(pmc)->ops.set_page_map)(pmc, map))
#define pmSetMap(pmc, addr, size, flag, hndl) \
((*(pmc)->ops.set_map)(pmc, addr, size, flag, hndl))
#define pmTimeRequest(pmc, dest) ((*(pmc)->ops.time_request)(pmc, dest))
#define pmTimeWait(pmc, timep) ((*(pmc)->ops.time_wait)(pmc, timep))
#define pmSetTimeParameter(pmc) ((*(pmc)->ops.set_time_parameter)(pmc))
#define pmSetTimeOffset(pmc) ((*(pmc)->ops.set_time_offset)(pmc))
#define pmGetTime(pmc, timep, offsetp) \
((*(pmc)->ops.get_time)(pmc, timep, offsetp))
#define pmCheckpoint(pmc, callback, arg) \
((*(pmc)->ops.checkpoint)(pmc, callback, arg))
#define pmRestartSys(pmc) ((*(pmc)->ops.restart_sys)(pmc))
#define pmRestartUser(pmc) ((*(pmc)->ops.restart_user)(pmc))
#define pmMigrateSys(pmc) ((*(pmc)->ops.migrate_sys)(pmc))
#define pmMigrateUser(pmc) ((*(pmc)->ops.migrate_user)(pmc))
#define pmDumpContext(pmc, file) ((*(pmc)->ops.dump)(pmc, file))
/*
* Alignment Macros for Remote Memory Access
*/
#define PM_DMA_ALIGN 4
#define PM_RMA_ROUND(x) ((x) & ~(PM_DMA_ALIGN-1))
#define PM_RMA_ADDRESS_ALIGN(x) PM_RMA_ROUND(x)
#define PM_RMA_LENGTH_ALIGN(x) PM_RMA_ROUND((x) + (PM_DMA_ALIGN-1))
/*
* Global Functions
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int pmGetTypeList(const char ***, int *);
int pmOpenDevice(const char *, int, char **, pmDevice **);
int pmAttachContext(const char *, int, pmContext **);
int pmGetOptionBit(const char *, unsigned long *);
int pmGetMmapInfo(pmMmapInfo *, int *);
int pmCacheSize(size_t);
void pmSetDebug(int, FILE *);
void pmDebug(int, const char *, ...);
extern const char *pmErrorString(int);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define PM_NODEBUG 0 /* No debug messages are printed*/
#define PM_ERROR 1 /* Error messages only */
#define PM_WARNING 2 /* Error and Warning msgs. */
#define PM_INFO 3 /* Error, Warning and info. msgs */
/*
* Obsolete Functions
*/
#define PMC_DONT_POLL 0x1 /* Not to poll this context */
#define pmSetContextFlag(pmc, f) \
(pmControlReceive(pmc, ((f) & PMC_DONT_POLL) == 0))