LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O1/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 0x5d529
xorl %r14d, %r14d
cmpq %rdi, 0x30(%rbx)
sete %r14b
leaq 0x41f1d(%rip), %rax     # 0x9f415
leaq 0x41f23(%rip), %rsi     # 0x9f422
cmoveq %rax, %rsi
movq 0xa8(%rdi), %r8
leaq 0x41f1b(%rip), %rcx     # 0x9f42c
xorl %edi, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b66f
movq $0x0, 0x28(%rbx,%r14,8)
orb $0x8, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5d53a
jmp 0x5d4d6
movq 0xb0(%rdi), %rdx
cmpq %rdi, 0x30(%rdx)
leaq 0x41ee7(%rip), %rax     # 0x9f433
leaq 0x41eed(%rip), %rsi     # 0x9f440
cmoveq %rax, %rsi
leaq 0x41aa0(%rip), %rcx     # 0x9effe
xorl %edi, %edi
xorl %eax, %eax
jmp 0x5b66f
// File: /workspace/github_c_makefile_star2_O1/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 0x5d57f
movq 0xf8(%rbx), %rax
movq 0xd8(%rax), %r8
testq %r8, %r8
je 0x5d5af
leaq 0x1f(%rip), %rax        # 0x5d5b1
leaq 0x41eb1(%rip), %rcx     # 0x9f44a
movq %rsi, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x63612
testl %eax, %eax
jne 0x5d5af
incl 0x38(%rbx)
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x6c9ce(%rip), %rcx     # 0xc9fa8
addq $0x58, %rcx
leaq 0x41e6d(%rip), %rdx     # 0x9f452
movq %rsp, %r15
movl $0x40, %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x1f120
leaq -0x4d(%rip), %rsi       # 0x5d5b1
leaq 0x41e5e(%rip), %rcx     # 0x9f463
movq %r14, %rdi
xorl %edx, %edx
movq %r15, %r8
xorl %eax, %eax
callq 0x63612
testl %eax, %eax
jne 0x5d61b
incl 0x38(%rbx)
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: redisAeAttach
static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
    redisContext *c = &(ac->c);
    redisAeEvents *e;

    /* Nothing should be attached when something is already attached */
    if (ac->ev.data != NULL)
        return REDIS_ERR;

    /* Create container for context and r/w events */
    // 创建适配器
    e = (redisAeEvents*)zmalloc(sizeof(*e));
    e->context = ac;
    e->loop = loop;
    e->fd = c->fd;
    e->reading = e->writing = 0;

    /* Register functions to start/stop listening for events */
    // 设置异步调用函数
    ac->ev.addRead = redisAeAddRead;
    ac->ev.delRead = redisAeDelRead;
    ac->ev.addWrite = redisAeAddWrite;
    ac->ev.delWrite = redisAeDelWrite;
    ac->ev.cleanup = redisAeCleanup;
    ac->ev.data = e;

    return REDIS_OK;
}

