co_routine.cpp分析

co_routine.cpp


#include "co_routine.h"
#include "co_routine_inner.h"
#include "co_epoll.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <map>

#include <poll.h>
#include <sys/time.h>
#include <errno.h>

#include <assert.h>

#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <limits.h>

extern "C"
{
   
	extern void coctx_swap( coctx_t *,coctx_t* ) asm("coctx_swap");
};//声明coctx_swap函数,调用coctx_swap汇编代码。
using namespace std;
stCoRoutine_t *GetCurrCo( stCoRoutineEnv_t *env );//获取当前协程
struct stCoEpoll_t;//管理定时事件的结构体

struct stCoRoutineEnv_t //管理协程环境的结构体
{
   
	stCoRoutine_t *pCallStack[ 128 ];//调用栈,添加协程则入栈,销毁协成则出栈。
	int iCallStackSize;//栈的大小
	stCoEpoll_t *pEpoll;//指向程序中负责管理定时事件的变量

	//for copy stack log lastco and nextco
	stCoRoutine_t* pending_co;//等待的协程
	stCoRoutine_t* occupy_co;//正在运行的协程
};
//int socket(int domain, int type, int protocol);
void co_log_err( const char *fmt,... )//错误日志
{
   
}


#if defined( __LIBCO_RDTSCP__)
static unsigned long long counter(void) 
{
   
	register uint32_t lo, hi;
	register unsigned long long o;
	__asm__ __volatile__ (
			"rdtscp" : "=a"(lo), "=d"(hi)::"%rcx"
			);
	o = hi;
	o <<= 32;
	return (o | lo);

}
static unsigned long long getCpuKhz()
{
   
	FILE *fp = fopen("/proc/cpuinfo","r");
	if(!fp) return 1;
	char buf[4096] = {
   0};
	fread(buf,1,sizeof(buf),fp);
	fclose(fp);

	char *lp = strstr(buf,"cpu MHz");
	if(!lp) return 1;
	lp += strlen("cpu MHz");
	while(*lp == ' ' || *lp == '\t' || *lp == ':')
	{
   
		++lp;
	}

	double mhz = atof(lp);
	unsigned long long u = (unsigned long long)(mhz * 1000);
	return u;
}
#endif

static unsigned long long GetTickMS()//获取时间
{
   
#if defined( __LIBCO_RDTSCP__)
	static uint32_t khz = getCpuKhz();
	return counter() / khz;
#else
	struct timeval now = {
    0 };
	gettimeofday( &now,NULL );
	unsigned long long u = now.tv_sec;
	u *= 1000;
	u += now.tv_usec / 1000;
	return u;
#endif
}

/* no longer use
static pid_t GetPid()
{
    static __thread pid_t pid = 0;
    static __thread pid_t tid = 0;
    if( !pid || !tid || pid != getpid() )
    {
        pid = getpid();
#if defined( __APPLE__ )
		tid = syscall( SYS_gettid );
		if( -1 == (long)tid )
		{
			tid = pid;
		}
#elif defined( __FreeBSD__ )
		syscall(SYS_thr_self, &tid);
		if( tid < 0 )
		{
			tid = pid;
		}
#else
        tid = syscall( __NR_gettid );
#endif

    }
    return tid;

}
static pid_t GetPid()
{
	char **p = (char**)pthread_self();
	return p ? *(pid_t*)(p + 18) : getpid();
}
*/
template <class T,class TLink>
void RemoveFromLink(T *ap) //把这个元素从链表中删除,这里使用了模板类,epoll cond timeout均可以使用。
{
   
	TLink *lst = ap->pLink;
	if(!lst) return ;
	assert( lst->head && lst->tail );

	if( ap == lst->head )
	{
   
		lst->head = ap->pNext;
		if(lst->head)
		{
   
			lst->head->pPrev = NULL;
		}
	}
	else
	{
   
		if(ap->pPrev)
		{
   
			ap->pPrev->pNext = ap->pNext;
		}
	}

	if( ap == lst->tail )
	{
   
		lst->tail = ap->pPrev;
		if(lst->tail)
		{
   
			lst->tail->pNext = NULL;
		}
	}
	else
	{
   
		ap->pNext->pPrev = ap->pPrev;
	}

	ap->pPrev = ap->pNext = NULL;
	ap->pLink = NULL;
}

template <class TNode,class TLink>
void inline AddTail(TLink*apLink,TNode *ap) //添加元素到链表中
{
   
	if( ap->pLink )
	{
   
		return ;
	}
	if(apLink->tail)
	{
   
		apLink->tail->pNext = (TNode*)ap;
		ap->pNext = NULL;
		ap->pPrev = apLink->tail;
		apLink->tail = ap;
	}
	else
	{
   
		apLink->head = apLink->tail = ap;
		ap->pNext = ap->pPrev = NULL;
	}
	ap->pLink = apLink;
}
template <class TNode,class TLink>
void inline PopHead( TLink*apLink )//删除链表头
{
   
	if( !apLink->head )
	{
   
		return ;
	}
	TNode *lp = apLink->head;
	if( apLink->head == apLink->tail )
	{
   
		apLink->head = apLink->tail = NULL;
	}
	else
	{
   
		apLink->head = apLink->head->pNext;
	}

	lp->pPrev = lp->pNext = NULL;
	lp->pLink = NULL;

	if( apLink->head )
	{
   
		apLink->head->pPrev = NULL;
	}
}

template <class TNode,class TLink>
void inline Join( TLink*apLink,TLink *apOther )//添加ap0ther到aplink中
{
   
	//printf("apOther %p\n",apOther);
	if( !apOther->head )
	{
   
		return ;
	}
	TNode *lp = apOther->head;
	while( lp )
	{
   
		lp->pLink = apLink;
		lp = lp->pNext;
	}
	lp = apOther->head;
	if(apLink->tail)
	{
   
		apLink->tail->pNext = (TNode*)lp;
		lp->pPrev = apLink->tail;
		apLink->tail = apOther->tail;
	}
	else
	{
   
		apLink->head = apOther->head;
		apLink->tail = apOther->tail;
	}

	apOther->head = apOther->tail = NULL;
}

/for copy stack //
stStackMem_t* co_alloc_stackmem(unsigned int stack_size) //为每个共享栈分配内存
{
   
	stStackMem_t* stack_mem = (stStackMem_t*)malloc(sizeof(stStackMem_t));
	stack_mem->occupy_co= NULL;
	stack_mem->stack_size = stack_size;
	stack_mem->stack_buffer = (char*)malloc(stack_size);
	stack_mem->stack_bp = stack_mem->stack_buffer + stack_size;
	return stack_mem;
}

stShareStack_t* co_alloc_sharestack(int count, int stack_size) //分配count个共享栈 大小为stack_size。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值