LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O3/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, 0xc(%rsp)
movq %rsi, %r15
movq %rdi, 0x10(%rsp)
movq 0xc0(%rdi), %rdi
callq 0x22aa0
movq %rax, %r14
movq %rax, %rdi
callq 0x22acf
xorl %r13d, %r13d
testq %rax, %rax
je 0x5bfc2
movq 0x8(%rax), %rbp
testq %rbx, %rbx
je 0x5bf7c
movq 0x10(%rbp), %rdi
testq %rdi, %rdi
je 0x5bf7c
movq %rbx, %rsi
callq 0x1f880
testl %eax, %eax
je 0x5bfa0
testq %r15, %r15
je 0x5bfb8
movq 0x20(%rbp), %r12
movq (%r12), %rdi
movq %r15, %rsi
callq 0x1f880
testl %eax, %eax
jne 0x5bfb8
movl 0xc(%rsp), %eax
cmpl %eax, 0x8(%r12)
jne 0x5bfb8
movq 0x10(%rsp), %rax
movq 0xc0(%rax), %rdi
movq 0x8(%rbp), %rsi
callq 0x22796
incl %r13d
movq %r14, %rdi
callq 0x22acf
jmp 0x5bf59
movq %r14, %rdi
callq 0x22b86
movl %r13d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/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 %r14
pushq %rbx
testb $0x1, (%rdi)
je 0x5c26a
movl %esi, %ebp
movq %rdi, %rbx
movq 0xc8(%rdi), %rdi
callq 0x229a9
leaq 0x6da27(%rip), %rdi     # 0xc9b80
xorl %esi, %esi
callq 0x2217b
movq %rax, 0xc8(%rbx)
testb $0x1, %bpl
jne 0x5c18e
movq 0xc0(%rbx), %rdi
callq 0x229a9
leaq 0x6da00(%rip), %rdi     # 0xc9b80
xorl %esi, %esi
callq 0x2217b
movq %rax, 0xc0(%rbx)
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
je 0x5c19f
movq %rbx, %rdi
callq 0x5be4f
movq 0x30(%rbx), %rsi
testq %rsi, %rsi
je 0x5c1b0
movq %rbx, %rdi
callq 0x5be4f
andl $0x9, (%rbx)
movq 0x118(%rbx), %rdi
testq %rdi, %rdi
je 0x5c1cf
callq 0x2850d
movq $0x0, 0x118(%rbx)
movl $0x0, 0x130(%rbx)
xorl %r14d, %r14d
movq %r14, 0x158(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x138(%rbx)
movq 0x10(%rbx), %rdi
callq 0x2850d
movq 0x100(%rbx), %rdi
callq 0x2850d
movq %r14, 0x10(%rbx)
movq %r14, 0x100(%rbx)
callq 0x23461
movq %rax, 0x60(%rbx)
callq 0x23461
movq %rax, 0x58(%rbx)
callq 0x23461
movq %rax, 0x68(%rbx)
callq 0x23461
movq %rax, 0xb0(%rbx)
movl $0x1, 0xa8(%rbx)
btl $0x10, %ebp
jb 0x5c249
popq %rbx
popq %r14
popq %rbp
retq
leaq 0x42e10(%rip), %rsi     # 0x9f060
leaq 0x42e17(%rip), %rcx     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
jmp 0x5b0ac
leaq 0x42dcc(%rip), %rdi     # 0x9f03d
leaq 0x42bac(%rip), %rsi     # 0x9ee24
movl $0x662, %edx            # imm = 0x662
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/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 0x6dac7(%rip), %rbx     # 0xc9fa8
movl 0x8(%rbx), %ebp
movl $0xa, 0x8(%rbx)
movq (%rbx), %rdi
callq 0x4856f
movl %ebp, 0x8(%rbx)
cmpl $-0x1, %eax
je 0x5c534
movq (%rbx), %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x1f640
cmpl $-0x1, %eax
je 0x5c534
movl %eax, %ebx
movl %eax, %edi
callq 0x1f5d0
cmpl $-0x1, %eax
je 0x5c52d
movl %ebx, %edi
callq 0x1f170
cmpl $-0x1, %eax
je 0x5c52d
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
movl %ebx, %edi
callq 0x1f170
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x42ef2(%rip), %rsi     # 0x9f439
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x23223
// File: /workspace/github_c_makefile_star2_O3/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 0x5cf1d
xorl %r14d, %r14d
cmpq %rdi, 0x30(%rbx)
sete %r14b
leaq 0x42599(%rip), %rax     # 0x9f485
leaq 0x4259f(%rip), %rsi     # 0x9f492
cmoveq %rax, %rsi
movq 0xa8(%rdi), %r8
leaq 0x42597(%rip), %rcx     # 0x9f49c
xorl %edi, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movq $0x0, 0x28(%rbx,%r14,8)
orb $0x8, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/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 0x5cf2e
jmp 0x5ceca
movq 0xb0(%rdi), %rdx
cmpq %rdi, 0x30(%rdx)
leaq 0x42563(%rip), %rax     # 0x9f4a3
leaq 0x42569(%rip), %rsi     # 0x9f4b0
cmoveq %rax, %rsi
leaq 0x4211c(%rip), %rcx     # 0x9f06e
xorl %edi, %edi
xorl %eax, %eax
jmp 0x5b0ac
// File: /workspace/github_c_makefile_star2_O3/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 0x5cf73
movq 0xf8(%rbx), %rax
movq 0xd8(%rax), %r8
testq %r8, %r8
je 0x5cfa3
leaq 0x1f(%rip), %rax        # 0x5cfa5
leaq 0x4252d(%rip), %rcx     # 0x9f4ba
movq %rsi, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x630fd
testl %eax, %eax
jne 0x5cfa3
incl 0x38(%rbx)
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O3/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 0x6cfda(%rip), %rcx     # 0xc9fa8
addq $0x58, %rcx
leaq 0x424e9(%rip), %rdx     # 0x9f4c2
movq %rsp, %r15
movl $0x40, %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x1f120
leaq -0x4d(%rip), %rsi       # 0x5cfa5
leaq 0x424da(%rip), %rcx     # 0x9f4d3
movq %r14, %rdi
xorl %edx, %edx
movq %r15, %r8
xorl %eax, %eax
callq 0x630fd
testl %eax, %eax
jne 0x5d00f
incl 0x38(%rbx)
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/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 0xa64(%rip), %rsi       # 0x5dcf3
leaq 0x3b6e8(%rip), %rcx     # 0x9897e
xorl %r14d, %r14d
xorl %edx, %edx
xorl %eax, %eax
callq 0x630fd
testl %eax, %eax
jne 0x5d2bf
incl 0x38(%rbx)
movl $0x1, %r14d
cmpq $0x0, 0x60(%rbx)
jne 0x5d2bf
callq 0x23461
movq %rax, 0x60(%rbx)
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/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 0x5d34f
movq %rsi, %rbx
callq 0x23461
movq %rax, 0x50(%r14)
cmpl $0x2, (%rbx)
jne 0x5d34f
cmpq $0x3, 0x20(%rbx)
jne 0x5d34f
movq 0x28(%rbx), %rcx
movq (%rcx), %rax
cmpl $0x1, (%rax)
jne 0x5d34f
movq 0x8(%rcx), %rdx
cmpl $0x1, (%rdx)
jne 0x5d34f
movq 0x10(%rcx), %r14
cmpl $0x1, (%r14)
jne 0x5d34f
movq 0x18(%rax), %rdi
leaq 0x4260c(%rip), %rsi     # 0x9f936
callq 0x1f880
testl %eax, %eax
jne 0x5d34f
movq 0x18(%r14), %rbx
leaq 0x6cc6a(%rip), %rsi     # 0xc9fa8
addq $0x58, %rsi
movq %rbx, %rdi
callq 0x1f660
testq %rax, %rax
je 0x5d357
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movl 0x10(%r14), %esi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x5de04
// File: /workspace/github_c_makefile_star2_O3/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
movl $0x20, %esi
callq 0x300c7
testq %r15, %r15
jne 0x5dc6d
movl $0x454e4f, (%rsp)       # imm = 0x454E4F
leaq 0x4211c(%rip), %r15     # 0x9fd89
movq 0x28(%rbx), %rdi
leaq -0xcd3(%rip), %rsi      # 0x5cfa5
leaq 0x4210d(%rip), %rcx     # 0x9fd8c
xorl %r14d, %r14d
movq %rsp, %r9
xorl %edx, %edx
movq %r15, %r8
xorl %eax, %eax
callq 0x630fd
cmpl $-0x1, %eax
je 0x5dcbd
incl 0x38(%rbx)
movq 0x28(%rbx), %rdi
leaq -0xcff(%rip), %rsi      # 0x5cfa5
leaq 0x3c775(%rip), %rcx     # 0x9a420
xorl %edx, %edx
xorl %eax, %eax
callq 0x630fd
testl %eax, %eax
jne 0x5dcc3
incl 0x38(%rbx)
jmp 0x5dcc3
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movl %r14d, %eax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/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 0x5dcf2
decl 0x38(%rdi)
testq %rsi, %rsi
je 0x5dcf2
cmpl $0x1, (%rsi)
jne 0x5dcf2
movq 0x18(%rsi), %rsi
jmp 0x5d3a2
retq
// File: /workspace/github_c_makefile_star2_O3/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 0x5ddd7
decl 0x38(%r14)
testq %rsi, %rsi
je 0x5ddd7
movl (%rsi), %eax
addl $-0x5, %eax
cmpl $0x1, %eax
ja 0x5ddce
movq 0x18(%rsi), %rbx
leaq 0x3a8eb(%rip), %rsi     # 0x98618
movl $0x4, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5ddbd
leaq 0x41945(%rip), %rsi     # 0x9f68a
movl $0x7, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5ddbd
leaq 0x41935(%rip), %rsi     # 0x9f692
movl $0xa, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5ddbd
leaq 0x41928(%rip), %rsi     # 0x9f69d
movl $0x4, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
jne 0x5ddce
movl $0x2010, %eax           # imm = 0x2010
andl (%r14), %eax
cmpl $0x10, %eax
jne 0x5ddce
movq 0x28(%r14), %rdi
leaq -0xdf9(%rip), %rsi      # 0x5cfa5
leaq 0x418fd(%rip), %rcx     # 0x9f6a2
xorl %edx, %edx
xorl %eax, %eax
callq 0x630fd
testl %eax, %eax
jne 0x5ddb6
incl 0x38(%r14)
orb $0x20, 0x1(%r14)
jmp 0x5ddce
callq 0x23461
movq %rax, 0x58(%r14)
movq $0x0, 0x60(%r14)
callq 0x23461
movq %rax, 0x68(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/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 0x5de02
decl 0x38(%rbx)
testq %rsi, %rsi
je 0x5de02
cmpl $0x6, (%rsi)
je 0x5de02
callq 0x23461
movq %rax, 0x70(%rbx)
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O3/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
movl (%rdi), %eax
movq %rdi, %r15
testb $0x1, %al
jne 0x5e0be
movq 0xf8(%rbx), %r15
movl (%r15), %eax
testb %al, %al
jns 0x5e0d8
movq 0x158(%r15), %rax
testq %rax, %rax
je 0x5e0d8
cmpl $0x4, 0x130(%r15)
jg 0x5e0db
movq %r15, %rax
movq 0x20(%rax), %r12
movq 0x28(%rbx), %rax
movl 0x84(%rax), %edi
movq %rsp, %rsi
movl $0x2e, %edx
xorl %ecx, %ecx
callq 0x21f83
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
cmpl $-0x1, %eax
je 0x5e190
testb $0x8, (%rbx)
jne 0x5e190
leaq 0x6be92(%rip), %r9      # 0xc9fa8
movl 0x88(%r9), %r8d
movl 0x8(%r12), %r10d
subq $0x8, %rsp
addq $0x58, %r9
leaq 0x415ef(%rip), %rdx     # 0x9f720
leaq 0x38(%rsp), %r14
leaq 0x8(%rsp), %rcx
movl $0x42e, %esi            # imm = 0x42E
movq %r14, %rdi
xorl %eax, %eax
pushq 0x18(%r15)
pushq %r10
pushq (%r12)
pushq 0x8(%r15)
pushq 0x8078f(%rip)           # 0xde8e8
callq 0x1f120
addq $0x30, %rsp
movq 0x28(%rbx), %rdi
leaq -0x38e(%rip), %rsi      # 0x5dddf
leaq 0x415c8(%rip), %rcx     # 0x9f73c
leaq 0x413ac(%rip), %r8      # 0x9f527
xorl %edx, %edx
movq %r14, %r9
xorl %eax, %eax
callq 0x630fd
testl %eax, %eax
jne 0x5e190
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_O3/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 %r14
pushq %rbx
pushq %rax
movl (%rdi), %eax
testb $0x1, %al
je 0x5ece7
movq %rdi, %rbx
movl $0x1, 0x130(%rdi)
orl $0x80, %eax
movl %eax, (%rdi)
movq 0x7fc97(%rip), %r8      # 0xde8e8
incq %r8
movq %r8, 0x7fc8d(%rip)      # 0xde8e8
movq %r8, 0x128(%rdi)
leaq 0x40a7a(%rip), %rsi     # 0x9f6e3
leaq 0x407c4(%rip), %rcx     # 0x9f434
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
leaq 0x4112f(%rip), %rsi     # 0x9fdb5
leaq 0x403e1(%rip), %rcx     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
callq 0x23461
movq %rax, %r14
callq 0x1faf0
cltq
imulq $0x10624dd3, %rax, %rcx # imm = 0x10624DD3
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x26, %rcx
addl %edx, %ecx
imull $0x3e8, %ecx, %ecx      # imm = 0x3E8
subl %ecx, %eax
cltq
addq %r14, %rax
movq %rax, 0x140(%rbx)
callq 0x23461
movq %rax, 0x138(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x410ac(%rip), %rdi     # 0x9fd9a
leaq 0x4012f(%rip), %rsi     # 0x9ee24
movl $0x1065, %edx           # imm = 0x1065
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/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 0x5f35f
movq %rsi, %rbx
decl 0x38(%r14)
testq %rsi, %rsi
je 0x5f35f
cmpl $0x2, (%rbx)
jne 0x5f35f
cmpq $0x3, 0x20(%rbx)
jne 0x5f35f
movq 0x28(%rbx), %rax
movq (%rax), %rcx
cmpl $0x3, (%rcx)
jne 0x5f35f
movq 0x8(%rax), %rcx
cmpl $0x1, (%rcx)
jne 0x5f35f
movq 0x10(%rax), %rax
cmpl $0x3, (%rax)
jne 0x5f35f
callq 0x23461
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 0x5f2f4
cmpb $0x0, 0x1(%rax)
je 0x5f35f
movq 0x118(%r14), %rdi
callq 0x2850d
movq 0x28(%rbx), %rax
movq 0x10(%rax), %rcx
movq 0x8(%rcx), %r8
cmpq %r8, 0x120(%r14)
je 0x5f338
movq 0x8(%r14), %rdx
movq 0x8(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0x409d7(%rip), %rsi     # 0x9fcff
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movq 0x28(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
callq 0x28486
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_O3/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 0x226ac
testq %rax, %rax
je 0x5f4ac
movq %rax, %rcx
movq 0x8(%rax), %rax
incq %rax
movq %rax, 0x8(%rcx)
jmp 0x5f4c9
movq %r14, %rdi
movq %rbx, %rsi
callq 0x224df
testq %rax, %rax
je 0x5f4d1
movq $0x1, 0x8(%rax)
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x3823c(%rip), %rdi     # 0x97714
leaq 0x3f945(%rip), %rsi     # 0x9ee24
movl $0xfc2, %edx            # imm = 0xFC2
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/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 0x5f802
movq 0x110(%rdx), %rsi
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rsi, 0x110(%rcx)
ja 0x5f802
movl $0x1, %eax
jb 0x5f802
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
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelFailoverWaitStart
void sentinelFailoverWaitStart(sentinelRedisInstance *ri) {
    char *leader;
    int isleader;

    /* Check if we are the leader for the failover epoch. */
    // 获取给定纪元的领头 Sentinel
    leader = sentinelGetLeader(ri, ri->failover_epoch);
    // 本 Sentinel 是否为领头 Sentinel ？
    isleader = leader && strcasecmp(leader,server.runid) == 0;
    sdsfree(leader);

    /* If I'm not the leader, and it is not a forced failover via
     * SENTINEL FAILOVER, then I can't continue with the failover. */
    // 如果本 Sentinel 不是领头，并且这次故障迁移不是一次强制故障迁移操作
    // 那么本 Sentinel 不做动作
    if (!isleader && !(ri->flags & SRI_FORCE_FAILOVER)) {
        int election_timeout = SENTINEL_ELECTION_TIMEOUT;

        /* The election timeout is the MIN between SENTINEL_ELECTION_TIMEOUT
         * and the configured failover timeout. */
        // 当选的时长（类似于任期）是 SENTINEL_ELECTION_TIMEOUT
        // 和 Sentinel 设置的故障迁移时长之间的较小那个值
        if (election_timeout > ri->failover_timeout)
            election_timeout = ri->failover_timeout;

        /* Abort the failover if I'm not the leader after some time. */
        // Sentinel 的当选时间已过，取消故障转移计划
        if (mstime() - ri->failover_start_time > election_timeout) {
            sentinelEvent(REDIS_WARNING,"-failover-abort-not-elected",ri,"%@");
            // 取消故障转移
            sentinelAbortFailover(ri);
        }
        return;
    }

    // 本 Sentinel 作为领头，开始执行故障迁移操作...

    sentinelEvent(REDIS_WARNING,"+elected-leader",ri,"%@");

    // 进入选择从服务器状态
    ri->failover_state = SENTINEL_FAILOVER_STATE_SELECT_SLAVE;
    ri->failover_state_change_time = mstime();

    sentinelEvent(REDIS_WARNING,"+failover-state-select-slave",ri,"%@");
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x128(%rdi), %rsi
callq 0x5f4f3
testq %rax, %rax
je 0x5f841
movq %rax, %r14
leaq 0x6a783(%rip), %rsi     # 0xc9fa8
addq $0x58, %rsi
movq %rax, %rdi
callq 0x1f2e0
movl %eax, %ebp
movq %r14, %rdi
callq 0x2850d
testl %ebp, %ebp
jne 0x5f848
jmp 0x5f89e
xorl %edi, %edi
callq 0x2850d
testb $0x10, 0x1(%rbx)
jne 0x5f89e
movq 0x148(%rbx), %rax
movl $0x2710, %ecx           # imm = 0x2710
cmpq %rcx, %rax
movslq %eax, %r14
cmovgeq %rcx, %r14
callq 0x23461
subq 0x140(%rbx), %rax
cmpq %r14, %rax
jle 0x5f8f1
leaq 0x40582(%rip), %rsi     # 0x9fdfe
leaq 0x3f7eb(%rip), %rcx     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movq %rbx, %rdi
popq %rbx
popq %r14
popq %rbp
jmp 0x5f8f6
leaq 0x40575(%rip), %rsi     # 0x9fe1a
leaq 0x3f7c2(%rip), %r14     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x5b0ac
movl $0x2, 0x130(%rbx)
callq 0x23461
movq %rax, 0x138(%rbx)
leaq 0x4054f(%rip), %rsi     # 0x9fe2a
movl $0x3, %edi
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
jmp 0x5b0ac
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelAbortFailover
void sentinelAbortFailover(sentinelRedisInstance *ri) {
    redisAssert(ri->flags & SRI_FAILOVER_IN_PROGRESS);
    redisAssert(ri->failover_state <= SENTINEL_FAILOVER_STATE_WAIT_PROMOTION);

    // 移除相关标识
    ri->flags &= ~(SRI_FAILOVER_IN_PROGRESS|SRI_FORCE_FAILOVER);

    // 清除状态
    ri->failover_state = SENTINEL_FAILOVER_STATE_NONE;
    ri->failover_state_change_time = mstime();

    // 清除新主服务器的升级标识
    if (ri->promoted_slave) {
        ri->promoted_slave->flags &= ~SRI_PROMOTED;
        // 清空新服务器
        ri->promoted_slave = NULL;
    }
}

// Assembly:
pushq %rbx
movl (%rdi), %eax
testb %al, %al
jns 0x5f943
movq %rdi, %rbx
cmpl $0x5, 0x130(%rdi)
jge 0x5f958
andl $0xffffef7f, %eax       # imm = 0xFFFFEF7F
movl %eax, (%rbx)
movl $0x0, 0x130(%rbx)
callq 0x23461
movq %rax, 0x138(%rbx)
movq 0x158(%rbx), %rax
testq %rax, %rax
je 0x5f941
andb $-0x2, 0x1(%rax)
movq $0x0, 0x158(%rbx)
popq %rbx
retq
leaq 0x405f7(%rip), %rdi     # 0x9ff41
leaq 0x3f4d3(%rip), %rsi     # 0x9ee24
movl $0x12d4, %edx           # imm = 0x12D4
jmp 0x5f96b
leaq 0x40607(%rip), %rdi     # 0x9ff66
leaq 0x3f4be(%rip), %rsi     # 0x9ee24
movl $0x12d5, %edx           # imm = 0x12D5
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelFailoverSelectSlave
void sentinelFailoverSelectSlave(sentinelRedisInstance *ri) {

    // 在旧主服务器所属的从服务器中，选择新服务器
    sentinelRedisInstance *slave = sentinelSelectSlave(ri);

    /* We don't handle the timeout in this state as the function aborts
     * the failover or go forward in the next state. */
    // 没有合适的从服务器，直接终止故障转移操作
    if (slave == NULL) {

        // 没有可用的从服务器可以提升为新主服务器，故障转移操作无法执行
        sentinelEvent(REDIS_WARNING,"-failover-abort-no-good-slave",ri,"%@");

        // 中止故障转移
        sentinelAbortFailover(ri);

    } else {

        // 成功选定新主服务器

        // 发送事件
        sentinelEvent(REDIS_WARNING,"+selected-slave",slave,"%@");

        // 打开实例的升级标记
        slave->flags |= SRI_PROMOTED;

        // 记录被选中的从服务器
        ri->promoted_slave = slave;

        // 更新故障转移状态
        ri->failover_state = SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE;

        // 更新状态改变时间
        ri->failover_state_change_time = mstime();

        // 发送事件
        sentinelEvent(REDIS_NOTICE,"+failover-state-send-slaveof-noone",
            slave, "%@");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
callq 0x5eaef
testq %rax, %rax
je 0x5f9ef
movq %rax, %r14
leaq 0x404cf(%rip), %rsi     # 0x9fe65
leaq 0x3f6d1(%rip), %r15     # 0x9f06e
movl $0x3, %edi
movq %rax, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x5b0ac
orb $0x1, 0x1(%r14)
movq %r14, 0x158(%rbx)
movl $0x3, 0x130(%rbx)
callq 0x23461
movq %rax, 0x138(%rbx)
leaq 0x4049d(%rip), %rsi     # 0x9fe75
movl $0x2, %edi
movq %r14, %rdx
movq %r15, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
jmp 0x5b0ac
leaq 0x40451(%rip), %rsi     # 0x9fe47
leaq 0x3f671(%rip), %rcx     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x5f8f6
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelFailoverWaitPromotion
void sentinelFailoverWaitPromotion(sentinelRedisInstance *ri) {
    /* Just handle the timeout. Switching to the next state is handled
     * by the function parsing the INFO command of the promoted slave. */
    if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
        sentinelEvent(REDIS_WARNING,"-failover-abort-slave-timeout",ri,"%@");
        sentinelAbortFailover(ri);
    }
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
callq 0x23461
subq 0x138(%rbx), %rax
cmpq 0x148(%rbx), %rax
jle 0x5faeb
leaq 0x403cc(%rip), %rsi     # 0x9fe98
leaq 0x3f59b(%rip), %rcx     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movq %rbx, %rdi
popq %rbx
jmp 0x5f8f6
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelFailoverSwitchToPromotedSlave
void sentinelFailoverSwitchToPromotedSlave(sentinelRedisInstance *master) {

    /// 选出要添加的 master
    sentinelRedisInstance *ref = master->promoted_slave ?
                                 master->promoted_slave : master;

    // 发送更新 master 事件
    sentinelEvent(REDIS_WARNING,"+switch-master",master,"%s %s %d %s %d",
        // 原 master 信息
        master->name, master->addr->ip, master->addr->port,
        // 新 master 信息
        ref->addr->ip, ref->addr->port);

    // 用新主服务器的信息代替原 master 的信息
    sentinelResetMasterAndChangeAddress(master,ref->addr->ip,ref->addr->port);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x158(%rdi), %r14
testq %r14, %r14
cmoveq %rdi, %r14
movq 0x8(%rdi), %r8
movq 0x20(%rdi), %rax
movq (%rax), %r9
movl 0x8(%rax), %r10d
movq 0x20(%r14), %r11
movl 0x8(%r11), %r15d
subq $0x8, %rsp
leaq 0x3f8ab(%rip), %rsi     # 0x9f702
leaq 0x3f8b3(%rip), %rcx     # 0x9f711
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
pushq %r15
pushq (%r11)
pushq %r10
callq 0x5b0ac
addq $0x20, %rsp
movq 0x20(%r14), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x5c2ff
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/notify.c
// Function: keyspaceEventsStringToFlags
int keyspaceEventsStringToFlags(char *classes) {
    char *p = classes;
    int c, flags = 0;

    while((c = *p++) != '\0') {
        switch(c) {
        case 'A': flags |= REDIS_NOTIFY_ALL; break;
        case 'g': flags |= REDIS_NOTIFY_GENERIC; break;
        case '$': flags |= REDIS_NOTIFY_STRING; break;
        case 'l': flags |= REDIS_NOTIFY_LIST; break;
        case 's': flags |= REDIS_NOTIFY_SET; break;
        case 'h': flags |= REDIS_NOTIFY_HASH; break;
        case 'z': flags |= REDIS_NOTIFY_ZSET; break;
        case 'x': flags |= REDIS_NOTIFY_EXPIRED; break;
        case 'e': flags |= REDIS_NOTIFY_EVICTED; break;
        case 'K': flags |= REDIS_NOTIFY_KEYSPACE; break;
        case 'E': flags |= REDIS_NOTIFY_KEYEVENT; break;
        // 不能识别
        default: return -1;
        }
    }

    return flags;
}

// Assembly:
xorl %eax, %eax
leaq 0x3fe2b(%rip), %rcx     # 0x9ffd4
movzbl (%rdi), %edx
cmpl $0x64, %edx
jle 0x601d2
cmpl $0x72, %edx
jg 0x601e8
addl $-0x65, %edx
cmpl $0x7, %edx
ja 0x6024d
movslq (%rcx,%rdx,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
movl $0x200, %esi            # imm = 0x200
jmp 0x6023e
cmpl $0x44, %edx
jg 0x601fe
cmpl $0x24, %edx
je 0x60239
movl $0x3fc, %esi            # imm = 0x3FC
cmpl $0x41, %edx
je 0x6023e
jmp 0x60248
cmpl $0x73, %edx
je 0x60232
cmpl $0x78, %edx
je 0x6022b
cmpl $0x7a, %edx
jne 0x6024d
movl $0x80, %esi
jmp 0x6023e
cmpl $0x45, %edx
je 0x60224
cmpl $0x4b, %edx
jne 0x6024d
movl $0x1, %esi
jmp 0x6023e
movl $0x4, %esi
jmp 0x6023e
movl $0x10, %esi
jmp 0x6023e
movl $0x40, %esi
jmp 0x6023e
movl $0x2, %esi
jmp 0x6023e
movl $0x100, %esi            # imm = 0x100
jmp 0x6023e
movl $0x20, %esi
jmp 0x6023e
movl $0x8, %esi
incq %rdi
orl %esi, %eax
jmp 0x601a9
testl %edx, %edx
jne 0x6024d
retq
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/notify.c
// Function: keyspaceEventsFlagsToString
sds keyspaceEventsFlagsToString(int flags) {
    sds res;

    res = sdsempty();
    if ((flags & REDIS_NOTIFY_ALL) == REDIS_NOTIFY_ALL) {
        res = sdscatlen(res,"A",1);
    } else {
        if (flags & REDIS_NOTIFY_GENERIC) res = sdscatlen(res,"g",1);
        if (flags & REDIS_NOTIFY_STRING) res = sdscatlen(res,"$",1);
        if (flags & REDIS_NOTIFY_LIST) res = sdscatlen(res,"l",1);
        if (flags & REDIS_NOTIFY_SET) res = sdscatlen(res,"s",1);
        if (flags & REDIS_NOTIFY_HASH) res = sdscatlen(res,"h",1);
        if (flags & REDIS_NOTIFY_ZSET) res = sdscatlen(res,"z",1);
        if (flags & REDIS_NOTIFY_EXPIRED) res = sdscatlen(res,"x",1);
        if (flags & REDIS_NOTIFY_EVICTED) res = sdscatlen(res,"e",1);
    }
    if (flags & REDIS_NOTIFY_KEYSPACE) res = sdscatlen(res,"K",1);
    if (flags & REDIS_NOTIFY_KEYEVENT) res = sdscatlen(res,"E",1);

    return res;
}

// Assembly:
pushq %rbx
movl %edi, %ebx
callq 0x2845e
movl %ebx, %ecx
notl %ecx
testl $0x3fc, %ecx            # imm = 0x3FC
jne 0x60273
leaq 0x4322e(%rip), %rsi     # 0xa349c
jmp 0x6032f
testb $0x4, %bl
je 0x6028c
leaq 0x41425(%rip), %rsi     # 0xa16a4
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb $0x8, %bl
je 0x602a5
leaq 0x3fd5c(%rip), %rsi     # 0x9fff4
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb $0x10, %bl
je 0x602be
leaq 0x3d399(%rip), %rsi     # 0x9d64a
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb $0x20, %bl
je 0x602d7
leaq 0x3f1b9(%rip), %rsi     # 0x9f483
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb $0x40, %bl
je 0x602f0
leaq 0x41b37(%rip), %rsi     # 0xa1e1a
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb %bl, %bl
jns 0x60308
leaq 0x398ae(%rip), %rsi     # 0x99ba9
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
btl $0x8, %ebx
jae 0x60322
leaq 0x368ff(%rip), %rsi     # 0x96c14
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
btl $0x9, %ebx
jae 0x6033c
leaq 0x41ff5(%rip), %rsi     # 0xa2324
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb $0x1, %bl
je 0x60355
leaq 0x3dda3(%rip), %rsi     # 0x9e0eb
movl $0x1, %edx
movq %rax, %rdi
callq 0x28689
testb $0x2, %bl
jne 0x6035c
popq %rbx
retq
leaq 0x3cf5e(%rip), %rsi     # 0x9d2c1
movl $0x1, %edx
movq %rax, %rdi
popq %rbx
jmp 0x28689
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/blocked.c
// Function: getTimeoutFromObjectOrReply
int getTimeoutFromObjectOrReply(redisClient *c, robj *object, mstime_t *timeout, int unit) {
    long long tval;

    if (getLongLongFromObjectOrReply(c,object,&tval,
        "timeout is not an integer or out of range") != REDIS_OK)
        return REDIS_ERR;

    if (tval < 0) {
        addReplyError(c,"timeout is negative");
        return REDIS_ERR;
    }

    if (tval > 0) {
        if (unit == UNIT_SECONDS) tval *= 1000;
        tval += mstime();
    }
    *timeout = tval;

    return REDIS_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %ecx, %ebp
movq %rdx, %r14
movq %rdi, %r15
leaq 0x3f7a4(%rip), %rcx     # 0xa0012
movq %rsp, %rdx
callq 0x31355
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0x608bf
movq (%rsp), %rax
testq %rax, %rax
js 0x608a9
xorl %ebx, %ebx
testq %rax, %rax
je 0x608ba
testl %ebp, %ebp
jne 0x6089e
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
movq %rax, (%rsp)
callq 0x23461
addq (%rsp), %rax
jmp 0x608bc
leaq 0x3f78c(%rip), %rsi     # 0xa003c
movq %r15, %rdi
callq 0x2dc63
jmp 0x608bf
xorl %eax, %eax
movq %rax, (%r14)
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/blocked.c
// Function: processUnblockedClients
void processUnblockedClients(void) {
    listNode *ln;
    redisClient *c;

    while (listLength(server.unblocked_clients)) {
        ln = listFirst(server.unblocked_clients);
        redisAssert(ln != NULL);
        c = ln->value;
        listDelNode(server.unblocked_clients,ln);
        c->flags &= ~REDIS_UNBLOCKED;
        c->btype = REDIS_BLOCKED_NONE;

        /* Process remaining data in the input buffer. */
        if (c->querybuf && sdslen(c->querybuf) > 0) {
            server.current_client = c;
            processInputBuffer(c);
            server.current_client = NULL;
        }
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
leaq 0x696b6(%rip), %r14     # 0xc9fa8
movq 0x738(%r14), %rdi
cmpq $0x0, 0x28(%rdi)
je 0x6094d
movq (%rdi), %rsi
testq %rsi, %rsi
je 0x60955
movq 0x10(%rsi), %rbx
callq 0x205b1
andb $0x7f, 0x90(%rbx)
movl $0x0, 0x118(%rbx)
movq 0x20(%rbx), %rax
testq %rax, %rax
je 0x608f2
cmpl $0x0, -0x8(%rax)
je 0x608f2
movq %rbx, 0x1d0(%r14)
movq %rbx, %rdi
callq 0x2ef92
movq $0x0, 0x1d0(%r14)
jmp 0x608f2
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x3869a(%rip), %rdi     # 0x98ff6
leaq 0x3f6ed(%rip), %rsi     # 0xa0050
movl $0x74, %edx
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/blocked.c
// Function: unblockClient
void unblockClient(redisClient *c) {
    if (c->btype == REDIS_BLOCKED_LIST) {
        unblockClientWaitingData(c);
    } else if (c->btype == REDIS_BLOCKED_WAIT) {
        unblockClientWaitingReplicas(c);
    } else {
        redisPanic("Unknown btype in unblockClient().");
    }
    /* Clear the flags, and put the client in the unblocked list so that
     * we'll process new commands in its query buffer ASAP. */
    c->flags &= ~REDIS_BLOCKED;
    c->flags |= REDIS_UNBLOCKED;
    c->btype = REDIS_BLOCKED_NONE;
    server.bpop_blocked_clients--;
    listAddNodeTail(server.unblocked_clients,c);
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movl 0x118(%rdi), %eax
cmpl $0x2, %eax
je 0x60995
cmpl $0x1, %eax
jne 0x609da
movq %rbx, %rdi
callq 0x3af68
jmp 0x6099d
movq %rbx, %rdi
callq 0x35cf6
movl $0xffffff6f, %eax       # imm = 0xFFFFFF6F
andl 0x90(%rbx), %eax
orl $0x80, %eax
movl %eax, 0x90(%rbx)
movl $0x0, 0x118(%rbx)
leaq 0x695e4(%rip), %rax     # 0xc9fa8
decl 0x730(%rax)
movq 0x738(%rax), %rdi
movq %rbx, %rsi
popq %rbx
jmp 0x204cb
leaq 0x3f679(%rip), %rdi     # 0xa005a
leaq 0x3f668(%rip), %rsi     # 0xa0050
movl $0x8c, %edx
callq 0x4cae0
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/blocked.c
// Function: replyToBlockedClientTimedOut
void replyToBlockedClientTimedOut(redisClient *c) {
    if (c->btype == REDIS_BLOCKED_LIST) {
        addReply(c,shared.nullmultibulk);
    } else if (c->btype == REDIS_BLOCKED_WAIT) {
        addReplyLongLong(c,replicationCountAcksByOffset(c->bpop.reploffset));
    } else {
        redisPanic("Unknown btype in replyToBlockedClientTimedOut().");
    }
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movl 0x118(%rdi), %eax
cmpl $0x2, %eax
je 0x60a24
cmpl $0x1, %eax
jne 0x60a3c
leaq 0x69de9(%rip), %rax     # 0xca800
movq 0x58(%rax), %rsi
movq %rbx, %rdi
popq %rbx
jmp 0x2d97c
movq 0x140(%rbx), %rdi
callq 0x35bc7
movslq %eax, %rsi
movq %rbx, %rdi
popq %rbx
jmp 0x2e133
leaq 0x3f63b(%rip), %rdi     # 0xa007e
leaq 0x3f606(%rip), %rsi     # 0xa0050
movl $0xa0, %edx
callq 0x4cae0
movl $0x1, %edi
callq 0x1f3b0
nop
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/hyperloglog.c
// Function: isHLLObjectOrReply
int isHLLObjectOrReply(redisClient *c, robj *o) {
    struct hllhdr *hdr;

    /* Key exists, check type */
    if (checkType(c,o,REDIS_STRING))
        return REDIS_ERR; /* Error already sent. */

    if (stringObjectLen(o) < sizeof(*hdr)) goto invalid;
    hdr = o->ptr;

    /* Magic should be "HYLL". */
    if (hdr->magic[0] != 'H' || hdr->magic[1] != 'Y' ||
        hdr->magic[2] != 'L' || hdr->magic[3] != 'L') goto invalid;

    if (hdr->encoding > HLL_MAX_ENCODING) goto invalid;

    /* Dense representation string length should match exactly. */
    if (hdr->encoding == HLL_DENSE &&
        stringObjectLen(o) != HLL_DENSE_SIZE) goto invalid;

    /* All tests passed. */
    return REDIS_OK;

invalid:
    addReplySds(c,
        sdsnew("-WRONGTYPE Key is not a valid "
               "HyperLogLog string value.\r\n"));
    return REDIS_ERR;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
xorl %edx, %edx
callq 0x30bbf
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0x61a02
movq %r14, %rdi
callq 0x30f42
cmpq $0x10, %rax
jb 0x619e6
movq 0x8(%r14), %rax
cmpb $0x48, (%rax)
jne 0x619e6
cmpb $0x59, 0x1(%rax)
jne 0x619e6
cmpb $0x4c, 0x2(%rax)
jne 0x619e6
cmpb $0x4c, 0x3(%rax)
jne 0x619e6
movb 0x4(%rax), %al
cmpb $0x1, %al
jbe 0x61a09
leaq 0x3e7b0(%rip), %rdi     # 0xa019d
callq 0x28486
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2db20
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ebp, %eax
popq %rbx
popq %r14
popq %rbp
retq
xorl %ebp, %ebp
testb %al, %al
jne 0x61a02
movq %r14, %rdi
callq 0x30f42
cmpq $0x3010, %rax           # imm = 0x3010
jne 0x619e6
jmp 0x61a02