LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/bio.c
// Function: bioKillThreads
void bioKillThreads(void) {
    int err, j;

    for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
        if (pthread_cancel(bio_threads[j]) == 0) {
            if ((err = pthread_join(bio_threads[j],NULL)) != 0) {
                redisLog(REDIS_WARNING,
                    "Bio thread for job type #%d can be joined: %s",
                        j, strerror(err));
            } else {
                redisLog(REDIS_WARNING,
                    "Bio thread for job type #%d terminated",j);
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
leaq 0x8774b(%rip), %r12     # 0xdb8c0
leaq 0x3fe8b(%rip), %rbx     # 0x94007
pushq $0x3
popq %rbp
leaq 0x3fe53(%rip), %r14     # 0x93fd9
xorl %r15d, %r15d
cmpq $0x2, %r15
je 0x541de
movq (%r12), %rdi
callq 0x1f750
testl %eax, %eax
jne 0x541d5
movq (%r12), %rdi
xorl %esi, %esi
callq 0x1f080
testl %eax, %eax
je 0x541c6
movl %eax, %edi
callq 0x1f630
movl %ebp, %edi
movq %r14, %rsi
movl %r15d, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x22613
jmp 0x541d5
movl %ebp, %edi
movq %rbx, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x22613
incq %r15
addq $0x8, %r12
jmp 0x54189
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/rio.c
// Function: rioWriteBulkString
size_t rioWriteBulkString(rio *r, const char *buf, size_t len) {
    size_t nwritten;

    // 写入 $<count>\r\n
    if ((nwritten = rioWriteBulkCount(r,'$',len)) == 0) return 0;

    // 写入 <payload>
    if (len > 0 && rioWrite(r,buf,len) == 0) return 0;

    // 写入 \r\n
    if (rioWrite(r,"\r\n",2) == 0) return 0;

    // 返回写入总量
    return nwritten+len+2;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, %r14
pushq $0x24
popq %rsi
callq 0x54281
testq %rax, %rax
je 0x5439f
movq %rax, %r15
testq %rbx, %rbx
je 0x5437e
movq %r14, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x542d1
testq %rax, %rax
je 0x5439f
leaq 0x3b34e(%rip), %rsi     # 0x8f6d3
pushq $0x2
popq %rdx
movq %r14, %rdi
callq 0x542d1
testq %rax, %rax
je 0x5439f
leaq (%rbx,%r15), %rax
addq $0x2, %rax
jmp 0x543a1
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/rio.c
// Function: rioBufferRead
static size_t rioBufferRead(rio *r, void *buf, size_t len) {

    // r 中的内容的长度不足 len 
    if (sdslen(r->io.buffer.ptr)-r->io.buffer.pos < len)
        return 0; /* not enough buffer to return len bytes. */
    
    // 复制 r 中的内容到 buf
    memcpy(buf,r->io.buffer.ptr+r->io.buffer.pos,len);
    r->io.buffer.pos += len;

    return 1;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq 0x38(%rdi), %rax
movq 0x40(%rdi), %rcx
movslq -0x8(%rax), %rdx
subq %rcx, %rdx
cmpq %rbx, %rdx
jae 0x544bb
xorl %eax, %eax
jmp 0x544d6
movq %rdi, %r14
addq %rcx, %rax
movq %rsi, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x1fbd0
addq %rbx, 0x40(%r14)
pushq $0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/rio.c
// Function: rioBufferWrite
static size_t rioBufferWrite(rio *r, const void *buf, size_t len) {

    // 追加
    r->io.buffer.ptr = sdscatlen(r->io.buffer.ptr,(char*)buf,len);

    // 更新偏移量
    r->io.buffer.pos += len;

    return 1;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rdi, %r14
movq 0x38(%rdi), %rdi
callq 0x2736d
movq %rax, 0x38(%r14)
addq %rbx, 0x40(%r14)
pushq $0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/bitops.c
// Function: getBitOffsetFromArgument
static int getBitOffsetFromArgument(redisClient *c, robj *o, size_t *offset) {
    long long loffset;
    char *err = "bit offset is not an integer or out of range";

    if (getLongLongFromObjectOrReply(c,o,&loffset,err) != REDIS_OK)
        return REDIS_ERR;

    /* Limit offset to 512MB in bytes */
    if ((loffset < 0) || ((unsigned long long)loffset >> 3) >= (512*1024*1024))
    {
        addReplyError(c,err);
        return REDIS_ERR;
    }

    *offset = (size_t)loffset;
    return REDIS_OK;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdx, %r15
movq %rdi, %r14
leaq 0x3fd03(%rip), %rcx     # 0x94d3b
leaq 0x8(%rsp), %rdx
callq 0x2f617
pushq $-0x1
popq %rbx
testl %eax, %eax
jne 0x5506d
movq 0x8(%rsp), %rax
movq %rax, %rcx
shrq $0x20, %rcx
je 0x55068
leaq 0x3fcdd(%rip), %rsi     # 0x94d3b
movq %r14, %rdi
callq 0x2c2da
jmp 0x5506d
movq %rax, (%r15)
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/bitops.c
// Function: getbitCommand
void getbitCommand(redisClient *c) {
    robj *o;
    char llbuf[32];
    size_t bitoffset;
    size_t byte, bit;
    size_t bitval = 0;

    // 读取 offset 参数
    if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset) != REDIS_OK)
        return;

    // 查找对象，并进行类型检查
    if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
        checkType(c,o,REDIS_STRING)) return;

    // 计算出 offset 所指定的位所在的字节
    byte = bitoffset >> 3;
    // 计算出位所在的位置
    bit = 7 - (bitoffset & 0x7);

    // 取出位
    if (sdsEncodedObject(o)) {
        // 字符串编码，直接取值
        if (byte < sdslen(o->ptr))
            bitval = ((uint8_t*)o->ptr)[byte] & (1 << bit);
    } else {
        // 整数编码，先转换成字符串，再取值
        if (byte < (size_t)ll2string(llbuf,sizeof(llbuf),(long)o->ptr))
            bitval = llbuf[byte] & (1 << bit);
    }

    // 返回位
    addReply(c, bitval ? shared.cone : shared.czero);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x30, %rsp
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x10(%rax), %rsi
leaq 0x8(%rsp), %rdx
callq 0x55022
testl %eax, %eax
je 0x550ad
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x72744(%rip), %r12     # 0xc7800
movq 0x20(%r12), %rdx
movq %rbx, %rdi
callq 0x2f9a9
testq %rax, %rax
je 0x5509f
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x2eec6
testl %eax, %eax
jne 0x5509f
movq 0x8(%rsp), %r14
movq %r14, %r13
shrq $0x3, %r13
movl (%r15), %eax
shrl $0x4, %eax
testb $0x7, %al
jne 0x5510a
movq 0x8(%r15), %rax
movslq -0x8(%rax), %rcx
cmpq %rcx, %r13
jae 0x5514a
addq %r13, %rax
jmp 0x5512a
movq 0x8(%r15), %rdx
leaq 0x10(%rsp), %rdi
pushq $0x20
popq %rsi
callq 0x2e511
cltq
cmpq %rax, %r13
jae 0x5514a
leaq (%rsp,%r13), %rax
addq $0x10, %rax
movzbl (%rax), %eax
notb %r14b
andb $0x7, %r14b
pushq $0x1
popq %rdx
movl %r14d, %ecx
shll %cl, %edx
xorl %ecx, %ecx
andl %eax, %edx
setne %cl
movq 0x20(%r12,%rcx,8), %rsi
jmp 0x5514f
movq 0x20(%r12), %rsi
movq %rbx, %rdi
callq 0x2c10d
jmp 0x5509f
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: releaseSentinelRedisInstance
void releaseSentinelRedisInstance(sentinelRedisInstance *ri) {

    /* Release all its slaves or sentinels if any. */
    // 释放（可能有的）sentinel 和 slave
    dictRelease(ri->sentinels);
    dictRelease(ri->slaves);

    /* Release hiredis connections. */
    // 释放连接
    if (ri->cc) sentinelKillLink(ri,ri->cc);
    if (ri->pc) sentinelKillLink(ri,ri->pc);

    /* Free other resources. */
    // 释放其他资源
    sdsfree(ri->name);
    sdsfree(ri->runid);
    sdsfree(ri->notification_script);
    sdsfree(ri->client_reconfig_script);
    sdsfree(ri->slave_master_host);
    sdsfree(ri->leader);
    sdsfree(ri->auth_pass);
    releaseSentinelAddr(ri->addr);

    /* Clear state into the master if needed. */
    // 清除故障转移带来的状态
    if ((ri->flags & SRI_SLAVE) && (ri->flags & SRI_PROMOTED) && ri->master)
        ri->master->promoted_slave = NULL;

    zfree(ri);
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movq 0xc0(%rdi), %rdi
callq 0x21e31
movq 0xc8(%rbx), %rdi
callq 0x21e31
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
je 0x55b9d
movq %rbx, %rdi
callq 0x5742b
movq 0x30(%rbx), %rsi
testq %rsi, %rsi
je 0x55bae
movq %rbx, %rdi
callq 0x5742b
movq 0x8(%rbx), %rdi
callq 0x271f7
movq 0x10(%rbx), %rdi
callq 0x271f7
movq 0x160(%rbx), %rdi
callq 0x271f7
movq 0x168(%rbx), %rdi
callq 0x271f7
movq 0x100(%rbx), %rdi
callq 0x271f7
movq 0x118(%rbx), %rdi
callq 0x271f7
movq 0xd8(%rbx), %rdi
callq 0x271f7
movq 0x20(%rbx), %rdi
callq 0x56756
movl (%rbx), %eax
notl %eax
testw $0x102, %ax             # imm = 0x102
jne 0x55c23
movq 0xf8(%rbx), %rax
testq %rax, %rax
je 0x55c23
andq $0x0, 0x158(%rax)
movq %rbx, %rdi
popq %rbx
jmp 0x283cd
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: initSentinel
void initSentinel(void) {
    int j;

    /* Remove usual Redis commands from the command table, then just add
     * the SENTINEL command. */

    // 清空 Redis 服务器的命令表（该表用于普通模式）
    dictEmpty(server.commands,NULL);
    // 将 SENTINEL 模式所用的命令添加进命令表
    for (j = 0; j < sizeof(sentinelcmds)/sizeof(sentinelcmds[0]); j++) {
        int retval;
        struct redisCommand *cmd = sentinelcmds+j;

        retval = dictAdd(server.commands, sdsnew(cmd->name), cmd);
        redisAssert(retval == DICT_OK);
    }

    /* Initialize various data structures. */
    /* 初始化 Sentinel 的状态 */
    // 初始化纪元
    sentinel.current_epoch = 0;

    // 初始化保存主服务器信息的字典
    sentinel.masters = dictCreate(&instancesDictType,NULL);

    // 初始化 TILT 模式的相关选项
    sentinel.tilt = 0;
    sentinel.tilt_start_time = 0;
    sentinel.previous_time = mstime();

    // 初始化脚本相关选项
    sentinel.running_scripts = 0;
    sentinel.scripts_queue = listCreate();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0x70a8a(%rip), %r15     # 0xc6fa8
movq 0x18(%r15), %rdi
xorl %ebp, %ebp
xorl %esi, %esi
callq 0x2231b
leaq 0x706ae(%rip), %r12     # 0xc6be0
leaq 0x50(%rbp), %r13
cmpq $0x320, %r13            # imm = 0x320
je 0x56586
leaq (%r12,%rbp), %rbx
movq 0x18(%r15), %r14
movq (%rbp,%r12), %rdi
callq 0x271cd
movq %r14, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x21956
movq %r13, %rbp
testl %eax, %eax
je 0x56532
leaq 0x382ad(%rip), %rdi     # 0x8e81a
leaq 0x3e824(%rip), %rsi     # 0x94d98
movl $0x28c, %edx            # imm = 0x28C
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
andq $0x0, 0x8535a(%rip)     # 0xdb8e8
leaq 0x705eb(%rip), %rdi     # 0xc6b80
xorl %esi, %esi
callq 0x216f0
movq %rax, 0x8534d(%rip)     # 0xdb8f0
andl $0x0, 0x8534e(%rip)     # 0xdb8f8
andq $0x0, 0x8534e(%rip)     # 0xdb900
callq 0x22843
movq %rax, 0x8534a(%rip)     # 0xdb908
andl $0x0, 0x85337(%rip)     # 0xdb8fc
callq 0x1fd8c
movq %rax, 0x8533f(%rip)     # 0xdb910
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelIsRunning
void sentinelIsRunning(void) {
    redisLog(REDIS_WARNING,"Sentinel runid is %s", server.runid);

    // Sentinel 不能在没有配置文件的情况下执行
    if (server.configfile == NULL) {
        redisLog(REDIS_WARNING,
            "Sentinel started without a config file. Exiting...");
        exit(1);
    } else if (access(server.configfile,W_OK) == -1) {
        redisLog(REDIS_WARNING,
            "Sentinel config file %s is not writable: %s. Exiting...",
            server.configfile,strerror(errno));
        exit(1);
    }

    /* We want to generate a +monitor event for every configured master
     * at startup. */
    sentinelGenerateInitialMonitorEvents();
}

// Assembly:
pushq %rbx
leaq 0x709c0(%rip), %rbx     # 0xc6fa8
leaq 0x58(%rbx), %rdx
leaq 0x3e7b0(%rip), %rsi     # 0x94da3
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x22613
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x56618
pushq $0x2
popq %rsi
callq 0x1fa20
cmpl $-0x1, %eax
je 0x5662b
popq %rbx
jmp 0x56659
leaq 0x3e799(%rip), %rsi     # 0x94db8
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x22613
jmp 0x56651
movq (%rbx), %rbx
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x3e7aa(%rip), %rsi     # 0x94deb
pushq $0x3
popq %rdi
movq %rbx, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x22613
pushq $0x1
popq %rdi
callq 0x1f2b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelGenerateInitialMonitorEvents
void sentinelGenerateInitialMonitorEvents(void) {
    dictIterator *di;
    dictEntry *de;

    di = dictGetIterator(sentinel.masters);
    while((de = dictNext(di)) != NULL) {
        sentinelRedisInstance *ri = dictGetVal(de);
        sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
    }
    dictReleaseIterator(di);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq 0x85289(%rip), %rdi     # 0xdb8f0
callq 0x21ef6
movq %rax, %rbx
leaq 0x3e7d0(%rip), %r14     # 0x94e46
leaq 0x3e7d2(%rip), %r15     # 0x94e4f
pushq $0x3
popq %rbp
movq %rbx, %rdi
callq 0x21f2f
testq %rax, %rax
je 0x566a9
movq 0x8(%rax), %rdx
movl 0xd0(%rdx), %r8d
movl %ebp, %edi
movq %r14, %rsi
movq %r15, %rcx
xorl %eax, %eax
callq 0x5678f
jmp 0x56680
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x21fe6
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: createSentinelAddr
sentinelAddr *createSentinelAddr(char *hostname, int port) {
    char buf[32];
    sentinelAddr *sa;

    // 检查端口号
    if (port <= 0 || port > 65535) {
        errno = EINVAL;
        return NULL;
    }

    // 检查并创建地址
    if (anetResolve(NULL,hostname,buf,sizeof(buf)) == ANET_ERR) {
        errno = ENOENT;
        return NULL;
    }

    // 创建并返回地址结构
    sa = zmalloc(sizeof(*sa));
    sa->ip = sdsnew(buf);
    sa->port = port;
    return sa;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x28, %rsp
movl %esi, %ebx
movl $0xffff0000, %eax       # imm = 0xFFFF0000
leal (%rbx,%rax), %ecx
cmpl %eax, %ecx
ja 0x566dd
callq 0x1f810
movl $0x16, (%rax)
jmp 0x56719
movq %rdi, %rsi
movq %rsp, %rdx
pushq $0x20
popq %rcx
xorl %edi, %edi
callq 0x20d60
cmpl $-0x1, %eax
je 0x5670e
pushq $0x10
popq %rdi
callq 0x2828d
movq %rax, %r14
movq %rsp, %rdi
callq 0x271cd
movq %rax, (%r14)
movl %ebx, 0x8(%r14)
jmp 0x5671c
callq 0x1f810
movl $0x2, (%rax)
xorl %r14d, %r14d
movq %r14, %rax
addq $0x28, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelKillTimedoutScripts
void sentinelKillTimedoutScripts(void) {
    listNode *ln;
    listIter li;
    mstime_t now = mstime();

    // 遍历队列中的所有脚本
    listRewind(sentinel.scripts_queue,&li);
    while ((ln = listNext(&li)) != NULL) {
        sentinelScriptJob *sj = ln->value;

        // 选出那些正在执行，并且执行时间超过限制的脚本
        if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
            (now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
        {
            // 发送脚本超时事件
            sentinelEvent(REDIS_WARNING,"-script-timeout",NULL,"%s %ld",
                sj->argv[0], (long)sj->pid);

            // 杀死脚本进程
            kill(sj->pid,SIGKILL);
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
callq 0x22843
movq %rax, %rbx
movq 0x84a56(%rip), %rdi     # 0xdb910
leaq 0x8(%rsp), %r14
movq %r14, %rsi
callq 0x1ffac
leaq 0x39564(%rip), %r12     # 0x90432
pushq $0x3
popq %rbp
pushq $0x9
popq %r13
movq %r14, %rdi
callq 0x1ffc6
testq %rax, %rax
je 0x56f29
movq 0x10(%rax), %r15
testb $0x1, (%r15)
je 0x56ed5
movq %rbx, %rax
subq 0x10(%r15), %rax
cmpq $0xea61, %rax           # imm = 0xEA61
jl 0x56ed5
movq 0x8(%r15), %rax
movq (%rax), %r8
movslq 0x18(%r15), %r9
movl %ebp, %edi
leaq 0x3e00c(%rip), %rsi     # 0x94f1b
xorl %edx, %edx
movq %r12, %rcx
xorl %eax, %eax
callq 0x5678f
movl 0x18(%r15), %edi
movl %r13d, %esi
callq 0x1f620
jmp 0x56ed5
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelRedisInstanceLookupSlave
sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
                sentinelRedisInstance *ri, char *ip, int port)
{
    sds key;
    sentinelRedisInstance *slave;
  
    redisAssert(ri->flags & SRI_MASTER);
    key = sdscatprintf(sdsempty(),
        strchr(ip,':') ? "[%s]:%d" : "%s:%d",
        ip,port);
    slave = dictFetchValue(ri->slaves,key);
    sdsfree(key);
    return slave;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
testb $0x1, (%rdi)
je 0x574ce
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
callq 0x271bf
movq %rax, %r15
pushq $0x3a
popq %rsi
movq %r14, %rdi
callq 0x1f790
testq %rax, %rax
leaq 0x374dc(%rip), %rax     # 0x8e965
leaq 0x35bce(%rip), %rsi     # 0x8d05e
cmoveq %rax, %rsi
movq %r15, %rdi
movq %r14, %rdx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x2763d
movq %rax, %r14
movq 0xc8(%rbx), %rdi
movq %rax, %rsi
callq 0x21e57
movq %rax, %rbx
movq %r14, %rdi
callq 0x271f7
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3dadc(%rip), %rdi     # 0x94fb1
leaq 0x3d8bc(%rip), %rsi     # 0x94d98
movl $0x5b1, %edx            # imm = 0x5B1
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: removeMatchingSentinelsFromMaster
int removeMatchingSentinelsFromMaster(sentinelRedisInstance *master, char *ip, int port, char *runid) {
    dictIterator *di;
    dictEntry *de;
    int removed = 0;

    di = dictGetSafeIterator(master->sentinels);
    while((de = dictNext(di)) != NULL) {
        sentinelRedisInstance *ri = dictGetVal(de);

        // 运行 ID 相同，或者 IP 和端口号相同，那么移除该实例
        if ((ri->runid && runid && strcmp(ri->runid,runid) == 0) ||
            (ip && strcmp(ri->addr->ip,ip) == 0 && port == ri->addr->port))
        {
            dictDelete(master->sentinels,ri->name);
            removed++;
        }
    }
    dictReleaseIterator(di);

    return removed;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rcx, %rbx
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, 0x10(%rsp)
movq 0xc0(%rdi), %rdi
callq 0x21f20
movq %rax, %r13
movl $0x0, 0xc(%rsp)
movq %r13, %rdi
callq 0x21f2f
testq %rax, %rax
je 0x57586
movq 0x8(%rax), %r15
testq %rbx, %rbx
je 0x5754b
movq 0x10(%r15), %rdi
testq %rdi, %rdi
je 0x5754b
movq %rbx, %rsi
callq 0x1f880
testl %eax, %eax
je 0x5756b
testq %r14, %r14
je 0x57520
movq 0x20(%r15), %r12
movq (%r12), %rdi
movq %r14, %rsi
callq 0x1f880
testl %eax, %eax
jne 0x57520
cmpl %ebp, 0x8(%r12)
jne 0x57520
movq 0x10(%rsp), %rax
movq 0xc0(%rax), %rdi
movq 0x8(%r15), %rsi
callq 0x21c36
incl 0xc(%rsp)
jmp 0x57520
movq %r13, %rdi
callq 0x21fe6
movl 0xc(%rsp), %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelResetMaster
void sentinelResetMaster(sentinelRedisInstance *ri, int flags) {

    redisAssert(ri->flags & SRI_MASTER);

    dictRelease(ri->slaves);
    ri->slaves = dictCreate(&instancesDictType,NULL);

    if (!(flags & SENTINEL_RESET_NO_SENTINELS)) {
        dictRelease(ri->sentinels);
        ri->sentinels = dictCreate(&instancesDictType,NULL);
    }

    if (ri->cc) sentinelKillLink(ri,ri->cc);

    if (ri->pc) sentinelKillLink(ri,ri->pc);

    // 设置标识为断线的主服务器
    ri->flags &= SRI_MASTER|SRI_DISCONNECTED;

    if (ri->leader) {
        sdsfree(ri->leader);
        ri->leader = NULL;
    }

    ri->failover_state = SENTINEL_FAILOVER_STATE_NONE;
    ri->failover_state_change_time = 0;
    ri->failover_start_time = 0;
    ri->promoted_slave = NULL;
    sdsfree(ri->runid);
    sdsfree(ri->slave_master_host);
    ri->runid = NULL;
    ri->slave_master_host = NULL;
    ri->last_ping_time = mstime();
    ri->last_avail_time = mstime();
    ri->last_pong_time = mstime();
    ri->role_reported_time = mstime();
    ri->role_reported = SRI_MASTER;
    // 发送主服务器重置事件
    if (flags & SENTINEL_GENERATE_EVENT)
        sentinelEvent(REDIS_WARNING,"+reset-master",ri,"%@");
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
testb $0x1, (%rdi)
je 0x57817
movl %esi, %ebp
movq %rdi, %rbx
movq 0xc8(%rdi), %rdi
callq 0x21e31
leaq 0x6f476(%rip), %rdi     # 0xc6b80
xorl %esi, %esi
callq 0x216f0
movq %rax, 0xc8(%rbx)
testb $0x1, %bpl
jne 0x5773f
movq 0xc0(%rbx), %rdi
callq 0x21e31
leaq 0x6f44f(%rip), %rdi     # 0xc6b80
xorl %esi, %esi
callq 0x216f0
movq %rax, 0xc0(%rbx)
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
je 0x57750
movq %rbx, %rdi
callq 0x5742b
movq 0x30(%rbx), %rsi
testq %rsi, %rsi
je 0x57761
movq %rbx, %rdi
callq 0x5742b
andl $0x9, (%rbx)
movq 0x118(%rbx), %rdi
testq %rdi, %rdi
je 0x5777d
callq 0x271f7
andq $0x0, 0x118(%rbx)
andl $0x0, 0x130(%rbx)
andq $0x0, 0x158(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x138(%rbx)
movq 0x10(%rbx), %rdi
callq 0x271f7
movq 0x100(%rbx), %rdi
callq 0x271f7
andq $0x0, 0x10(%rbx)
andq $0x0, 0x100(%rbx)
callq 0x22843
movq %rax, 0x60(%rbx)
callq 0x22843
movq %rax, 0x58(%rbx)
callq 0x22843
movq %rax, 0x68(%rbx)
callq 0x22843
movq %rax, 0xb0(%rbx)
movl $0x1, 0xa8(%rbx)
btl $0x10, %ebp
jb 0x577f6
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
leaq 0x3d7d7(%rip), %rsi     # 0x94fd4
leaq 0x3d7de(%rip), %rcx     # 0x94fe2
pushq $0x3
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x5678f
leaq 0x3d793(%rip), %rdi     # 0x94fb1
leaq 0x3d573(%rip), %rsi     # 0x94d98
movl $0x662, %edx            # imm = 0x662
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelFlushConfig
void sentinelFlushConfig(void) {
    int fd = -1;
    int saved_hz = server.hz;
    int rewrite_status;

    server.hz = REDIS_DEFAULT_HZ;
    rewrite_status = rewriteConfig(server.configfile);
    server.hz = saved_hz;

    if (rewrite_status == -1) goto werr;
    if ((fd = open(server.configfile,O_RDONLY)) == -1) goto werr;
    if (fsync(fd) == -1) goto werr;
    if (close(fd) == EOF) goto werr;
    return;

werr:
    if (fd != -1) close(fd);
    redisLog(REDIS_WARNING,"WARNING: Sentinel was not able to save the new configuration on disk!!!: %s", strerror(errno));
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
leaq 0x6f579(%rip), %rbx     # 0xc6fa8
movl 0x8(%rbx), %ebp
movl $0xa, 0x8(%rbx)
movq (%rbx), %rdi
callq 0x45127
movl %ebp, 0x8(%rbx)
cmpl $-0x1, %eax
je 0x57a82
movq (%rbx), %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x1f640
cmpl $-0x1, %eax
je 0x57a82
movl %eax, %ebx
movl %eax, %edi
callq 0x1f5d0
cmpl $-0x1, %eax
je 0x57a7b
movl %ebx, %edi
callq 0x1f170
cmpl $-0x1, %eax
je 0x57a7b
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
movl %ebx, %edi
callq 0x1f170
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x3d918(%rip), %rsi     # 0x953ad
pushq $0x3
popq %rdi
movq %rax, %rdx
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x22613
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelDisconnectInstanceFromContext
void sentinelDisconnectInstanceFromContext(const redisAsyncContext *c) {
    sentinelRedisInstance *ri = c->data;
    int pubsub;

    if (ri == NULL) return; /* The instance no longer exists. */

    // 发送断线事件
    pubsub = (ri->pc == c);
    sentinelEvent(REDIS_DEBUG, pubsub ? "-pubsub-link" : "-cmd-link", ri,
        "%@ #%s", c->errstr);

    if (pubsub)
        ri->pc = NULL;
    else
        ri->cc = NULL;

    // 打开标志
    ri->flags |= SRI_DISCONNECTED;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0xb0(%rdi), %rbx
testq %rbx, %rbx
je 0x583be
xorl %r14d, %r14d
cmpq %rdi, 0x30(%rbx)
sete %r14b
leaq 0x3d069(%rip), %rax     # 0x953f9
leaq 0x3d06f(%rip), %rsi     # 0x95406
cmoveq %rax, %rsi
movq 0xa8(%rdi), %r8
leaq 0x3d067(%rip), %rcx     # 0x95410
xorl %edi, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
andq $0x0, 0x28(%rbx,%r14,8)
orb $0x8, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelLinkEstablishedCallback
void sentinelLinkEstablishedCallback(const redisAsyncContext *c, int status) {
    if (status != REDIS_OK) {
        sentinelDisconnectInstanceFromContext(c);
    } else {
        sentinelRedisInstance *ri = c->data;
        int pubsub = (ri->pc == c);

        // 发送连接事件
        sentinelEvent(REDIS_DEBUG, pubsub ? "+pubsub-link" : "+cmd-link", ri,
            "%@");
    }
}

// Assembly:
testl %esi, %esi
je 0x583cf
jmp 0x5836e
movq 0xb0(%rdi), %rdx
cmpq %rdi, 0x30(%rdx)
leaq 0x3d036(%rip), %rax     # 0x95417
leaq 0x3d03c(%rip), %rsi     # 0x95424
cmoveq %rax, %rsi
leaq 0x3cbef(%rip), %rcx     # 0x94fe2
xorl %edi, %edi
xorl %eax, %eax
jmp 0x5678f
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelSendAuthIfNeeded
void sentinelSendAuthIfNeeded(sentinelRedisInstance *ri, redisAsyncContext *c) {

    // 如果 ri 是主服务器，那么使用实例自己的密码
    // 如果 ri 是从服务器，那么使用主服务器的密码
    char *auth_pass = (ri->flags & SRI_MASTER) ? ri->auth_pass :
                                                 ri->master->auth_pass;

    // 发送 AUTH 命令
    if (auth_pass) {
        if (redisAsyncCommand(c, sentinelDiscardReplyCallback, NULL, "AUTH %s",
            auth_pass) == REDIS_OK) ri->pending_commands++;
    }
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
testb $0x1, (%rdi)
movq %rdi, %rax
jne 0x58414
movq 0xf8(%rbx), %rax
movq 0xd8(%rax), %r8
testq %r8, %r8
je 0x58444
leaq 0x1f(%rip), %rax        # 0x58446
leaq 0x3d000(%rip), %rcx     # 0x9542e
movq %rsi, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x5e024
testl %eax, %eax
jne 0x58444
incl 0x38(%rbx)
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelSetClientName
void sentinelSetClientName(sentinelRedisInstance *ri, redisAsyncContext *c, char *type) {
    char name[64];

    snprintf(name,sizeof(name),"sentinel-%.8s-%s",server.runid,type);
    if (redisAsyncCommand(c, sentinelDiscardReplyCallback, NULL,
        "CLIENT SETNAME %s", name) == REDIS_OK)
    {
        ri->pending_commands++;
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x40, %rsp
movq %rdx, %r8
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x6eb39(%rip), %rcx     # 0xc6fa8
addq $0x58, %rcx
leaq 0x3cfbc(%rip), %rdx     # 0x95436
movq %rsp, %r15
pushq $0x40
popq %rsi
movq %r15, %rdi
xorl %eax, %eax
callq 0x1f120
leaq -0x4b(%rip), %rsi       # 0x58446
leaq 0x3cfaf(%rip), %rcx     # 0x95447
movq %r14, %rdi
xorl %edx, %edx
movq %r15, %r8
xorl %eax, %eax
callq 0x5e024
testl %eax, %eax
jne 0x584ae
incl 0x38(%rbx)
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelSendPing
int sentinelSendPing(sentinelRedisInstance *ri) {
    int retval = redisAsyncCommand(ri->cc,
        sentinelPingReplyCallback, NULL, "PING");
    if (retval == REDIS_OK) {
        ri->pending_commands++;
        /* We update the ping time only if we received the pong for
         * the previous ping, otherwise we are technically waiting
         * since the first ping that did not received a reply. */
        if (ri->last_ping_time == 0) ri->last_ping_time = mstime();
        return 1;
    } else {
        return 0;
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x28(%rdi), %rdi
leaq 0x961(%rip), %rsi       # 0x5908a
leaq 0x36212(%rip), %rcx     # 0x8e942
xorl %r14d, %r14d
xorl %edx, %edx
xorl %eax, %eax
callq 0x5e024
testl %eax, %eax
jne 0x58757
incl 0x38(%rbx)
pushq $0x1
popq %r14
cmpq $0x0, 0x60(%rbx)
jne 0x58757
callq 0x22843
movq %rax, 0x60(%rbx)
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelReceiveHelloMessages
void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) {
    sentinelRedisInstance *ri = c->data;
    redisReply *r;

    if (!reply || !ri) return;
    r = reply;

    /* Update the last activity in the pubsub channel. Note that since we
     * receive our messages as well this timestamp can be used to detect
     * if the link is probably disconnected even if it seems otherwise. */
    // 更新最后一次接收频道命令的时间
    ri->pc_last_activity = mstime();
   
    /* Sanity check in the reply we expect, so that the code that follows
     * can avoid to check for details. */
    // 只处理频道发来的信息，不处理订阅时和退订时产生的信息
    if (r->type != REDIS_REPLY_ARRAY ||
        r->elements != 3 ||
        r->element[0]->type != REDIS_REPLY_STRING ||
        r->element[1]->type != REDIS_REPLY_STRING ||
        r->element[2]->type != REDIS_REPLY_STRING ||
        strcmp(r->element[0]->str,"message") != 0) return;

    /* We are not interested in meeting ourselves */
    // 只处理非自己发送的信息
    if (strstr(r->element[2]->str,server.runid) != NULL) return;

    sentinelProcessHelloMessage(r->element[2]->str, r->element[2]->len);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0xb0(%rdi), %r14
testq %rsi, %rsi
setne %al
testq %r14, %r14
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x587e7
movq %rsi, %rbx
callq 0x22843
movq %rax, 0x50(%r14)
cmpl $0x2, (%rbx)
jne 0x587e7
cmpq $0x3, 0x20(%rbx)
jne 0x587e7
movq 0x28(%rbx), %rcx
movq (%rcx), %rax
cmpl $0x1, (%rax)
jne 0x587e7
movq 0x8(%rcx), %rdx
cmpl $0x1, (%rdx)
jne 0x587e7
movq 0x10(%rcx), %r14
cmpl $0x1, (%r14)
jne 0x587e7
movq 0x18(%rax), %rdi
leaq 0x3d0e8(%rip), %rsi     # 0x958aa
callq 0x1f880
testl %eax, %eax
jne 0x587e7
movq 0x18(%r14), %rbx
leaq 0x6e7d2(%rip), %rsi     # 0xc6fa8
addq $0x58, %rsi
movq %rbx, %rdi
callq 0x1f660
testq %rax, %rax
je 0x587ef
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movl 0x10(%r14), %esi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x59190
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelSendSlaveOf
int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port) {
    char portstr[32];
    int retval;

    ll2string(portstr,sizeof(portstr),port);

    if (host == NULL) {
        host = "NO";
        memcpy(portstr,"ONE",4);
    }

    // 发送 SLAVEOF NO ONE
    retval = redisAsyncCommand(ri->cc,
        sentinelDiscardReplyCallback, NULL, "SLAVEOF %s %s", host, portstr);
    if (retval == REDIS_ERR) return retval;

    ri->pending_commands++;

    // 发送 CONFIG REWRITE
    if (redisAsyncCommand(ri->cc,
        sentinelDiscardReplyCallback, NULL, "CONFIG REWRITE") == REDIS_OK)
    {
        ri->pending_commands++;
    }

    return REDIS_OK;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rsi, %r15
movq %rdi, %rbx
movslq %edx, %rdx
movq %rsp, %rdi
pushq $0x20
popq %rsi
callq 0x2e511
testq %r15, %r15
jne 0x59006
movl $0x454e4f, (%rsp)       # imm = 0x454E4F
leaq 0x3ccf7(%rip), %r15     # 0x95cfd
movq 0x28(%rbx), %rdi
leaq -0xbcb(%rip), %rsi      # 0x58446
leaq 0x3cce8(%rip), %rcx     # 0x95d00
xorl %r14d, %r14d
movq %rsp, %r9
xorl %edx, %edx
movq %r15, %r8
xorl %eax, %eax
callq 0x5e024
cmpl $-0x1, %eax
je 0x59056
incl 0x38(%rbx)
movq 0x28(%rbx), %rdi
leaq -0xbf7(%rip), %rsi      # 0x58446
leaq 0x373a0(%rip), %rcx     # 0x903e4
xorl %edx, %edx
xorl %eax, %eax
callq 0x5e024
testl %eax, %eax
jne 0x5905a
incl 0x38(%rbx)
jmp 0x5905a
pushq $-0x1
popq %r14
movl %r14d, %eax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelInfoReplyCallback
void sentinelInfoReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
    sentinelRedisInstance *ri = c->data;
    redisReply *r;

    if (ri) ri->pending_commands--;
    if (!reply || !ri) return;
    r = reply;

    if (r->type == REDIS_REPLY_STRING) {
        sentinelRefreshInstanceInfo(ri,r->str);
    }
}

// Assembly:
movq 0xb0(%rdi), %rdi
testq %rdi, %rdi
je 0x59089
decl 0x38(%rdi)
testq %rsi, %rsi
je 0x59089
cmpl $0x1, (%rsi)
jne 0x59089
movq 0x18(%rsi), %rsi
jmp 0x5883a
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelPingReplyCallback
void sentinelPingReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
    sentinelRedisInstance *ri = c->data;
    redisReply *r;

    if (ri) ri->pending_commands--;
    if (!reply || !ri) return;
    r = reply;

    if (r->type == REDIS_REPLY_STATUS ||
        r->type == REDIS_REPLY_ERROR) {

        /* Update the "instance available" field only if this is an
         * acceptable reply. */
        // 只在实例返回 acceptable 回复时更新 last_avail_time
        if (strncmp(r->str,"PONG",4) == 0 ||
            strncmp(r->str,"LOADING",7) == 0 ||
            strncmp(r->str,"MASTERDOWN",10) == 0)
        {
            // 实例运作正常
            ri->last_avail_time = mstime();
            ri->last_ping_time = 0; /* Flag the pong as received. */
        } else {

            // 实例运作不正常

            /* Send a SCRIPT KILL command if the instance appears to be
             * down because of a busy script. */
            // 如果服务器因为执行脚本而进入 BUSY 状态，
            // 那么尝试通过发送 SCRIPT KILL 来恢复服务器
            if (strncmp(r->str,"BUSY",4) == 0 &&
                (ri->flags & SRI_S_DOWN) &&
                !(ri->flags & SRI_SCRIPT_KILL_SENT))
            {
                if (redisAsyncCommand(ri->cc,
                        sentinelDiscardReplyCallback, NULL,
                        "SCRIPT KILL") == REDIS_OK)
                    ri->pending_commands++;
                ri->flags |= SRI_SCRIPT_KILL_SENT;
            }
        }
    }

    // 更新实例最后一次回复 PING 命令的时间
    ri->last_pong_time = mstime();
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0xb0(%rdi), %r14
testq %r14, %r14
je 0x59163
decl 0x38(%r14)
testq %rsi, %rsi
je 0x59163
movl (%rsi), %eax
addl $-0x5, %eax
cmpl $0x1, %eax
ja 0x5915a
movq 0x18(%rsi), %rbx
leaq 0x35518(%rip), %rsi     # 0x8e5dc
pushq $0x4
popq %rdx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5914c
leaq 0x3c524(%rip), %rsi     # 0x955fe
pushq $0x7
popq %rdx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5914c
leaq 0x3c516(%rip), %rsi     # 0x95606
pushq $0xa
popq %rdx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5914c
leaq 0x3c50b(%rip), %rsi     # 0x95611
pushq $0x4
popq %rdx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
jne 0x5915a
movl $0x2010, %eax           # imm = 0x2010
andl (%r14), %eax
cmpl $0x10, %eax
jne 0x5915a
movq 0x28(%r14), %rdi
leaq -0xce7(%rip), %rsi      # 0x58446
leaq 0x3c4e2(%rip), %rcx     # 0x95616
xorl %edx, %edx
xorl %eax, %eax
callq 0x5e024
testl %eax, %eax
jne 0x59145
incl 0x38(%r14)
orb $0x20, 0x1(%r14)
jmp 0x5915a
callq 0x22843
movq %rax, 0x58(%r14)
andq $0x0, 0x60(%r14)
callq 0x22843
movq %rax, 0x68(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelPublishReplyCallback
void sentinelPublishReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
    sentinelRedisInstance *ri = c->data;
    redisReply *r;

    if (ri) ri->pending_commands--;
    if (!reply || !ri) return;
    r = reply;

    /* Only update pub_time if we actually published our message. Otherwise
     * we'll retry against in 100 milliseconds. */
    // 如果命令发送成功，那么更新 last_pub_time
    if (r->type != REDIS_REPLY_ERROR)
        ri->last_pub_time = mstime();
}

// Assembly:
pushq %rbx
movq 0xb0(%rdi), %rbx
testq %rbx, %rbx
je 0x5918e
decl 0x38(%rbx)
testq %rsi, %rsi
je 0x5918e
cmpl $0x6, (%rsi)
je 0x5918e
callq 0x22843
movq %rax, 0x70(%rbx)
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelSendHello
int sentinelSendHello(sentinelRedisInstance *ri) {
    char ip[REDIS_IP_STR_LEN];
    char payload[REDIS_IP_STR_LEN+1024];
    int retval;

    // 如果实例是主服务器，那么使用此实例的信息
    // 如果实例是从服务器，那么使用这个从服务器的主服务器的信息
    sentinelRedisInstance *master = (ri->flags & SRI_MASTER) ? ri : ri->master;

    // 获取地址信息
    sentinelAddr *master_addr = sentinelGetCurrentMasterAddress(master);

    /* Try to obtain our own IP address. */
    // 获取实例自身的地址
    if (anetSockName(ri->cc->c.fd,ip,sizeof(ip),NULL) == -1) return REDIS_ERR;
    if (ri->flags & SRI_DISCONNECTED) return REDIS_ERR;

    /* Format and send the Hello message. */
    // 格式化信息
    snprintf(payload,sizeof(payload),
        "%s,%d,%s,%llu," /* Info about this sentinel. */
        "%s,%s,%d,%llu", /* Info about current master. */
        ip, server.port, server.runid,
        (unsigned long long) sentinel.current_epoch,
        /* --- */
        master->name,master_addr->ip,master_addr->port,
        (unsigned long long) master->config_epoch);
    
    // 发送信息
    retval = redisAsyncCommand(ri->cc,
        sentinelPublishReplyCallback, NULL, "PUBLISH %s %s",
            SENTINEL_HELLO_CHANNEL,payload);

    if (retval != REDIS_OK) return REDIS_ERR;

    ri->pending_commands++;

    return REDIS_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x460, %rsp            # imm = 0x460
movq %rdi, %rbx
testb $0x1, (%rdi)
movq %rdi, %r14
jne 0x59418
movq 0xf8(%rbx), %r14
movq %r14, %rdi
callq 0x57ae9
movq %rax, %r15
movq 0x28(%rbx), %rax
movl 0x84(%rax), %edi
movq %rsp, %rsi
pushq $0x2e
popq %rdx
xorl %ecx, %ecx
callq 0x21513
pushq $-0x1
popq %rbp
cmpl $-0x1, %eax
je 0x594ca
testb $0x8, (%rbx)
jne 0x594ca
leaq 0x6db56(%rip), %r9      # 0xc6fa8
movl 0x88(%r9), %r8d
movl 0x8(%r15), %r10d
subq $0x8, %rsp
addq $0x58, %r9
leaq 0x3c228(%rip), %rdx     # 0x95694
leaq 0x38(%rsp), %r12
leaq 0x8(%rsp), %rcx
movl $0x42e, %esi            # imm = 0x42E
movq %r12, %rdi
xorl %eax, %eax
pushq 0x18(%r14)
pushq %r10
pushq (%r15)
pushq 0x8(%r14)
pushq 0x82455(%rip)           # 0xdb8e8
callq 0x1f120
addq $0x30, %rsp
movq 0x28(%rbx), %rdi
leaq -0x33c(%rip), %rsi      # 0x5916b
leaq 0x3c202(%rip), %rcx     # 0x956b0
leaq 0x3bfe6(%rip), %r8      # 0x9549b
xorl %edx, %edx
movq %r12, %r9
xorl %eax, %eax
callq 0x5e024
testl %eax, %eax
jne 0x594ca
incl 0x38(%rbx)
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x460, %rsp            # imm = 0x460
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelStartFailover
void sentinelStartFailover(sentinelRedisInstance *master) {
    redisAssert(master->flags & SRI_MASTER);

    // 更新故障转移状态
    master->failover_state = SENTINEL_FAILOVER_STATE_WAIT_START;

    // 更新主服务器状态
    master->flags |= SRI_FAILOVER_IN_PROGRESS;

    // 更新纪元
    master->failover_epoch = ++sentinel.current_epoch;

    sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
        (unsigned long long) sentinel.current_epoch);

    sentinelEvent(REDIS_WARNING,"+try-failover",master,"%@");

    // 记录故障转移状态的变更时间
    master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
    master->failover_state_change_time = mstime();
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movl (%rdi), %eax
testb $0x1, %al
je 0x59fc8
movq %rdi, %rbx
movl $0x1, 0x130(%rdi)
orl $0x80, %eax
movl %eax, (%rdi)
movq 0x8199b(%rip), %r8      # 0xdb8e8
incq %r8
movq %r8, 0x81991(%rip)      # 0xdb8e8
movq %r8, 0x128(%rdi)
leaq 0x3b6f2(%rip), %rsi     # 0x95657
leaq 0x3b43c(%rip), %rcx     # 0x953a8
pushq $0x3
popq %rbp
movl %ebp, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
leaq 0x3bda7(%rip), %rsi     # 0x95d29
leaq 0x3b059(%rip), %rcx     # 0x94fe2
movl %ebp, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
callq 0x22843
movq %rax, %r14
callq 0x1faf0
movl $0x3e8, %ecx            # imm = 0x3E8
cltd
idivl %ecx
movslq %edx, %rax
addq %r14, %rax
movq %rax, 0x140(%rbx)
callq 0x22843
movq %rax, 0x138(%rbx)
popq %rbx
popq %r14
popq %rbp
retq
leaq 0x3bd3f(%rip), %rdi     # 0x95d0e
leaq 0x3adc2(%rip), %rsi     # 0x94d98
movl $0x1065, %edx           # imm = 0x1065
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelReceiveIsMasterDownReply
void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *privdata) {
    sentinelRedisInstance *ri = c->data;
    redisReply *r;

    if (ri) ri->pending_commands--;
    if (!reply || !ri) return;
    r = reply;

    /* Ignore every error or unexpected reply.
     * 忽略错误回复
     * Note that if the command returns an error for any reason we'll
     * end clearing the SRI_MASTER_DOWN flag for timeout anyway. */
    if (r->type == REDIS_REPLY_ARRAY && r->elements == 3 &&
        r->element[0]->type == REDIS_REPLY_INTEGER &&
        r->element[1]->type == REDIS_REPLY_STRING &&
        r->element[2]->type == REDIS_REPLY_INTEGER)
    {
        // 更新最后一次回复询问的时间
        ri->last_master_down_reply_time = mstime();

        // 设置 SENTINEL 认为主服务器的状态
        if (r->element[0]->integer == 1) {
            // 已下线
            ri->flags |= SRI_MASTER_DOWN;
        } else {
            // 未下线
            ri->flags &= ~SRI_MASTER_DOWN;
        }

        // 如果运行 ID 不是 "*" 的话，那么这是一个带投票的回复
        if (strcmp(r->element[1]->str,"*")) {
            /* If the runid in the reply is not "*" the Sentinel actually
             * replied with a vote. */
            sdsfree(ri->leader);
            // 打印日志
            if (ri->leader_epoch != r->element[2]->integer)
                redisLog(REDIS_WARNING,
                    "%s voted for %s %llu", ri->name,
                    r->element[1]->str,
                    (unsigned long long) r->element[2]->integer);
            // 设置实例的领头
            ri->leader = sdsnew(r->element[1]->str);
            ri->leader_epoch = r->element[2]->integer;
        }
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0xb0(%rdi), %r14
testq %r14, %r14
je 0x5a5f4
movq %rsi, %rbx
decl 0x38(%r14)
testq %rsi, %rsi
je 0x5a5f4
cmpl $0x2, (%rbx)
jne 0x5a5f4
cmpq $0x3, 0x20(%rbx)
jne 0x5a5f4
movq 0x28(%rbx), %rax
movq (%rax), %rcx
cmpl $0x3, (%rcx)
jne 0x5a5f4
movq 0x8(%rax), %rcx
cmpl $0x1, (%rcx)
jne 0x5a5f4
movq 0x10(%rax), %rax
cmpl $0x3, (%rax)
jne 0x5a5f4
callq 0x22843
movq %rax, 0x80(%r14)
movq 0x28(%rbx), %rax
movq (%rax), %rcx
xorl %edx, %edx
cmpq $0x1, 0x8(%rcx)
sete %dl
movl (%r14), %ecx
andl $-0x41, %ecx
shll $0x6, %edx
orl %ecx, %edx
movl %edx, (%r14)
movq 0x8(%rax), %rax
movq 0x18(%rax), %rax
cmpb $0x2a, (%rax)
jne 0x5a58b
cmpb $0x0, 0x1(%rax)
je 0x5a5f4
movq 0x118(%r14), %rdi
callq 0x271f7
movq 0x28(%rbx), %rax
movq 0x10(%rax), %rcx
movq 0x8(%rcx), %r8
cmpq %r8, 0x120(%r14)
je 0x5a5cd
movq 0x8(%r14), %rdx
movq 0x8(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0x3b6b4(%rip), %rsi     # 0x95c73
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x22613
movq 0x28(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
callq 0x271cd
movq %rax, 0x118(%r14)
movq 0x28(%rbx), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x120(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelLeaderIncr
int sentinelLeaderIncr(dict *counters, char *runid) {
    dictEntry *de = dictFind(counters,runid);
    uint64_t oldval;

    if (de) {
        oldval = dictGetUnsignedIntegerVal(de);
        dictSetUnsignedIntegerVal(de,oldval+1);
        return oldval+1;
    } else {
        de = dictAddRaw(counters,runid);
        redisAssert(de != NULL);
        dictSetUnsignedIntegerVal(de,1);
        return 1;
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
callq 0x21b64
testq %rax, %rax
je 0x5a737
movq %rax, %rcx
movq 0x8(%rax), %rax
incq %rax
movq %rax, 0x8(%rcx)
jmp 0x5a752
movq %r14, %rdi
movq %rbx, %rsi
callq 0x21997
testq %rax, %rax
je 0x5a75a
movq $0x1, 0x8(%rax)
pushq $0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x32f95(%rip), %rdi     # 0x8d6f6
leaq 0x3a630(%rip), %rsi     # 0x94d98
movl $0xfc2, %edx            # imm = 0xFC2
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: compareSlavesForPromotion
int compareSlavesForPromotion(const void *a, const void *b) {
    sentinelRedisInstance **sa = (sentinelRedisInstance **)a,
                          **sb = (sentinelRedisInstance **)b;
    char *sa_runid, *sb_runid;

    // 优先级较小的从服务器胜出
    if ((*sa)->slave_priority != (*sb)->slave_priority)
        return (*sa)->slave_priority - (*sb)->slave_priority;

    /* If priority is the same, select the slave with greater replication
     * offset (processed more data frmo the master). */
    // 如果优先级相同，那么复制偏移量较大的那个从服务器胜出
    // （偏移量较大表示从主服务器获取的数据更多，更完整）
    if ((*sa)->slave_repl_offset > (*sb)->slave_repl_offset) {
        return -1; /* a < b */
    } else if ((*sa)->slave_repl_offset < (*sb)->slave_repl_offset) {
        return 1; /* b > a */
    }

    /* If the replication offset is the same select the slave with that has
     * the lexicographically smaller runid. Note that we try to handle runid
     * == NULL as there are old Redis versions that don't publish runid in
     * INFO. A NULL runid is considered bigger than any other runid. */
    // 如果复制偏移量也相同，那么选出运行 ID 较低的那个从服务器
    // 注意，对于没有运行 ID 的旧版 Redis 来说，默认的运行 ID 为 NULL
    sa_runid = (*sa)->runid;
    sb_runid = (*sb)->runid;
    if (sa_runid == NULL && sb_runid == NULL) return 0;
    else if (sa_runid == NULL) return 1;  /* a > b */
    else if (sb_runid == NULL) return -1; /* a < b */
    return strcasecmp(sa_runid, sb_runid);
}

// Assembly:
movq (%rdi), %rcx
movl 0xe8(%rcx), %eax
movq (%rsi), %rdx
subl 0xe8(%rdx), %eax
jne 0x5aa18
movq 0x110(%rdx), %rax
cmpq %rax, 0x110(%rcx)
jbe 0x5a9d8
pushq $-0x1
jmp 0x5a9dc
jae 0x5a9de
pushq $0x1
popq %rax
retq
movq 0x10(%rcx), %rdi
movq 0x10(%rdx), %rsi
testq %rdi, %rdi
sete %al
testq %rsi, %rsi
sete %r8b
xorl %ecx, %ecx
movq %rdi, %rdx
orq %rsi, %rdx
setne %dl
orb %al, %r8b
xorl %eax, %eax
movq %rdi, %r9
negq %r9
sbbl %eax, %eax
testb %r8b, %r8b
je 0x1f2e0
movb %dl, %cl
orl %ecx, %eax
retq