Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

These are currently defined memory operations for redo and undo, it is quite different with what PMDK provided. Because WAL size is going to be critical, instead of coping all data bytes into WAL, umem defines different operations like MOVE and SET to describe memory operation behavior, instead of save its actual content. For example, MOVE is defined for memmove(), data content is already in-place before the move, there is no necessity to copy the data into WAL.

Code Block
/* Type of memory actions */
enum {
        UMEM_ACT_NOOP                   = 0,
        /** copy appended payload to specified storage address */
        UMEM_ACT_COPY,
        /** copy payload addressed by @ptr to specified storage address */
        UMEM_ACT_COPY_PTR,
        /** assign 8/16/32/64 bits integer to specified storage address */
        UMEM_ACT_ASSIGN,
        /** move specified bytes from source address to destination address */
        UMEM_ACT_MOVE,
        /** memset a region with specified value */
        UMEM_ACT_SET,
        /** set the specified bit in bitmap */
        UMEM_ACT_SET_BITS,
        /** unset the specified bit in bitmap */
        UMEM_ACT_CLR_BITS,
        /** it's checksum of the specified address */
        UMEM_ACT_CSUM,
};

Each umem_action can describe a memory operation and its parameters, some simple operations, e.g., set/clear bitmap and integer assignment, can fit into 16 bytes, other operations requires at least 32 bytes to describe the behavior and parameters.

Code Block
/**
 * Memory operations for redo/undo.
 * 16 bytes for bit operation (set/clr) and integer assignment, 32+ bytes for
 * other operations.
 */
struct umem_action {
        uint16_t                        ac_opc;
        union {
                struct {
                        uint64_t                addr;
                        uint64_t                size;
                        uint8_t                 payload[0];
                } ac_copy;      /**< copy payload from @payload to @addr */
                struct {
                        uint64_t                addr;
                        uint64_t                size;
                        uint64_t                ptr;
                } ac_copy_ptr;  /**< copy payload from @ptr to @addr */
                struct {
                        uint16_t                size;
                        uint32_t                val;
                        uint64_t                addr;
                } ac_assign;    /**< assign integer to @addr, int64 should use ac_copy */
                struct {
                        uint16_t                num;
                        uint32_t                pos;
                        uint64_t                bmap;
                } ac_op_bits;   /**< set or clear the @pos bit in bitmap @bmap */
                struct {
                        uint16_t                val;
                        uint32_t                size;
                        uint64_t                addr;
                } ac_set;       /**< memset(addr, val, size) */
                struct {
                        uint16_t                pad16;
                        uint32_t                size;
                        uint64_t                src;
                        uint64_t                dst;
                } ac_move;      /**< memmove(dst, size src) */
                struct {
                        uint16_t                csum_sz;
                        uint32_t                size;
                        uint64_t                addr;
                        uint8_t                 csum[0];
                } ac_csum;      /**< it is checksum of data stored in @addr */
        };
};