Пример #1
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;

    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    while (init_count < nthreads) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);
}
Пример #2
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthr, struct event_base *main_base,
                 void (*dispatcher_callback)(int, short, void *)) {
    int i;
    nthreads = nthr + 1;

    cqi_freelist = NULL;

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL,
                                        "Can't allocate thread descriptors: %s",
                                        strerror(errno));
        exit(1);
    }
    thread_ids = calloc(nthreads, sizeof(pthread_t));
    if (! thread_ids) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    setup_dispatcher(main_base, dispatcher_callback);

    for (i = 0; i < nthreads; i++) {
        if (!create_notification_pipe(&threads[i])) {
            exit(1);
        }
        threads[i].index = i;

        setup_thread(&threads[i]);
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i], &thread_ids[i]);
        threads[i].thread_id = thread_ids[i];
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    while (init_count < nthreads) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);
}
Пример #3
0
void thread_init(struct event_base *main_base, int nthreads, pthread_t *th)
{
    int i;

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    threads = (LIBEVENT_THREAD *)calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (NULL == threads) {
        mfatal("allocate threads failed!");
        exit(1);
    }

    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            mfatal("can't create notify pipe!");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
    }

    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i], th + i);
    }

    pthread_mutex_lock(&init_lock);
    wait_for_thread_registration(nthreads);
    pthread_mutex_unlock(&init_lock);

    num_threads = nthreads;
}
Пример #4
0
int thread_init(int num_of_threads){
    int i;
    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);
    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    thread_cgs = calloc(num_of_threads, sizeof(thread_cg));

    if(!thread_cgs){
        perror("can't alloc thread_cg");
        exit(1);
    }
    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    for(i = 0; i < num_of_threads; i++){
        int fds[2];
        if(pipe(fds)){
            perror("can't create notify pipe");
            exit(1);
        }

        thread_cgs[i].read_fd = fds[0];
        thread_cgs[i].write_fd = fds[1];

        setup_thread(&thread_cgs[i]);
    }
    //未完成,需要等待现成完成setup,然后才退出函数
    for(i = 0; i < num_of_threads; i++){
        start_worker(worker_libevent, &thread_cgs[i]);
    }

    pthread_mutex_lock(&init_lock);
    while (init_count < NUM_OF_THREADS) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);

}
Пример #5
0
void work_thread_init(int nthreads){
    int i;

    work_threads = (LIBEVENT_WORK_THREAD *)calloc(nthreads, sizeof(LIBEVENT_WORK_THREAD));    
    if(!work_threads){
        DEBUG("work_threads create error");
        exit(1);
    }

    wtq_queue_tail = wtq_queue_head = NULL;

    pthread_mutex_init(&init_work_lock, NULL);
    pthread_cond_init(&init_work_cond, NULL);

    for(i=0; i< nthreads; i++){
        int fds[2];
        if(pipe(fds)){

        }
        work_threads[i].notify_read_fd = fds[0];
        work_threads[i].notify_write_fd = fds[1];
        work_threads[i].no = i;
        work_threads[i].tdbp = initdbp(); 
        setup_thread(&work_threads[i]);
    }

    for(i=0; i<nthreads; i++){
        create_worker(worker_libevent, &work_threads[i]);
    }

    pthread_mutex_lock(&init_work_lock);
    while (init_count < nthreads) {
        pthread_cond_wait(&init_work_cond, &init_work_lock);
    }
    wtq_queue_head->next = wtq_queue_tail;
    pthread_mutex_unlock(&init_work_lock);
}
Пример #6
0
void thread_init()
{
    int nthreads = 4;
 pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);
    work_threads = calloc(nthreads, sizeof(WORK_THREAD));
    if (! work_threads) {
        perror("Can't allocate thread descriptors\n");
        exit(1);
    }


    //dispatcher_thread.loop = EV_DEFAULT_UC;
    //dispatcher_thread.thread_id = pthread_self();
    dispatcher_thread.loop = ev_default_loop(0);
  dispatcher_thread.thread_id = pthread_self();
    
    int i = 0;
    for (i = 0; i < nthreads; i++) {
        setup_thread(&work_threads[i]);
    }


    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libev, &work_threads[i]);
    }


    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    while (init_count < nthreads) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);
}
Пример #7
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;
    int         power;

    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    /* Want a wide lock table, but don't waste memory */
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else {
        /* 8192 buckets, and central locks don't scale much past 5 threads */
        power = 13;
    }

    item_lock_count = ((unsigned long int)1 << (power));
    item_lock_mask  = item_lock_count - 1;

    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }

    // added by Bin since libevent is not used for cache bench
    if (main_base == NULL) {
        //printf("as you know we are not using libevent\n");
        return;
    }

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i], i);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    while (init_count < nthreads) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);
}
Пример #8
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 */
void memcached_thread_init(int nthreads, void *arg) {
    int         i;
    int         power;

    for (i = 0; i < POWER_LARGEST; i++) {
        pthread_mutex_init(&lru_locks[i], NULL);
    }
    pthread_mutex_init(&worker_hang_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    /* Want a wide lock table, but don't waste memory */
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else if (nthreads <= 10) {
        power = 13;
    } else if (nthreads <= 20) {
        power = 14;
    } else {
        /* 32k buckets. just under the hashpower default. */
        power = 15;
    }

    if (power >= hashpower) {
        fprintf(stderr, "Hash table power size (%d) cannot be equal to or less than item lock table (%d)\n", hashpower, power);
        fprintf(stderr, "Item lock table grows with `-t N` (worker threadcount)\n");
        fprintf(stderr, "Hash table grows with `-o hashpower=N` \n");
        exit(1);
    }

    item_lock_count = hashsize(power);
    item_lock_hashpower = power;

    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats_state.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    wait_for_thread_registration(nthreads);
    pthread_mutex_unlock(&init_lock);
}
 //参数nthread是woker线程的数量。main_base则是主线程的event_base
 //主线程在main函数调用本函数,创建nthreads个worker线程
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;
    int         power;

	//申请一个CQ_ITEM时需要加锁
    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    /* Want a wide lock table, but don't waste memory */
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else {
        /* 8192 buckets, and central locks don't scale much past 5 threads */
        power = 13;
    }

    item_lock_count = hashsize(power);
    item_lock_hashpower = power;

    //哈希表中段级别的锁。并不是一个桶就对应有一个锁。而是多个桶共用一个锁  
    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }
    pthread_key_create(&item_lock_type_key, NULL);
    pthread_mutex_init(&item_global_lock, NULL);

	//申请具有nthreads个元素的LIBEVENT_THREAD数据
    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    //主线程对应的
    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    //子线程的
    for (i = 0; i < nthreads; i++) {
        int fds[2];
		//为每个worker线程分配一个管道,用于通知worker线程
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];
		//每一个线程配一个event_base,并设置event监听notify_receive_fd的读事件
		//同时还为这个线程分配一个conn_queue队列
        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
		//创建线程,线程函数为worker_libevent,线程参数为&thread[i]
        create_worker(worker_libevent, &threads[i]);
    }
    
    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    wait_for_thread_registration(nthreads); //主线程阻塞等待事件到来
    pthread_mutex_unlock(&init_lock);
}
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;
    int         power;

    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    /* Want a wide lock table, but don't waste memory */
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else {
        /* 8192 buckets, and central locks don't scale much past 5 threads */
        power = 13;
    }

    item_lock_count = hashsize(power);
    item_lock_hashpower = power;

    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }
    pthread_key_create(&item_lock_type_key, NULL);
    pthread_mutex_init(&item_global_lock, NULL);

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    wait_for_thread_registration(nthreads);
    pthread_mutex_unlock(&init_lock);
}
Пример #11
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;
#ifdef WIN32
    struct sockaddr_in serv_addr;
    int sockfd;

    if ((sockfd = createLocalListSock(&serv_addr)) < 0)
        exit(1);