// Assembly:
cmpq $0x0, 0xb8(%rsi)
je 0x5d808
retq
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movl $0x20, %edi
callq 0x29709
movq %rbx, (%rax)
movq %r14, 0x8(%rax)
movl 0x84(%rbx), %ecx
movl %ecx, 0x10(%rax)
movq $0x0, 0x14(%rax)
leaq 0x2db4(%rip), %rcx      # 0x605ef
movq %rcx, 0xc0(%rbx)
leaq 0x2dd1(%rip), %rcx      # 0x6061a
movq %rcx, 0xc8(%rbx)
leaq 0x2de5(%rip), %rcx      # 0x6063c
movq %rcx, 0xd0(%rbx)
leaq 0x2e02(%rip), %rcx      # 0x60667
movq %rcx, 0xd8(%rbx)
leaq 0x2e16(%rip), %rcx      # 0x60689
movq %rcx, 0xe0(%rbx)
movq %rax, 0xb8(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x9e7(%rip), %rsi       # 0x5e282
leaq 0x3b06c(%rip), %rcx     # 0x9890e
xorl %r14d, %r14d
xorl %edx, %edx
xorl %eax, %eax
callq 0x63612
testl %eax, %eax
jne 0x5d8cb
incl 0x38(%rbx)
movl $0x1, %r14d
cmpq $0x0, 0x60(%rbx)
jne 0x5d8cb
callq 0x232a3
movq %rax, 0x60(%rbx)
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5d95b
movq %rsi, %rbx
callq 0x232a3
movq %rax, 0x50(%r14)
cmpl $0x2, (%rbx)
jne 0x5d95b
cmpq $0x3, 0x20(%rbx)
jne 0x5d95b
movq 0x28(%rbx), %rcx
movq (%rcx), %rax
cmpl $0x1, (%rax)
jne 0x5d95b
movq 0x8(%rcx), %rdx
cmpl $0x1, (%rdx)
jne 0x5d95b
movq 0x10(%rcx), %r14
cmpl $0x1, (%r14)
jne 0x5d95b
movq 0x18(%rax), %rdi
leaq 0x41f90(%rip), %rsi     # 0x9f8c6
callq 0x1f880
testl %eax, %eax
jne 0x5d95b
movq 0x18(%r14), %rbx
leaq 0x6c65e(%rip), %rsi     # 0xc9fa8
addq $0x58, %rsi
movq %rbx, %rdi
callq 0x1f660
testq %rax, %rax
je 0x5d963
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movl 0x10(%r14), %esi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x5e3a5
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelMasterLooksSane
int sentinelMasterLooksSane(sentinelRedisInstance *master) {
    return
        master->flags & SRI_MASTER &&
        master->role_reported == SRI_MASTER &&
        (master->flags & (SRI_S_DOWN|SRI_O_DOWN)) == 0 &&
        (mstime() - master->info_refresh) < SENTINEL_INFO_PERIOD*2;
}

// Assembly:
movl (%rdi), %ecx
xorl %eax, %eax
testb $0x1, %cl
je 0x5d9ad
testb $0x30, %cl
jne 0x5d9ad
pushq %rbx
movq %rdi, %rbx
cmpl $0x1, 0xa8(%rdi)
jne 0x5d9ac
callq 0x232a3
movq %rax, %rcx
subq 0xa0(%rbx), %rcx
xorl %eax, %eax
cmpq $0x4e20, %rcx           # imm = 0x4E20
setl %al
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x2fe12
testq %r15, %r15
jne 0x5e1f1
movl $0x454e4f, (%rsp)       # imm = 0x454E4F
leaq 0x41b28(%rip), %r15     # 0x9fd19
movq 0x28(%rbx), %rdi
leaq -0xc4b(%rip), %rsi      # 0x5d5b1
leaq 0x41b19(%rip), %rcx     # 0x9fd1c
xorl %r14d, %r14d
movq %rsp, %r9
xorl %edx, %edx
movq %r15, %r8
xorl %eax, %eax
callq 0x63612
cmpl $-0x1, %eax
je 0x5e241
incl 0x38(%rbx)
movq 0x28(%rbx), %rdi
leaq -0xc77(%rip), %rsi      # 0x5d5b1
leaq 0x3c1a9(%rip), %rcx     # 0x9a3d8
xorl %edx, %edx
xorl %eax, %eax
callq 0x63612
testl %eax, %eax
jne 0x5e247
incl 0x38(%rbx)
jmp 0x5e247
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movl %r14d, %eax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5e263
decl 0x38(%rdi)
testq %rdi, %rdi
sete %al
testq %rsi, %rsi
sete %cl
orb %al, %cl
jne 0x5e281
cmpl $0x1, (%rsi)
jne 0x5e281
movq 0x18(%rsi), %rsi
jmp 0x5d9ae
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5e296
decl 0x38(%r14)
testq %r14, %r14
sete %al
testq %rsi, %rsi
sete %cl
orb %al, %cl
jne 0x5e36d
movl (%rsi), %eax
addl $-0x5, %eax
cmpl $0x1, %eax
ja 0x5e364
movq 0x18(%rsi), %rbx
leaq 0x3a2e5(%rip), %rsi     # 0x985a8
movl $0x4, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5e353
leaq 0x4133f(%rip), %rsi     # 0x9f61a
movl $0x7, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5e353
leaq 0x4132f(%rip), %rsi     # 0x9f622
movl $0xa, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
je 0x5e353
leaq 0x41322(%rip), %rsi     # 0x9f62d
movl $0x4, %edx
movq %rbx, %rdi
callq 0x1f340
testl %eax, %eax
jne 0x5e364
movl $0x2010, %eax           # imm = 0x2010
andl (%r14), %eax
cmpl $0x10, %eax
jne 0x5e364
movq 0x28(%r14), %rdi
leaq -0xd83(%rip), %rsi      # 0x5d5b1
leaq 0x412f7(%rip), %rcx     # 0x9f632
xorl %edx, %edx
xorl %eax, %eax
callq 0x63612
testl %eax, %eax
jne 0x5e34c
incl 0x38(%r14)
orb $0x20, 0x1(%r14)
jmp 0x5e364
callq 0x232a3
movq %rax, 0x58(%r14)
movq $0x0, 0x60(%r14)
callq 0x232a3
movq %rax, 0x68(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5e385
decl 0x38(%rbx)
testq %rbx, %rbx
sete %al
testq %rsi, %rsi
sete %cl
orb %al, %cl
jne 0x5e3a3
cmpl $0x6, (%rsi)
je 0x5e3a3
callq 0x232a3
movq %rax, 0x70(%rbx)
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O1/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, %r15
jne 0x5e65b
movq 0xf8(%rbx), %r15
testb $-0x80, (%r15)
je 0x5e677
movq 0x158(%r15), %rax
testq %rax, %rax
je 0x5e677
cmpl $0x4, 0x130(%r15)
jg 0x5e67a
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 0x21da1
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
cmpl $-0x1, %eax
je 0x5e72f
testb $0x8, (%rbx)
jne 0x5e72f
leaq 0x6b8f3(%rip), %r9      # 0xc9fa8
movl 0x88(%r9), %r8d
movl 0x8(%r12), %r10d
subq $0x8, %rsp
addq $0x58, %r9
leaq 0x40fe0(%rip), %rdx     # 0x9f6b0
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 0x801f0(%rip)           # 0xde8e8
callq 0x1f120
addq $0x30, %rsp
movq 0x28(%rbx), %rdi
leaq -0x397(%rip), %rsi      # 0x5e375
leaq 0x40fb9(%rip), %rcx     # 0x9f6cc
leaq 0x40d9d(%rip), %r8      # 0x9f4b7
xorl %edx, %edx
movq %r14, %r9
xorl %eax, %eax
callq 0x63612
testl %eax, %eax
jne 0x5e72f
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_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: addReplyDictOfRedisInstances
void addReplyDictOfRedisInstances(redisClient *c, dict *instances) {
    dictIterator *di;
    dictEntry *de;

    di = dictGetIterator(instances);
    addReplyMultiBulkLen(c,dictSize(instances));
    while((de = dictNext(di)) != NULL) {
        sentinelRedisInstance *ri = dictGetVal(de);

        addReplySentinelRedisInstance(c,ri);
    }
    dictReleaseIterator(di);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x228b5
movq %rax, %r14
movq 0x48(%r15), %rsi
addq 0x28(%r15), %rsi
movq %rbx, %rdi
callq 0x2ded8
movq %r14, %rdi
callq 0x22913
testq %rax, %rax
je 0x5eede
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x5e81b
jmp 0x5eec3
movq %r14, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x229b9
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelVoteLeader
char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char *req_runid, uint64_t *leader_epoch) {
    if (req_epoch > sentinel.current_epoch) {
        sentinel.current_epoch = req_epoch;
        sentinelFlushConfig();
        sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
            (unsigned long long) sentinel.current_epoch);
    }

    if (master->leader_epoch < req_epoch && sentinel.current_epoch <= req_epoch)
    {
        sdsfree(master->leader);
        master->leader = sdsnew(req_runid);
        master->leader_epoch = sentinel.current_epoch;
        sentinelFlushConfig();
        sentinelEvent(REDIS_WARNING,"+vote-for-leader",master,"%s %llu",
            master->leader, (unsigned long long) master->leader_epoch);
        /* If we did not voted for ourselves, set the master failover start
         * time to now, in order to force a delay before we can start a
         * failover for the same master. */
        if (strcasecmp(master->leader,server.runid))
            master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
    }

    *leader_epoch = master->leader_epoch;
    return master->leader ? sdsnew(master->leader) : NULL;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
cmpq %rsi, 0x7f9ae(%rip)     # 0xde8e8
jae 0x5ef6c
movq %r12, 0x7f9a5(%rip)     # 0xde8e8
callq 0x5cac1
movq 0x7f999(%rip), %r8      # 0xde8e8
leaq 0x4071d(%rip), %rsi     # 0x9f673
leaq 0x40467(%rip), %rcx     # 0x9f3c4
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x5b66f
cmpq %r12, 0x120(%r14)
jae 0x5f031
cmpq %r12, 0x7f968(%rip)     # 0xde8e8
ja 0x5f031
movq 0x118(%r14), %rdi
callq 0x28204
movq %r15, %rdi
callq 0x281da
movq %rax, 0x118(%r14)
movq 0x7f940(%rip), %rax     # 0xde8e8
movq %rax, 0x120(%r14)
callq 0x5cac1
movq 0x118(%r14), %r8
movq 0x120(%r14), %r9
leaq 0x40d09(%rip), %rsi     # 0x9fcd2
leaq 0x40374(%rip), %rcx     # 0x9f344
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x5b66f
movq 0x118(%r14), %rdi
leaq 0x6afbb(%rip), %rsi     # 0xc9fa8
addq $0x58, %rsi
callq 0x1f2e0
testl %eax, %eax
je 0x5f031
callq 0x232a3
movq %rax, %r15
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 %r15, %rax
movq %rax, 0x140(%r14)
movq 0x120(%r14), %rax
movq %rax, (%rbx)
movq 0x118(%r14), %rdi
testq %rdi, %rdi
je 0x5f057
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x281da
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5f259
movq %rdi, %rbx
movl $0x1, 0x130(%rdi)
orl $0x80, %eax
movl %eax, (%rdi)
movq 0x7f725(%rip), %r8      # 0xde8e8
incq %r8
movq %r8, 0x7f71b(%rip)      # 0xde8e8
movq %r8, 0x128(%rdi)
leaq 0x40498(%rip), %rsi     # 0x9f673
leaq 0x401e2(%rip), %rcx     # 0x9f3c4
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b66f
leaq 0x40b4d(%rip), %rsi     # 0x9fd45
leaq 0x3fdff(%rip), %rcx     # 0x9effe
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b66f
callq 0x232a3
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 0x232a3
movq %rax, 0x138(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x40aca(%rip), %rdi     # 0x9fd2a
leaq 0x3fb4d(%rip), %rsi     # 0x9edb4
movl $0x1065, %edx           # imm = 0x1065
callq 0x4d037
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/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 %rsi, %rbx
movq 0xb0(%rdi), %r14
testq %r14, %r14
je 0x5f81f
decl 0x38(%r14)
testq %r14, %r14
sete %al
testq %rbx, %rbx
sete %cl
orb %al, %cl
jne 0x5f91f
cmpl $0x2, (%rbx)
jne 0x5f91f
cmpq $0x3, 0x20(%rbx)
jne 0x5f91f
movq 0x28(%rbx), %rax
movq (%rax), %rcx
cmpl $0x3, (%rcx)
jne 0x5f91f
movq 0x8(%rax), %rcx
cmpl $0x1, (%rcx)
jne 0x5f91f
movq 0x10(%rax), %rax
cmpl $0x3, (%rax)
jne 0x5f91f
callq 0x232a3
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), %rdi
leaq 0x34f89(%rip), %rsi     # 0x94834
callq 0x1f880
testl %eax, %eax
je 0x5f91f
movq 0x118(%r14), %rdi
callq 0x28204
movq 0x28(%rbx), %rax
movq 0x10(%rax), %rcx
movq 0x8(%rcx), %r8
cmpq %r8, 0x120(%r14)
je 0x5f8f4
movq 0x8(%r14), %rdx
movq 0x8(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0x403a7(%rip), %rsi     # 0x9fc8f
movl $0x3, %edi
xorl %eax, %eax
callq 0x23064
movq 0x28(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
callq 0x281da
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_O1/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 0x224dc
testq %rax, %rax
je 0x5fa6c
movq %rax, %rcx
movq 0x8(%rax), %rax
incq %rax
movq %rax, 0x8(%rcx)
jmp 0x5fa89
movq %r14, %rdi
movq %rbx, %rsi
callq 0x222f9
testq %rax, %rax
je 0x5fa91
movq $0x1, 0x8(%rax)
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x37c0a(%rip), %rdi     # 0x976a2
leaq 0x3f315(%rip), %rsi     # 0x9edb4
movl $0xfc2, %edx            # imm = 0xFC2
callq 0x4d037
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelStartFailoverIfNeeded
int sentinelStartFailoverIfNeeded(sentinelRedisInstance *master) {

    /* We can't failover if the master is not in O_DOWN state. */
    if (!(master->flags & SRI_O_DOWN)) return 0;

    /* Failover already in progress? */
    if (master->flags & SRI_FAILOVER_IN_PROGRESS) return 0;

    /* Last failover attempt started too little time ago? */
    if (mstime() - master->failover_start_time <
        master->failover_timeout*2)
    {
        if (master->failover_delay_logged != master->failover_start_time) {
            time_t clock = (master->failover_start_time +
                            master->failover_timeout*2) / 1000;
            char ctimebuf[26];

            ctime_r(&clock,ctimebuf);
            ctimebuf[24] = '\0'; /* Remove newline. */
            master->failover_delay_logged = master->failover_start_time;
            redisLog(REDIS_WARNING,
                "Next failover delay: I will not start a failover before %s",
                ctimebuf);
        }
        return 0;
    }

    // 开始一次故障转移
    sentinelStartFailover(master);

    return 1;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x30, %rsp
movl $0xa0, %eax
andl (%rdi), %eax
xorl %ebp, %ebp
cmpl $0x20, %eax
jne 0x5fd14
movq %rdi, %rbx
callq 0x232a3
movq %rax, %rcx
movq 0x140(%rbx), %rdx
movq 0x148(%rbx), %rax
subq %rdx, %rcx
addq %rax, %rax
cmpq %rax, %rcx
jge 0x5fd07
cmpq %rdx, 0x150(%rbx)
je 0x5fd14
addq %rdx, %rax
movabsq $0x20c49ba5e353f7cf, %rcx # imm = 0x20C49BA5E353F7CF
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x7, %rdx
addq %rax, %rdx
leaq 0x8(%rsp), %rdi
movq %rdx, (%rdi)
leaq 0x10(%rsp), %r14
movq %r14, %rsi
callq 0x1fb40
movb $0x0, 0x18(%r14)
movq 0x140(%rbx), %rax
movq %rax, 0x150(%rbx)
leaq 0x4005f(%rip), %rsi     # 0x9fd53
xorl %ebp, %ebp
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x23064
jmp 0x5fd14
movq %rbx, %rdi
callq 0x5f19a
movl $0x1, %ebp
movl %ebp, %eax
addq $0x30, %rsp
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5fd89
movq 0x110(%rdx), %rsi
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rsi, 0x110(%rcx)
ja 0x5fd89
movl $0x1, %eax
jb 0x5fd89
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_O1/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 0x5fab3
movq %rax, %r14
testq %rax, %rax
je 0x5fdc8
leaq 0x6a1fc(%rip), %rsi     # 0xc9fa8
addq $0x58, %rsi
movq %r14, %rdi
callq 0x1f2e0
movl %eax, %ebp
movq %r14, %rdi
callq 0x28204
testl %ebp, %ebp
jne 0x5fdd0
jmp 0x5fe26
movq %r14, %rdi
callq 0x28204
testb $0x10, 0x1(%rbx)
jne 0x5fe26
movq 0x148(%rbx), %rax
movl $0x2710, %ecx           # imm = 0x2710
cmpq %rcx, %rax
movslq %eax, %r14
cmovgeq %rcx, %r14
callq 0x232a3
subq 0x140(%rbx), %rax
cmpq %r14, %rax
jle 0x5fe79
leaq 0x3ff8a(%rip), %rsi     # 0x9fd8e
leaq 0x3f1f3(%rip), %rcx     # 0x9effe
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b66f
movq %rbx, %rdi
popq %rbx
popq %r14
popq %rbp
jmp 0x5fe7e
leaq 0x3ff7d(%rip), %rsi     # 0x9fdaa
leaq 0x3f1ca(%rip), %r14     # 0x9effe
movl $0x3, %edi
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x5b66f
movl $0x2, 0x130(%rbx)
callq 0x232a3
movq %rax, 0x138(%rbx)
leaq 0x3ff57(%rip), %rsi     # 0x9fdba
movl $0x3, %edi
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
jmp 0x5b66f
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x5fecb
movq %rdi, %rbx
cmpl $0x5, 0x130(%rdi)
jge 0x5fee0
andl $0xffffef7f, %eax       # imm = 0xFFFFEF7F
movl %eax, (%rbx)
movl $0x0, 0x130(%rbx)
callq 0x232a3
movq %rax, 0x138(%rbx)
movq 0x158(%rbx), %rax
testq %rax, %rax
je 0x5fec9
andb $-0x2, 0x1(%rax)
movq $0x0, 0x158(%rbx)
popq %rbx
retq
leaq 0x3ffff(%rip), %rdi     # 0x9fed1
leaq 0x3eedb(%rip), %rsi     # 0x9edb4
movl $0x12d4, %edx           # imm = 0x12D4
jmp 0x5fef3
leaq 0x4000f(%rip), %rdi     # 0x9fef6
leaq 0x3eec6(%rip), %rsi     # 0x9edb4
movl $0x12d5, %edx           # imm = 0x12D5
callq 0x4d037
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/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 0x5f065
testq %rax, %rax
je 0x5ff77
movq %rax, %r14
leaq 0x3fed7(%rip), %rsi     # 0x9fdf5
leaq 0x3f0d9(%rip), %r15     # 0x9effe
movl $0x3, %edi
movq %rax, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x5b66f
orb $0x1, 0x1(%r14)
movq %r14, 0x158(%rbx)
movl $0x3, 0x130(%rbx)
callq 0x232a3
movq %rax, 0x138(%rbx)
leaq 0x3fea5(%rip), %rsi     # 0x9fe05
movl $0x2, %edi
movq %r14, %rdx
movq %r15, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
jmp 0x5b66f
leaq 0x3fe59(%rip), %rsi     # 0x9fdd7
leaq 0x3f079(%rip), %rcx     # 0x9effe
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b66f
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x5fe7e
// File: /workspace/github_c_makefile_star2_O1/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 0x232a3
subq 0x138(%rbx), %rax
cmpq 0x148(%rbx), %rax
jle 0x60073
leaq 0x3fdd4(%rip), %rsi     # 0x9fe28
leaq 0x3efa3(%rip), %rcx     # 0x9effe
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b66f
movq %rbx, %rdi
popq %rbx
jmp 0x5fe7e
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x3f2f6(%rip), %rsi     # 0x9f692
leaq 0x3f2fe(%rip), %rcx     # 0x9f6a1
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
pushq %r15
pushq (%r11)
pushq %r10
callq 0x5b66f
addq $0x20, %rsp
movq 0x20(%r14), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x5c8e9
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: redisAeAddRead
static void redisAeAddRead(void *privdata) {
    redisAeEvents *e = (redisAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    // 如果读事件处理器未安装，那么进行安装
    if (!e->reading) {
        e->reading = 1;
        aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
    }
}

// Assembly:
cmpl $0x0, 0x14(%rdi)
je 0x605f6
retq
movq %rdi, %r8
movq 0x8(%rdi), %rdi
movl $0x1, 0x14(%r8)
movl 0x10(%r8), %esi
leaq 0xc2(%rip), %rcx        # 0x606d2
movl $0x1, %edx
jmp 0x209d7
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: redisAeDelRead
static void redisAeDelRead(void *privdata) {
    redisAeEvents *e = (redisAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    // 仅在读事件处理器已安装的情况下进行删除
    if (e->reading) {
        e->reading = 0;
        aeDeleteFileEvent(loop,e->fd,AE_READABLE);
    }
}

// Assembly:
cmpl $0x0, 0x14(%rdi)
je 0x6063b
movq 0x8(%rdi), %rax
movl $0x0, 0x14(%rdi)
movl 0x10(%rdi), %esi
movq %rax, %rdi
movl $0x1, %edx
jmp 0x20a9d
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: redisAeAddWrite
static void redisAeAddWrite(void *privdata) {
    redisAeEvents *e = (redisAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    if (!e->writing) {
        e->writing = 1;
        aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
    }
}

// Assembly:
cmpl $0x0, 0x18(%rdi)
je 0x60643
retq
movq %rdi, %r8
movq 0x8(%rdi), %rdi
movl $0x1, 0x18(%r8)
movl 0x10(%r8), %esi
leaq 0x7d(%rip), %rcx        # 0x606da
movl $0x2, %edx
jmp 0x209d7
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: redisAeDelWrite
static void redisAeDelWrite(void *privdata) {
    redisAeEvents *e = (redisAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    if (e->writing) {
        e->writing = 0;
        aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
    }
}

// Assembly:
cmpl $0x0, 0x18(%rdi)
je 0x60688
movq 0x8(%rdi), %rax
movl $0x0, 0x18(%rdi)
movl 0x10(%rdi), %esi
movq %rax, %rdi
movl $0x2, %edx
jmp 0x20a9d
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: redisAeCleanup
static void redisAeCleanup(void *privdata) {
    redisAeEvents *e = (redisAeEvents*)privdata;
    redisAeDelRead(privdata);
    redisAeDelWrite(privdata);
    zfree(e);
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
cmpl $0x0, 0x14(%rdi)
je 0x606ab
movq 0x8(%rbx), %rdi
movl $0x0, 0x14(%rbx)
movl 0x10(%rbx), %esi
movl $0x1, %edx
callq 0x20a9d
cmpl $0x0, 0x18(%rbx)
je 0x606c9
movq 0x8(%rbx), %rdi
movl $0x0, 0x18(%rbx)
movl 0x10(%rbx), %esi
movl $0x2, %edx
callq 0x20a9d
movq %rbx, %rdi
popq %rbx
jmp 0x2984b
// File: /workspace/github_c_makefile_star2_O1/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 0x3f877(%rip), %rcx     # 0x9ff64
movzbl (%rdi), %edx
cmpl $0x64, %edx
jle 0x60716
cmpl $0x72, %edx
jg 0x6072c
addl $-0x65, %edx
cmpl $0x7, %edx
ja 0x60791
movslq (%rcx,%rdx,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
movl $0x200, %esi            # imm = 0x200
jmp 0x60782
cmpl $0x44, %edx
jg 0x60742
cmpl $0x24, %edx
je 0x6077d
movl $0x3fc, %esi            # imm = 0x3FC
cmpl $0x41, %edx
je 0x60782
jmp 0x6078c
cmpl $0x73, %edx
je 0x60776
cmpl $0x78, %edx
je 0x6076f
cmpl $0x7a, %edx
jne 0x60791
movl $0x80, %esi
jmp 0x60782
cmpl $0x45, %edx
je 0x60768
cmpl $0x4b, %edx
jne 0x60791
movl $0x1, %esi
jmp 0x60782
movl $0x4, %esi
jmp 0x60782
movl $0x10, %esi
jmp 0x60782
movl $0x40, %esi
jmp 0x60782
movl $0x2, %esi
jmp 0x60782
movl $0x100, %esi            # imm = 0x100
jmp 0x60782
movl $0x20, %esi
jmp 0x60782
movl $0x8, %esi
incq %rdi
orl %esi, %eax
jmp 0x606ed
testl %edx, %edx
jne 0x60791
retq
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
retq
// File: /workspace/github_c_makefile_star2_O1/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 0x281b2
movl %ebx, %ecx
notl %ecx
testl $0x3fc, %ecx            # imm = 0x3FC
jne 0x607b7
leaq 0x42bea(%rip), %rsi     # 0xa339c
jmp 0x60873
testb $0x4, %bl
je 0x607d0
leaq 0x40e51(%rip), %rsi     # 0xa1614
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb $0x8, %bl
je 0x607e9
leaq 0x3f7a8(%rip), %rsi     # 0x9ff84
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb $0x10, %bl
je 0x60802
leaq 0x3ce15(%rip), %rsi     # 0x9d60a
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb $0x20, %bl
je 0x6081b
leaq 0x3ec05(%rip), %rsi     # 0x9f413
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb $0x40, %bl
je 0x60834
leaq 0x3603c(%rip), %rsi     # 0x96863
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb %bl, %bl
jns 0x6084c
leaq 0x39322(%rip), %rsi     # 0x99b61
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
btl $0x8, %ebx
jae 0x60866
leaq 0x36363(%rip), %rsi     # 0x96bbc
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
btl $0x9, %ebx
jae 0x60880
leaq 0x41a01(%rip), %rsi     # 0xa2274
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb $0x1, %bl
je 0x60899
leaq 0x3d81f(%rip), %rsi     # 0x9e0ab
movl $0x1, %edx
movq %rax, %rdi
callq 0x28380
testb $0x2, %bl
jne 0x608a0
popq %rbx
retq
leaq 0x3c9da(%rip), %rsi     # 0x9d281
movl $0x1, %edx
movq %rax, %rdi
popq %rbx
jmp 0x28380
// File: /workspace/github_c_makefile_star2_O1/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, %rbx
movq %rdi, %r15
leaq 0x3f214(%rip), %rcx     # 0x9ffa2
movq %rsp, %rdx
callq 0x31082
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0x60dde
movq (%rsp), %rax
testq %rax, %rax
js 0x60dcf
je 0x60dc3
testl %ebp, %ebp
jne 0x60dba
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
movq %rax, (%rsp)
callq 0x232a3
addq %rax, (%rsp)
movq (%rsp), %rax
movq %rax, (%rbx)
xorl %r14d, %r14d
jmp 0x60dde
leaq 0x3f1f6(%rip), %rsi     # 0x9ffcc
movq %r15, %rdi
callq 0x2d9d7
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq