// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/redis.c
// Function: initServer
void initServer() {
    int j;

    // 设置信号处理函数
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    setupSignalHandlers();

    // 设置 syslog
    if (server.syslog_enabled) {
        openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
            server.syslog_facility);
    }

    // 初始化并创建数据结构
    server.current_client = NULL;
    server.clients = listCreate();
    server.clients_to_close = listCreate();
    server.slaves = listCreate();
    server.monitors = listCreate();
    server.slaveseldb = -1; /* Force to emit the first SELECT command. */
    server.unblocked_clients = listCreate();
    server.ready_keys = listCreate();
    server.clients_waiting_acks = listCreate();
    server.get_ack_from_slaves = 0;
    server.clients_paused = 0;

    // 创建共享对象
    createSharedObjects();
    adjustOpenFilesLimit();
    server.el = aeCreateEventLoop(server.maxclients+REDIS_EVENTLOOP_FDSET_INCR);
    server.db = zmalloc(sizeof(redisDb)*server.dbnum);

    /* Open the TCP listening socket for the user commands. */
    // 打开 TCP 监听端口，用于等待客户端的命令请求
    if (server.port != 0 &&
        listenToPort(server.port,server.ipfd,&server.ipfd_count) == REDIS_ERR)
        exit(1);

    /* Open the listening Unix domain socket. */
    // 打开 UNIX 本地端口
    if (server.unixsocket != NULL) {
        unlink(server.unixsocket); /* don't care if this fails */
        server.sofd = anetUnixServer(server.neterr,server.unixsocket,
            server.unixsocketperm, server.tcp_backlog);
        if (server.sofd == ANET_ERR) {
            redisLog(REDIS_WARNING, "Opening socket: %s", server.neterr);
            exit(1);
        }
        anetNonBlock(NULL,server.sofd);
    }

    /* Abort if there are no listening sockets at all. */
    if (server.ipfd_count == 0 && server.sofd < 0) {
        redisLog(REDIS_WARNING, "Configured to not listen anywhere, exiting.");
        exit(1);
    }

    /* Create the Redis databases, and initialize other internal state. */
    // 创建并初始化数据库结构
    for (j = 0; j < server.dbnum; j++) {
        server.db[j].dict = dictCreate(&dbDictType,NULL);
        server.db[j].expires = dictCreate(&keyptrDictType,NULL);
        server.db[j].blocking_keys = dictCreate(&keylistDictType,NULL);
        server.db[j].ready_keys = dictCreate(&setDictType,NULL);
        server.db[j].watched_keys = dictCreate(&keylistDictType,NULL);
        server.db[j].eviction_pool = evictionPoolAlloc();
        server.db[j].id = j;
        server.db[j].avg_ttl = 0;
    }

    // 创建 PUBSUB 相关结构
    server.pubsub_channels = dictCreate(&keylistDictType,NULL);
    server.pubsub_patterns = listCreate();
    listSetFreeMethod(server.pubsub_patterns,freePubsubPattern);
    listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern);

    server.cronloops = 0;
    server.rdb_child_pid = -1;
    server.aof_child_pid = -1;
    aofRewriteBufferReset();
    server.aof_buf = sdsempty();
    server.lastsave = time(NULL); /* At startup we consider the DB saved. */
    server.lastbgsave_try = 0;    /* At startup we never tried to BGSAVE. */
    server.rdb_save_time_last = -1;
    server.rdb_save_time_start = -1;
    server.dirty = 0;
    resetServerStats();
    /* A few stats we don't want to reset: server startup time, and peak mem. */
    server.stat_starttime = time(NULL);
    server.stat_peak_memory = 0;
    server.resident_set_size = 0;
    server.lastbgsave_status = REDIS_OK;
    server.aof_last_write_status = REDIS_OK;
    server.aof_last_write_errno = 0;
    server.repl_good_slaves_count = 0;
    updateCachedTime();

    /* Create the serverCron() time event, that's our main way to process
     * background operations. */
    // 为 serverCron() 创建时间事件
    if(aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) {
        redisPanic("Can't create the serverCron time event.");
        exit(1);
    }

    /* Create an event handler for accepting new connections in TCP and Unix
     * domain sockets. */
    // 为 TCP 连接关联连接应答（accept）处理器
    // 用于接受并应答客户端的 connect() 调用
    for (j = 0; j < server.ipfd_count; j++) {
        if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE,
            acceptTcpHandler,NULL) == AE_ERR)
            {
                redisPanic(
                    "Unrecoverable error creating server.ipfd file event.");
            }
    }

    // 为本地套接字关联应答处理器
    if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE,
        acceptUnixHandler,NULL) == AE_ERR) redisPanic("Unrecoverable error creating server.sofd file event.");

    /* Open the AOF file if needed. */
    // 如果 AOF 持久化功能已经打开，那么打开或创建一个 AOF 文件
    if (server.aof_state == REDIS_AOF_ON) {
        server.aof_fd = open(server.aof_filename,
                               O_WRONLY|O_APPEND|O_CREAT,0644);
        if (server.aof_fd == -1) {
            redisLog(REDIS_WARNING, "Can't open the append-only file: %s",
                strerror(errno));
            exit(1);
        }
    }

    /* 32 bit instances are limited to 4GB of address space, so if there is
     * no explicit limit in the user provided configuration we set a limit
     * at 3 GB using maxmemory with 'noeviction' policy'. This avoids
     * useless crashes of the Redis instance for out of memory. */
    // 对于 32 位实例来说，默认将最大可用内存限制在 3 GB
    if (server.arch_bits == 32 && server.maxmemory == 0) {
        redisLog(REDIS_WARNING,"Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.");
        server.maxmemory = 3072LL*(1024*1024); /* 3 GB */
        server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
    }

    // 如果服务器以 cluster 模式打开，那么初始化 cluster
    if (server.cluster_enabled) clusterInit();

    // 初始化复制功能有关的脚本缓存
    replicationScriptCacheInit();

    // 初始化脚本系统
    scriptingInit();

    // 初始化慢查询功能
    slowlogInit();

    // 初始化 BIO 系统
    bioInit();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl $0x1, %esi
