// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/rdb.c
// Function: rdbSaveBackground
int rdbSaveBackground(char *filename) {
    pid_t childpid;
    long long start;

    // 如果 BGSAVE 已经在执行，那么出错
    if (server.rdb_child_pid != -1) return REDIS_ERR;

    // 记录 BGSAVE 执行前的数据库被修改次数
    server.dirty_before_bgsave = server.dirty;

    // 最近一次尝试执行 BGSAVE 的时间
    server.lastbgsave_try = time(NULL);

    // fork() 开始前的时间，记录 fork() 返回耗时用
    start = ustime();

    if ((childpid = fork()) == 0) {
        int retval;

        /* Child */

        // 关闭网络连接 fd
        closeListeningSockets(0);

        // 设置进程的标题，方便识别
        redisSetProcTitle("redis-rdb-bgsave");

        // 执行保存操作
        retval = rdbSave(filename);

        // 打印 copy-on-write 时使用的内存数
        if (retval == REDIS_OK) {
            size_t private_dirty = zmalloc_get_private_dirty();

            if (private_dirty) {
                redisLog(REDIS_NOTICE,
                    "RDB: %zu MB of memory used by copy-on-write",
                    private_dirty/(1024*1024));
            }
        }

        // 向父进程发送信号
        exitFromChild((retval == REDIS_OK) ? 0 : 1);

    } else {

        /* Parent */

        // 计算 fork() 执行的时间
        server.stat_fork_time = ustime()-start;

        // 如果 fork() 出错，那么报告错误
        if (childpid == -1) {
            server.lastbgsave_status = REDIS_ERR;
            redisLog(REDIS_WARNING,"Can't save in background: fork: %s",
                strerror(errno));
            return REDIS_ERR;
        }

        // 打印 BGSAVE 开始的日志
        redisLog(REDIS_NOTICE,"Background saving started by pid %d",childpid);

        // 记录数据库开始 BGSAVE 的时间
        server.rdb_save_time_start = time(NULL);

        // 记录负责执行 BGSAVE 的子进程 ID
        server.rdb_child_pid = childpid;

        // 关闭自动 rehash
        updateDictResizePolicy();

        return REDIS_OK;
    }

    return REDIS_OK; /* unreached */
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
leaq 0xce9f5(%rip), %rax     # 0x1138f8
cmpl $-0x1, 0x570(%rax)
je 0x44f18
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x45081
leaq 0xce9d9(%rip), %rax     # 0x1138f8
movq 0x560(%rax), %rcx
leaq 0xce9cb(%rip), %rax     # 0x1138f8
movq %rcx, 0x568(%rax)
xorl %eax, %eax
movl %eax, %edi
callq 0x1fc70
movq %rax, %rcx
leaq 0xce9b1(%rip), %rax     # 0x1138f8
movq %rcx, 0x5a0(%rax)
callq 0x252a0
movq %rax, -0x20(%rbp)
callq 0x1fa40
movl %eax, -0x14(%rbp)
cmpl $0x0, %eax
jne 0x44fd0
xorl %edi, %edi
callq 0x298b0
leaq 0x9dcce(%rip), %rdi     # 0xe2c40
callq 0x2ba60
movq -0x10(%rbp), %rdi
callq 0x449a0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x44fb6
callq 0x2e750
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x44fb4
movq -0x30(%rbp), %rdx
shrq $0x14, %rdx
movl $0x2, %edi
leaq 0x9dca4(%rip), %rsi     # 0xe2c51
movb $0x0, %al
callq 0x24fb0
jmp 0x44fb6
movl -0x24(%rbp), %ecx
movl $0x1, %edi
xorl %eax, %eax
cmpl $0x0, %ecx
cmovel %eax, %edi
callq 0x25300
jmp 0x4507a
callq 0x252a0
movq %rax, %rcx
subq -0x20(%rbp), %rcx
leaq 0xce915(%rip), %rax     # 0x1138f8
movq %rcx, 0x380(%rax)
cmpl $-0x1, -0x14(%rbp)
jne 0x4502c
leaq 0xce901(%rip), %rax     # 0x1138f8
movl $0xffffffff, 0x5b8(%rax) # imm = 0xFFFFFFFF
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, %rdx
movl $0x3, %edi
leaq 0x9dc61(%rip), %rsi     # 0xe2c7d
movb $0x0, %al
callq 0x24fb0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x45081
movl -0x14(%rbp), %edx
movl $0x2, %edi
leaq 0x9dc65(%rip), %rsi     # 0xe2ca0
movb $0x0, %al
callq 0x24fb0
xorl %eax, %eax
movl %eax, %edi
callq 0x1fc70
movq %rax, %rcx
leaq 0xce8a3(%rip), %rax     # 0x1138f8
movq %rcx, 0x5b0(%rax)
movl -0x14(%rbp), %ecx
leaq 0xce892(%rip), %rax     # 0x1138f8
movl %ecx, 0x570(%rax)
callq 0x258c0
movl $0x0, -0x4(%rbp)
jmp 0x45081
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)