#endif

    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    threads[0].base = main_base;
    threads[0].thread_id = pthread_self();

    for (i = 0; i < nthreads; i++) {
        int fds[2];

#ifdef WIN32
        if (createLocalSocketPair(sockfd,fds,&serv_addr) == -1) {
            fprintf(stderr, "Can't create notify pipe: %s", strerror(errno));
            exit(1);
        }
#else
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }
#endif

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
#ifdef WIN32
        if (i == (nthreads - 1)) {
            shutdown(sockfd, 2);
        }
#endif

    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 1; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    init_count++; /* main thread */
    while (init_count < nthreads) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);
}
Пример #12
0
/*
 + ========================== +
 | 线程初始化
 | 主线程Accept
 | 4个worker线程 read
 | 1个线程监控消息
 | 4个worker线程 write
 + ========================== +
 */
void thread_init(void)
{   /*{{{*/
    int i;
    threads       = calloc(THREAD_NUM,sizeof(THREAD));
    write_threads = calloc(W_THREAD_NUM,sizeof(THREAD));
    //msg_thread    = (THREAD*)malloc(sizeof(THREAD));

    char* name[] = {"r_a","r_b","r_c","r_d","r_e"};
    char* w_name[] = {"w_a","w_b","w_c","w_d","w_e"};

    for(i = 0; i < THREAD_NUM; ++i) {
        int fds[2];
        //create pipe
        if(pipe(fds)) {
            printf("pipe create error!\n");
            exit(1);
        }

        threads[i].id = i + 1;
        threads[i].name = name[i];
        threads[i].type = T_R;

        threads[i].notify_recv = fds[0];
        threads[i].notify_send = fds[1];
        threads[i].conn_queue  = NULL;

        setup_thread(&threads[i]);
    }

    /*
    for(i = 0;i < W_THREAD_NUM;++i){
    	int fds[2];
    	//create pipe
    	if(pipe(fds)){
    		printf("pipe create error!\n");
    		exit(1);
    	}

    	write_threads[i].id = i + 1;
    	write_threads[i].name = w_name[i];
    	write_threads[i].type = T_W;

    	write_threads[i].notify_recv = fds[0];
    	write_threads[i].notify_send = fds[1];
    	write_threads[i].conn_queue  = NULL;

    	setup_thread(&write_threads[i]);
    }
    */

    //setup_msg_thread(msg_thread);

    //create thread
    for(i = 0; i < THREAD_NUM; ++i) {
        create_worker(worker_libevent,&threads[i]);
    }

    /*
    for(i = 0;i < W_THREAD_NUM;++i){
    	create_worker(worker_libevent,&write_threads[i]);
    }
    */
    //create_worker(worker_msg_dispatcher,msg_thread);
}/*}}}*/
Пример #13
0
void *reader_thread(void *_arg)
{
	orc_t *orc = (orc_t*) _arg;

	setup_thread();

	orc->fd = -1;

	int reconnectcount = 0;

reconnect:
	
	// reconnect, if necessary.
	while (orc->fd < 0) {
		LOG_INFO("Trying to connect to orcboard...(%i)", reconnectcount++);
		orc->fd = orc->impl->connect(orc->impl);
		
		if (orc->fd < 0)
			sleep(1);
	}

	// read for a while
	while (1) {

		// read a packet
		uint8_t buf[3];
		int res = read_fully(orc->fd, buf, 1);
		if (res <= 0)
			goto disconnected;
		if (buf[0] != 0xED) {
			LOG_DEBUG("Recovering sync [%02X]", buf[0]);
			continue;
		}

		res = read_fully(orc->fd, &buf[1], 2);
		if (res <= 0)
			goto disconnected;

		int id = buf[1];
		int datalen = buf[2];

		transaction_t *t = &orc->transactions[id];
		memcpy(t->response, buf, 3);

		res = read_fully(orc->fd, &t->response[PACKET_DATA], datalen + 1);
		if (res <= 0)
			goto disconnected;
		if (!packet_test_checksum(t->response)) {
			LOG_WARN("Bad checksum received from Orc");
			continue;
		}

		if (t->response == garbage && t->response[1]>=orc->idLow && t->response[1]<=orc->idHigh)
			LOG_VERBOSE("Unsolicited ack, id = %02X", t->response[1]);

		// is this a message from orcd, assigning us a client id?
		if (t->response[1] == 0xf7) {
			orc->idLow = t->response[4];
			orc->idHigh = t->response[5];
			orc->idLast = orc->idLow;
			LOG_INFO("Got client transaction range: %02x-%02x", orc->idLow, orc->idHigh);
		}

		if (t->response[1] == 0xfe)
			handle_pad_packet(orc, t->response);

		if (t->response[1] == PACKET_ID_ORCBOARD_BROADCAST &&
		    packet_16u(t->response, 1) == MSG_ASYNC_HEARTBEAT)
			handle_heartbeat_packet(orc, t->response);

		pthread_mutex_lock(&t->mutex);
		pthread_cond_signal(&t->cond);
		pthread_mutex_unlock(&t->mutex);

	}
	
disconnected:
	orc->impl->disconnect(orc->impl, orc->fd);
	orc->fd = -1;
	goto reconnect;

	// silence compiler
	return NULL;
}
Пример #14
0
 //初始化主线程
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;
    int         power;

    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    /* Want a wide lock table, but don't waste memory */
	//初始化item lock
	//根据线程数目调配锁的数目(加锁是由于线程之间的并发导致的,所以item锁的数量也要根据线程的个数来进行调配)
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else {
        /* 8192 buckets, and central locks don't scale much past 5 threads */
        power = 13;
    }

    item_lock_count = hashsize(power);
    item_lock_hashpower = power;

    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }
    pthread_key_create(&item_lock_type_key, NULL);
    pthread_mutex_init(&item_global_lock, NULL);

	//创建nthreads个worker线程对象
    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

	//设置主线程对象的event_base
    dispatcher_thread.base = main_base;
	//设置主线程对象的pid
    dispatcher_thread.thread_id = pthread_self();

	//为每个work线程创建与主线程通信的管道
    for (i = 0; i < nthreads; i++) {
        int fds[2];
		//建立管道
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0]; //worker线程管道接收fd
        threads[i].notify_send_fd = fds[1];  //worker线程管道发送fd

		//初始化worker线程的libevent配置
        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
		//创建worker线程,配置worker线程运行的函数:worker_libevent
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
	//等待所有worker线程启动完毕
    wait_for_thread_registration(nthreads);
    pthread_mutex_unlock(&init_lock);
}
Пример #15
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthr, struct event_base *main_base) {
    int i;
    nthreads = nthr;
#ifdef __WIN32__
    struct sockaddr_in serv_addr;
    int sockfd;

    if ((sockfd = createLocalListSock(&serv_addr)) < 0)
        exit(1);
#endif

    pthread_mutex_init(&stats_lock, NULL);
    pthread_mutex_init(&setting_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        mc_logger->log(EXTENSION_LOG_WARNING, NULL,
                "Can't allocate thread descriptors: %s", strerror(errno));
        exit(1);
    }
    thread_ids = calloc(nthreads, sizeof(pthread_t));
    if (! thread_ids) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    int fds[2];
    for (i = 0; i < nthreads; i++) {
#ifdef __WIN32__
        if (createLocalSocketPair(sockfd,fds,&serv_addr) == -1) {
            mc_logger->log(EXTENSION_LOG_WARNING, NULL,
                    "Can't create notify pipe: %s", strerror(errno));
            exit(1);
        }
#else
        if (pipe(fds)) {
            mc_logger->log(EXTENSION_LOG_WARNING, NULL,
                    "Can't create notify pipe: %s", strerror(errno));
            exit(1);
        }
#endif

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];
        threads[i].index = i;

        setup_thread(&threads[i]);
#ifdef __WIN32__
        if (i == (nthreads - 1)) {
            shutdown(sockfd, 2);
        }
#endif
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i], &thread_ids[i]);
        threads[i].thread_id = thread_ids[i];
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    while (init_count < nthreads) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);
}
Пример #16
0
/*
 * 初始化线程子系统, 创建工作线程
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
    需准备的线程数
 * main_base Event base for main thread
    分发线程
 */
