#include "sr_ct.h"
#include "sr_log.h"

#include "sr_osal.h"




int g_ctReturn = SR_NULL;  /*!< 用于记录当前函数返回值*/
_THREAD_T *g_curThread =SR_NULL; /*!< 当前正在执行的协程*/

static os_slist_node_t gs_threadListHead = OS_SLIST_INIT(gs_threadListHead);
static os_slist_node_t gs_deleteListHead = OS_SLIST_INIT(gs_deleteListHead);



//按优先级插入到链表中
void _InsertByPriority(os_slist_node_t *head, os_slist_node_t *entry,int priority) 
{	
	os_slist_node_t *current = head;

	//从大到小排列
	while (current->next != SR_NULL && SR_CONTAINER_OF(current->next, _THREAD_T, list)->priority >= priority)
	{
		current = current->next;
	}
	entry->next = current->next;
	current->next = entry;
 
}

SR_THREAD_T SR_OsThreadCreate(char *name,int (*func)(void *args),void *args,uint16_t stackSize,uint8_t priority)
{
	//创建协程控制句柄
	_THREAD_T *thd = (_THREAD_T*)SR_OsCalloc(1,sizeof(_THREAD_T)+stackSize);
	if(!thd) return SR_NULL;
		
	snprintf(thd->name, SR_NAME_LEN, "%s",name);
	thd->func = func;
	thd->args = args;
	thd->stackSize = stackSize;
	thd->priority = priority;
	thd->list.next = SR_NULL;
	thd->dltList.next = SR_NULL;
	thd->state = THD_READY;
	thd->stack= thd->dynStack;  //动态栈
	thd->sp = thd->stack;  //上下文指针指向stack起始位置

	((SR_CT_T *)(thd->dynStack))->stackSize  = sizeof(SR_CT_T);  //协程根节点默认栈大小

	//按优先级插入运行链表
	_InsertByPriority(&gs_threadListHead, &thd->list, priority);

	return (void *)thd;
}



//删除
int SR_OsThreadDelete(SR_THREAD_T thd)
{
	_THREAD_T *thread= (_THREAD_T * )thd;

	if(!thread) thread = g_curThread;

	//将节点添加到删除列表 gs_deleteListHead
	os_slist_add(&gs_deleteListHead, &thread->dltList);

	//thread->ct.wait = 0xDE;
	//((SR_CT_T *)(thread->stack))->wait = 0xDE;
	thread->state = THD_EXITED;

	return 0;
}



//协程调度函数
#if   0
void SR_Schedule(void)
{
	os_slist_node_t *pos = SR_NULL;   //当前节点
	_THREAD_T * thread = SR_NULL;
	
    //遍历链表，取出协程控制句柄，执行
	//for (pos = (head)->next; pos != SR_NULL; pos = pos->next)
	os_slist_for_each(pos, &gs_threadListHead)
	{
	  	thread = SR_CONTAINER_OF(pos, _THREAD_T, list);

		if(((SR_CT_T *)(thread->stack))->wait == 0xDE) continue;
		
	  	g_curThread = thread;
		thread->sp =thread->stack;
		if(thread->func(thread->args)>=SR_CT_EXITED)
		{
			//将节点添加到删除列表 gs_deleteListHead
			os_slist_add(&gs_deleteListHead, &thread->dltList);
			((SR_CT_T *)(thread->stack))->wait = 0xDE;
		}
		
	}
	
	//遍历删除列表，清理待删除协程
	//for (pos = (head)->next; pos != SR_NULL; pos = pos->next)
	while(gs_deleteListHead.next!=SR_NULL)
	{
		pos = gs_deleteListHead.next;
		gs_deleteListHead.next = pos->next;
		
		//从gs_threadListHead中删除
		os_slist_del(&gs_threadListHead, &(SR_CONTAINER_OF(pos, _THREAD_T, dltList)->list));
		pos->next =SR_NULL;

		//销毁线程变量分配空间
		thread = SR_CONTAINER_OF(pos, _THREAD_T, dltList);
		if(thread->flags==FLAG_STATIC_STACK || thread->flags==0)  //静态栈和动态CB 、动态CB和动态栈
		{
			SR_OsFree(thread);
		}
		else if(thread->flags==FLAG_STATIC_CB) //静态CB和动态栈
		{ 
			SR_OsFree(thread->stack);
		}
			
	}
	
}

