型とマクロ定義


/*
 * 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))