void thread_init(int nthreads, struct event_base *main_base) {
    int         i;
    int         power;

    // 互斥量初始化
    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;

    /* Want a wide lock table, but don't waste memory */
    // 锁表?
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else {
        // 2^13
        /* 8192 buckets, and central locks don't scale much past 5 threads */
        power = 13;
    }

    // 预申请那么多的锁, 拿来做什么
    // hashsize = 2^n
    item_lock_count = hashsize(power);

    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    // 初始化
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }
    pthread_key_create(&item_lock_type_key, NULL);
    pthread_mutex_init(&item_global_lock, NULL);


    // LIBEVENT_THREAD 是结合 libevent 使用的结构体, event_base, 读写管道
    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD)); // 生成 nthreads 数量的线程
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    // main_base 应该是分发任务的线程, 即主线程
    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    // 管道, libevent 通知用的
    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        // 读管道
        threads[i].notify_receive_fd = fds[0];
        // 写管道
        threads[i].notify_send_fd = fds[1];

        // 初始化线程信息数据结构, 其中就将 event 结构体的回调函数设置为 thread_libevent_process()
        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    // 创建并初始化线程, 线程的代码都是 work_libevent()
    for (i = 0; i < nthreads; i++) {
        // 调用 pthread_attr_init() 和 pthread_create()
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    // wait_for_thread_registration() 是 pthread_cond_wait 的调用
    wait_for_thread_registration(nthreads);
    pthread_mutex_unlock(&init_lock);
}