#else
//LW_RETURN_TEST
void SR_Schedule(void)
{
	os_slist_node_t *pos = SR_NULL;   //当前节点
	_THREAD_T * thread = SR_NULL;
	
    //遍历链表，取出协程控制句柄，执行
	//for (pos = (head)->next; pos != SR_NULL; pos = pos->next)
	os_slist_for_each(pos, &gs_threadListHead)
	{
	  	thread = SR_CONTAINER_OF(pos, _THREAD_T, list);

		//if(((SR_CT_T *)(thread->stack))->wait == 0xDE) continue;
		if(thread->state == THD_EXITED) continue;
		
	  	g_curThread = thread;
		thread->sp =thread->stack;
		thread->state = THD_RUNNING;
		//if(thread->func(thread->args)>=SR_CT_EXITED)
		if(thread->func(thread->args)<=SR_CT_EXITED)
		{
			thread->state = THD_EXITED;
			//将节点添加到删除列表 gs_deleteListHead
			os_slist_add(&gs_deleteListHead, &thread->dltList);
			((SR_CT_T *)(thread->stack))->wait = 0xDE;
		}
		else
			thread->state = THD_READY;
		
	}
	
	//遍历删除列表，清理待删除协程
	//for (pos = (head)->next; pos != SR_NULL; pos = pos->next)
	while(gs_deleteListHead.next!=SR_NULL)
	{
		pos = gs_deleteListHead.next;
		gs_deleteListHead.next = pos->next;
		
		//从gs_threadListHead中删除
		os_slist_del(&gs_threadListHead, &(SR_CONTAINER_OF(pos, _THREAD_T, dltList)->list));
		pos->next =SR_NULL;

		//销毁线程变量分配空间
		thread = SR_CONTAINER_OF(pos, _THREAD_T, dltList);
		if(thread->flags==FLAG_STATIC_STACK || thread->flags==0)  //静态栈和动态CB 、动态CB和动态栈
		{
			SR_OsFree(thread);
		}
		else if(thread->flags==FLAG_STATIC_CB) //静态CB和动态栈
		{ 
			SR_OsFree(thread->stack);
		}

		SR_LOG(DEBUG,"thd:%s deleted!",thread->name);	
	}
	
}


#endif

void _OsErrHdl(int type)
{
   if(_OS_ERR_STACK_OF ==type)  //栈溢出
	 {
		SR_LOG(ERR,"stack overflow,thd(%s)!",g_curThread->name);
		while(1)
		{
		
		}
	 }
}


#if  1

