• skynet源代码学习



    学习云风的skynet源代码,简单记录下。

    void 
    skynet_globalmq_push(struct message_queue * queue) {
    	struct global_queue *q= Q;
    
    	uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1));
    
    	// only one thread can set the slot (change q->queue[tail] from NULL to queue)
    	if (!__sync_bool_compare_and_swap(&q->queue[tail], NULL, queue)) {
    		// The queue may full seldom, save queue in list
    		// 假设swap失败说明queue[] 满了,达到了64K个队列,出现的几率非常小
    		// 假设这种话,就把其保存在Q的list中
    		assert(queue->next == NULL);
    		struct message_queue * last;
    		do {
    			last = q->list;
    			queue->next = last;
    		} while(!__sync_bool_compare_and_swap(&q->list, last, queue));
    
    		return;
    	}
    }
    
    // 结构体global_queue中的 head, tail 字段分别控制着Q的取,存过程
    // GP呢能够看做是一个hash的过程,以此来确定其维护的queues的index
    struct message_queue * 
    skynet_globalmq_pop() {
    	struct global_queue *q = Q;
    	uint32_t head =  q->head;
    
    	if (head == q->tail) {
    		// The queue is empty.
    		return NULL;
    	}
    
    	uint32_t head_ptr = GP(head);
    
    	struct message_queue * list = q->list;
    	// 假设list非空,说明Q->queue以前满过,就把他们转移回queue[]中,由于那里速度更快
    	if (list) {
    		// If q->list is not empty, try to load it back to the queue
    		struct message_queue *newhead = list->next;
    		if (__sync_bool_compare_and_swap(&q->list, list, newhead)) {
    			// try load list only once, if success , push it back to the queue.
    			list->next = NULL;
    			skynet_globalmq_push(list);
    		}
    	}
    
    	// 从头取一个消息队列
    	struct message_queue * mq = q->queue[head_ptr];
    	if (mq == NULL) {
    		// globalmq push not complete
    		return NULL;
    	}
    	// 取走一个消息后自然要将index往后移动一个位置,而且刚那个position置为空
    	if (!__sync_bool_compare_and_swap(&q->head, head, head+1)) {
    		return NULL;
    	}
    	// only one thread can get the slot (change q->queue[head_ptr] to NULL)
    	if (!__sync_bool_compare_and_swap(&q->queue[head_ptr], mq, NULL)) {
    		return NULL;
    	}
    
    	return mq;
    }
    


  • 相关阅读:
    【转载】Chrome 0day漏洞:不要用Chrome查看pdf文件
    内网渗透闲谈
    Sticky Fingure安装教程
    局域网下交换机配置
    Access 2010 应用基础 单元三:SQL查询
    ESP8266 wifi干扰、钓鱼实现
    这是谁的锅
    svn/git的diff、patch
    sublime开发php必备工具集合(mac)
    gcc学习笔记
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3959579.html
Copyright © 2020-2023  润新知