movl $0x1, %edi
callq 0x1f770
movl $0x1, %esi
movl $0xd, %edi
callq 0x1f770
callq 0x25864
cmpl $0x0, 0xa5277(%rip)     # 0xca580
je 0x25322
movq 0xa5276(%rip), %rdi     # 0xca588
movl 0xa5278(%rip), %edx     # 0xca590
movl $0x19, %esi
callq 0x1f290
movq $0x0, 0xa4e4b(%rip) # 0xca178
callq 0x2038c
movq %rax, 0xa4e1f(%rip)     # 0xca158
callq 0x2038c
movq %rax, 0xa4e1b(%rip)     # 0xca160
callq 0x2038c
movq %rax, 0xa4e17(%rip)     # 0xca168
callq 0x2038c
movq %rax, 0xa4e13(%rip)     # 0xca170
movl $0xffffffff, 0xa522d(%rip) # imm = 0xFFFFFFFF
callq 0x2038c
movq %rax, 0xa536d(%rip)     # 0xca6e0
callq 0x2038c
movq %rax, 0xa5369(%rip)     # 0xca6e8
callq 0x2038c
movq %rax, 0xa532d(%rip)     # 0xca6b8
xorl %eax, %eax
movl %eax, 0xa532d(%rip)     # 0xca6c0
movl %eax, 0xa4de7(%rip)     # 0xca180
callq 0x24300
callq 0x24f6a
movl 0xa531b(%rip), %edi     # 0xca6c4
subl $-0x80, %edi
callq 0x207c0
movq %rax, 0xa4c18(%rip)     # 0xc9fd0
movslq 0xa5069(%rip), %rdi     # 0xca428
shlq $0x6, %rdi
callq 0x29709
movq %rax, 0xa4be9(%rip)     # 0xc9fb8
movl 0xa4c5b(%rip), %edi     # 0xca030
testl %edi, %edi
je 0x253f5
leaq 0xa4cec(%rip), %rsi     # 0xca0cc
leaq 0xa4d25(%rip), %rdx     # 0xca10c
callq 0x250db
cmpl $-0x1, %eax
je 0x2585a
movq 0xa4cc4(%rip), %rdi     # 0xca0c0
testq %rdi, %rdi
je 0x2543d
callq 0x1f3a0
movq 0xa4cb3(%rip), %rsi     # 0xca0c0
movl 0xa4cb5(%rip), %edx     # 0xca0c8
movl 0xa4c1b(%rip), %ecx     # 0xca034
leaq 0xa4d70(%rip), %rdi     # 0xca190
callq 0x21acc
movl %eax, 0xa4ce5(%rip)     # 0xca110
cmpl $-0x1, %eax
je 0x2580e
xorl %edi, %edi
movl %eax, %esi
callq 0x21120
cmpl $0x0, 0xa4cc8(%rip)     # 0xca10c
jne 0x25453
cmpl $0x0, 0xa4cc3(%rip)     # 0xca110
js 0x257e4
cmpl $0x0, 0xa4fce(%rip)     # 0xca428
jle 0x25536
xorl %ebp, %ebp
leaq 0xa44c7(%rip), %r14     # 0xc9930
leaq 0xa4550(%rip), %r15     # 0xc99c0
leaq 0xa43f9(%rip), %r12     # 0xc9870
xorl %ebx, %ebx
leaq 0xa4450(%rip), %rdi     # 0xc98d0
xorl %esi, %esi
callq 0x21f97
movq 0xa4b2a(%rip), %rcx     # 0xc9fb8
movq %rax, (%rcx,%rbp)
movq %r14, %rdi
xorl %esi, %esi
callq 0x21f97
movq 0xa4b15(%rip), %rcx     # 0xc9fb8
movq %rax, 0x8(%rcx,%rbp)
movq %r15, %rdi
xorl %esi, %esi
callq 0x21f97
movq 0xa4aff(%rip), %rcx     # 0xc9fb8
movq %rax, 0x10(%rcx,%rbp)
movq %r12, %rdi
xorl %esi, %esi
callq 0x21f97
movq 0xa4ae9(%rip), %rcx     # 0xc9fb8
movq %rax, 0x18(%rcx,%rbp)
movq %r15, %rdi
xorl %esi, %esi
callq 0x21f97
movq 0xa4ad3(%rip), %rcx     # 0xc9fb8
movq %rax, 0x20(%rcx,%rbp)
movl $0x100, %edi            # imm = 0x100
callq 0x29709
movq %rax, %r13
movl $0x100, %edx            # imm = 0x100
movq %rax, %rdi
xorl %esi, %esi
callq 0x1f110
movq 0xa4aab(%rip), %rax     # 0xc9fb8
movq %r13, 0x28(%rax,%rbp)
movl %ebx, 0x30(%rax,%rbp)
movq $0x0, 0x38(%rax,%rbp)
incq %rbx
movslq 0xa4eff(%rip), %rax     # 0xca428
addq $0x40, %rbp
cmpq %rax, %rbx
jl 0x25479
leaq 0xa4483(%rip), %rdi     # 0xc99c0
xorl %r14d, %r14d
xorl %esi, %esi
callq 0x21f97
movq %rax, 0xa5202(%rip)     # 0xca750
callq 0x2038c
movq %rax, 0xa51fe(%rip)     # 0xca758
leaq 0x26223(%rip), %rcx     # 0x4b784
movq %rcx, 0x18(%rax)
leaq 0x2622e(%rip), %rcx     # 0x4b79a
movq %rcx, 0x20(%rax)
movl %r14d, 0xa4a85(%rip)    # 0xc9ffc
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, 0xa4f96(%rip)     # 0xca518
movl %eax, 0xa4f24(%rip)     # 0xca4ac
callq 0x49364
callq 0x281b2
movq %rax, 0xa4f1f(%rip)     # 0xca4b8
xorl %edi, %edi
callq 0x1fc50
movq %rax, 0xa4f99(%rip)     # 0xca540
movq %r14, 0xa4f9a(%rip)     # 0xca548
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0xa4f96(%rip)    # 0xca550
movq %r14, 0xa4f47(%rip)     # 0xca508
pxor %xmm0, %xmm0
movdqu %xmm0, 0xa4d23(%rip)    # 0xca2f0
movdqu %xmm0, 0xa4d2b(%rip)    # 0xca300
movdqu %xmm0, 0xa4d33(%rip)    # 0xca310
movdqu %xmm0, 0xa4d43(%rip)    # 0xca328
movdqu %xmm0, 0xa4d4b(%rip)    # 0xca338
movq %r14, 0xa4d54(%rip)     # 0xca348
leaq 0xa4d8d(%rip), %rdi     # 0xca388
movl $0x84, %edx
xorl %esi, %esi
callq 0x1f110
leaq 0x8(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1f2f0
imulq $0xf4240, (%rbx), %rax  # imm = 0xF4240
addq 0x8(%rbx), %rax
movabsq $0x20c49ba5e353f7cf, %rcx # imm = 0x20C49BA5E353F7CF
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x7, %rdx
addq %rax, %rdx
movq %rdx, 0xa4d35(%rip)     # 0xca378
movq %r14, 0xa4d36(%rip)     # 0xca380
xorl %edi, %edi
callq 0x1fc50
movq %rax, 0xa4c90(%rip)     # 0xca2e8
movq %r14, 0xa4cc1(%rip)     # 0xca320
movq %r14, 0xa4d0a(%rip)     # 0xca370
movl %r14d, 0xa4ef3(%rip)    # 0xca560
movq %r14, 0xa4e88(%rip)     # 0xca4fc
movl %r14d, 0xa4f6d(%rip)    # 0xca5e8
callq 0x23c9a
movq 0xa4949(%rip), %rdi     # 0xc9fd0
leaq -0x19a1(%rip), %rdx     # 0x23ced
movl $0x1, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x20b63
cmpq $-0x1, %rax
je 0x257f9
cmpl $0x0, 0xa4a5e(%rip)     # 0xca10c
jle 0x256f8
xorl %r14d, %r14d
leaq 0xa48ee(%rip), %r15     # 0xc9fa8
leaq 0x89ae(%rip), %rbx      # 0x2e06f
movq 0xa4908(%rip), %rdi     # 0xc9fd0
movl 0x124(%r15,%r14,4), %esi
movl $0x1, %edx
movq %rbx, %rcx
xorl %r8d, %r8d
callq 0x209d7
cmpl $-0x1, %eax
je 0x257c2
incq %r14
movslq 0xa4a19(%rip), %rax     # 0xca10c
cmpq %rax, %r14
jl 0x256c1
movl 0xa4a12(%rip), %esi     # 0xca110
testl %esi, %esi
jle 0x25726
movq 0xa48c7(%rip), %rdi     # 0xc9fd0
leaq 0x8aa3(%rip), %rcx      # 0x2e1b3
movl $0x1, %edx
xorl %r8d, %r8d
callq 0x209d7
cmpl $-0x1, %eax
je 0x25823
cmpl $0x1, 0xa4d4b(%rip)     # 0xca478
jne 0x25756
movq 0xa4d4a(%rip), %rdi     # 0xca480
movl $0x441, %esi            # imm = 0x441
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x1f640
movl %eax, 0xa4d73(%rip)     # 0xca4c0
cmpl $-0x1, %eax
je 0x25838
cmpl $0x20, 0xa489b(%rip)    # 0xc9ff8
jne 0x25792
cmpq $0x0, 0xa4f61(%rip)     # 0xca6c8
jne 0x25792
leaq 0x6f988(%rip), %rsi     # 0x950f8
movl $0x3, %edi
xorl %eax, %eax
callq 0x23064
movl $0xc0000000, %eax       # imm = 0xC0000000
movq %rax, 0xa4f40(%rip)     # 0xca6c8
movl $0x5, 0xa4f3e(%rip)     # 0xca6d0
cmpl $0x0, 0xa4fcb(%rip)     # 0xca764
je 0x257a0
callq 0x50862
callq 0x3567d
callq 0x579c2
callq 0x56854
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x58a68
leaq 0x6f89d(%rip), %rdi     # 0x95066
leaq 0x7aec0(%rip), %rsi     # 0xa0690
movl $0x875, %edx            # imm = 0x875
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
leaq 0x6f825(%rip), %rsi     # 0x95010
movl $0x3, %edi
xorl %eax, %eax
callq 0x23064
jmp 0x2585a
leaq 0x6f83c(%rip), %rdi     # 0x9503c
leaq 0x7ae89(%rip), %rsi     # 0xa0690
movl $0x868, %edx            # imm = 0x868
jmp 0x257d5
leaq 0x6f7e8(%rip), %rsi     # 0x94ffd
leaq 0xa4974(%rip), %rdx     # 0xca190
movl $0x3, %edi
jmp 0x25853
leaq 0x6f873(%rip), %rdi     # 0x9509d
leaq 0x7ae5f(%rip), %rsi     # 0xa0690
movl $0x87b, %edx            # imm = 0x87B
jmp 0x257d5
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x6f889(%rip), %rsi     # 0x950d4
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x23064
movl $0x1, %edi
callq 0x1f2b0