/********************************线程相关API*************************************************************/
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
{
	_THREAD_T *thd;  //线程控制句柄
	static  uint16_t thdNum = 1U;  
	uint16_t stackSize = SR_OS_STACK_SIZE_DEF;   //默认栈大小
    uint32_t prio  = (uint32_t)osPriorityNormal; //默认优先级
    uint8_t memFlag   = 0;  //静态内存标志

	//检查参数
    if (SR_NULL == func) return SR_NULL;
 

	if (attr != SR_NULL)  
	{
		if (attr->priority != osPriorityNone) prio = (uint32_t)attr->priority;

		if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
			return (SR_NULL);
		}

		if ((attr->cb_mem != SR_NULL) && (attr->cb_size >= sizeof(_THREAD_T)))  memFlag |= FLAG_STATIC_CB;
		if (attr->stack_size > 0U)    stackSize = attr->stack_size ;    
		if (attr->stack_mem != SR_NULL)  memFlag |= FLAG_STATIC_STACK;

    }

	//分配变量内存
	if(memFlag==FLAG_STATIC_STACK)  //静态栈和动态CB
	{
	    thd = (_THREAD_T*)SR_OsCalloc(1,sizeof(_THREAD_T));
	    if(thd==SR_NULL) return SR_NULL;
		thd->stack = attr->stack_mem;
	}
	else if(memFlag==FLAG_STATIC_CB){ //静态CB和动态栈
		thd = (_THREAD_T *)attr->cb_mem;
		thd->stack = (uint8_t *)SR_OsCalloc(1,stackSize);
		if(thd->stack==SR_NULL) return SR_NULL;
	}
	else  //动态CB和动态栈
	{
	    thd = (_THREAD_T*)SR_OsCalloc(1,sizeof(_THREAD_T)+stackSize);
	    if(thd==SR_NULL) return SR_NULL;
		thd->stack = thd->dynStack;
	}

	if ((SR_NULL == attr) || (SR_NULL == attr->name))
        snprintf(thd->name, SR_NAME_LEN, "th%02d", thdNum++);
    else
        snprintf(thd->name, SR_NAME_LEN, "%s", attr->name);
	thd->func = func;
	thd->args = argument;
	thd->stackSize = stackSize;
	thd->priority = prio;
	thd->list.next = SR_NULL;
	thd->dltList.next = SR_NULL;
	thd->state = THD_READY;
	thd->sp = thd->stack;  //上下文指针指向stack起始位置
	thd->flags = memFlag;

	//((SR_CT_T *)(thd->stack))->stackSize  = sizeof(SR_CT_T);  //协程根节点默认栈大小
	SR_CT_INIT((SR_CT_T *)(thd->stack));

	//按优先级从大到小插入运行链表
	_InsertByPriority(&gs_threadListHead, &thd->list, prio);

	return (void *)thd;
}

osStatus_t osThreadTerminate(osThreadId_t thread_id)
{
	_THREAD_T *thd = (_THREAD_T *)thread_id;  //线程控制句柄

	if(thd==SR_NULL) return osErrorParameter;

	//将节点添加到删除列表 gs_deleteListHead
	os_slist_add(&gs_deleteListHead, &thd->dltList);

	//((SR_CT_T *)(thd->stack))->wait = 0xDE;
	thd->state = THD_EXITED;

	return osOK;
}


const char *osThreadGetName(osThreadId_t thread_id)
{
	_THREAD_T *thd = (_THREAD_T *)thread_id;  //线程控制句柄

	return (thd == SR_NULL)?  SR_NULL:thd->name;
}

osThreadId_t osThreadGetId(void)
{
    return (osThreadId_t)(g_curThread);
}



/********************************信号量相关API***********************************************************/
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
{
	static uint16_t semNum = 0U;
	_SEM_T *sem_cb;

	/* Check parameters */
    if ((0U == max_count) || (initial_count > max_count))
    {
        return SR_NULL;
    }

	if ((SR_NULL == attr) || (SR_NULL == attr->cb_mem))
    {
		//动态分配
        sem_cb = (_SEM_T *)SR_OsCalloc(1,sizeof(_SEM_T));
        if (SR_NULL == sem_cb) return SR_NULL;

        sem_cb->flags |= FLAG_MALLOC_CB;
    }
    else
    {
		//静态分配
        if (attr->cb_size >= sizeof(_SEM_T))
        {
            sem_cb = attr->cb_mem;
            sem_cb->flags = 0;
        }
        else
            return SR_NULL;
    }


	if ((SR_NULL == attr) || (SR_NULL == attr->name))
    {
        snprintf(sem_cb->name, SR_NAME_LEN, "sem%02d", semNum++);
    }
    else
        snprintf(sem_cb->name, SR_NAME_LEN, "%s", attr->name);

	
	sem_cb->count = initial_count;
	sem_cb->maxCnt = max_count;

	return sem_cb;
}

const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id)
{
    _SEM_T *sem_cb = (_SEM_T *)semaphore_id;

    /* Check parameters */
    if ((SR_NULL == sem_cb) ) return SR_NULL;

    return sem_cb->name;
}

//获取信号量，宏实现详见cmsis_os2.h
//osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout);

//释放信号量
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)	
{
	_SEM_T *sem_cb = (_SEM_T *)semaphore_id;

	if (SR_NULL == sem_cb) return osErrorParameter;

	if(sem_cb->count < sem_cb->maxCnt) ++(sem_cb)->count;
	
	return osOK;
}

//获取信号量剩余计数
uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
{
    _SEM_T *sem_cb = (_SEM_T *)semaphore_id;

    /* Check parameters */
    if (SR_NULL == sem_cb) return 0U;
    {
        
    }

    return sem_cb->count;
}

//删除信号量
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
{
    _SEM_T *sem_cb = (_SEM_T *)semaphore_id;

    /* Check parameters */
    if (SR_NULL == sem_cb)  return osErrorParameter;

	//考虑释放阻塞的线程，待完善

    sem_cb->count =0;
	sem_cb->maxCnt =0;

	//释放内存
    if (sem_cb->flags & FLAG_MALLOC_CB) SR_OsFree(sem_cb);

    return osOK;
}



/********************************互斥量相关API***********************************************************/
//创建互斥量
osMutexId_t osMutexNew(const osMutexAttr_t *attr)
{
    _MUTEX_T *mutex_cb;
    static uint16_t mutexNum = 0U;

    if ((SR_NULL == attr) || (SR_NULL == attr->cb_mem))
    {
		//动态分配CB
        mutex_cb = (_MUTEX_T *)SR_OsCalloc(1,sizeof(_MUTEX_T));
        if (SR_NULL == mutex_cb) return SR_NULL;

        mutex_cb->flags |= FLAG_MALLOC_CB;
    }
    else
    {
		//静态态分配CB
        if (attr->cb_size >= sizeof(_MUTEX_T))
        {
            mutex_cb = attr->cb_mem;
            mutex_cb->flags = 0;
        }
        else
            return SR_NULL;
    }

    if ((SR_NULL == attr) || (0 == attr->attr_bits))
    {
        mutex_cb->flags |= osMutexRecursive;
    }
    else
        mutex_cb->flags |= attr->attr_bits;

	if ((SR_NULL == attr) || (SR_NULL == attr->name))
    {
        snprintf(mutex_cb->name, SR_NAME_LEN, "mutex%02d", mutexNum++);
    }
    else
        snprintf(mutex_cb->name, SR_NAME_LEN, "%s", attr->name);


	mutex_cb->lock = 1;
	mutex_cb->owner = SR_NULL;

    return mutex_cb;
}

//获取互斥量名字
const char *osMutexGetName(osMutexId_t mutex_id)
{
    _MUTEX_T *mutex_cb = (_MUTEX_T *)mutex_id;

    /* Check parameters */
    if (SR_NULL == mutex_cb) return SR_NULL;
    
    return mutex_cb->name;
}


//获取互斥量，宏实现详见cmsis_os2.h
//osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)


//释放互斥量
osStatus_t osMutexRelease(osMutexId_t mutex_id)
{
    _MUTEX_T *mutex_cb = (_MUTEX_T *)mutex_id;
    /* Check parameters */
    if (SR_NULL == mutex_cb) return osErrorParameter;

    if(((mutex_cb)->owner==g_curThread)&&((mutex_cb)->lock < 1)) 
		if((++(mutex_cb)->lock) == 1) (mutex_cb)->owner=SR_NULL;
	else
		return osError;

    return osOK;
}

//获取互斥量的拥有者
osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
{
    _MUTEX_T *mutex_cb = (_MUTEX_T *)mutex_id;

    /* Check parameters */
    if (SR_NULL == mutex_cb) return SR_NULL;

    return mutex_cb->owner;
}


//删除互斥量
osStatus_t osMutexDelete(osMutexId_t mutex_id)
{
    _MUTEX_T *mutex_cb = (_MUTEX_T *)mutex_id;

    /* Check parameters */
    if (SR_NULL == mutex_cb) return osErrorParameter;

	//考虑释放阻塞的线程，待完善
    if (mutex_cb->flags & FLAG_MALLOC_CB) SR_OsFree(mutex_cb);

    return osOK;
}


#endif
