/************************************************************************
 * AUTHOR: NiuJiuRu
 * FILENAME: testLib.c
 * CONTENT: "swapi library"库基准测试程序
 * NOTE: 由于"swapi library"库包含的内容较多，这里只测试重要核心的东西
 	 包括：内存、堆、线程、线程池、消息队列、字符串函、日志数等
 * HISTORY:
 * 1, [2010-12-28] created by NiuJiuRu
 ***********************************************************************/
#include "swapi.h"
#include "swmem.h"
#include "swthrd.h"
#include "swthrdpool.h"
#include "swmsgq.h"
#include "swstring.h"
#include "swrand.h"
#include "swlog.h"

// 可分块/可跟踪内存泄露的全局堆
static void *s_hPool = NULL;

// 超时
static int s_timeout = 2000;

// 线程函数1(循环)
static int fun1(unsigned long wParam, unsigned long lParam)
{
	printf("Hello, world!\n");
	return 1000; // 延时1秒
}

// 线程函数2(单次)
static int fun2(unsigned long wParam, unsigned long lParam)
{
	int a = 0;
	int cnt0 = 0, cnt1 = 0, cnt2 = 0, cnt3 = 0, cnt4 = 0, cnt5 = 0, cnt6 = 0, cnt7 = 0, cnt8 = 0, cnt9 = 0;
	int i = 0;
	
	printf("生成1000个10以内的随机数:\n");
	for(i = 0; i < 1000; i++)
	{
		a = xrand32(10);
		
		if(a==0) cnt0++;
		else if(a==1) cnt1++;
		else if(a==2) cnt2++;
		else if(a==3) cnt3++;
		else if(a==4) cnt4++;
		else if(a==5) cnt5++;
		else if(a==6) cnt6++;
		else if(a==7) cnt7++;
		else if(a==8) cnt8++;
		else if(a==9) cnt9++;
		
		printf("%d ", a);
	}
	printf("\n统计概率次数:\n");
	printf("0=%d; 1=%d; 2=%d; 3=%d; 4=%d; 5=%d; 6=%d; 7=%d; 8=%d; 9=%d\n", cnt0, cnt1, cnt2, cnt3, cnt4, cnt5, cnt6, cnt7, cnt8, cnt9);
	
	return -1; // 退出线程
}

// 线程函数3(消息队列)
static void *s_hMsgQ = NULL;
#define MSG_1 0x1980
#define MSG_2 0x0813
static int fun3(unsigned long wParam, unsigned long lParam)
{
	void *hThrd = NULL;
	int msg = 0;
	
	sw_msgq_read(s_hMsgQ, &msg, 0, 0, 1000);
	if(msg == MSG_1)
	{
		printf("[带消息队列的线程]read messag: %d ok\n", msg);
	}
	else if(msg == MSG_2)
	{
		hThrd = sw_thrdpool_alloc(s_hPool, fun2, 0, 0, s_timeout);
		if(hThrd) sw_thrd_resume(hThrd);
	}
	
	return 1;
}

// 检查核心内存分配情况
static void coreMemCheck(const char *filename, int line, const char *ptr, int size, void *lpParameter)
{
	sw_log_info("filename:%s line:%d addr:%#p size:%dbytes", filename, line, ptr, size);
}

// 主函数
int main(int argc,char *argv[])
{
	void *hThrd1 = NULL, *hThrd2 = NULL, *hThrd3 = NULL;
	char coreBuf[64*1024] = { 0 }, cmdBuf[32] = { 0 };
	
	// 测试日志打印
	sw_log_info("\"swapi library\" standard test starting...");
	
	// 初始化全局堆
	if(!sw_heap_init(coreBuf, sizeof(coreBuf), 4)) goto EndP;
	
	// 创建线程池
	s_hPool = sw_thrdpool_create(8);
	if(!s_hPool) goto EndP;
	
	// 创建消息队列
	s_hMsgQ = sw_msgq_create(8);
	if(!s_hMsgQ) goto EndP;
	
	// 创建线程
	hThrd1 = sw_thrdpool_alloc(s_hPool, fun1, 0, 0, s_timeout);
	if(hThrd1) sw_thrd_resume(hThrd1);
	
	hThrd2 = sw_thrdpool_alloc(s_hPool, fun2, 0, 0, s_timeout);
	if(hThrd2) sw_thrd_resume(hThrd2);
	
	hThrd3 = sw_thrdpool_alloc(s_hPool, fun3, 0, 0, s_timeout);
	if(hThrd3) sw_thrd_resume(hThrd3);
	
	// 打印全局堆的内存分配情况
	sw_log_info("memory allocation situation(0x%08x %dbytes):", coreBuf, sw_heap_getTotalSize());
	sw_heap_check(coreMemCheck, NULL);
	
	// 控制命令
CmdP:
	memset(cmdBuf, 0, sizeof(cmdBuf));
	if(fgets(cmdBuf, sizeof(cmdBuf), stdin) == NULL)
	{
		sw_thrd_delay(1); // 没有读到任何输入时, 延时1毫秒, 交出CPU控制权
		goto CmdP;
	}

	if(xstrncasecmp(cmdBuf, "exit", strlen("exit")) == 0 || xstrncasecmp(cmdBuf, "0", 1) == 0)
	{
		sw_thrdpool_printf(s_hPool); // 打印线程池当前的分配情况
		sw_thrdpool_destroy(s_hPool, s_timeout); // 销毁线程池
		goto EndP;
	}
	else if(xstrncasecmp(cmdBuf, "1", 1) == 0)
	{
		sw_thrd_pause(hThrd1);
		sw_msgq_post(s_hMsgQ, MSG_1, 0, 0);
	}
	else if(xstrncasecmp(cmdBuf, "2", 1) == 0)
	{
		sw_thrd_resume(hThrd1);
		sw_msgq_post(s_hMsgQ, MSG_2, 0, 0);
	}
	
	goto CmdP;
	
	// 结束退出
EndP:
	sw_msgq_destroy(s_hMsgQ); // 销毁消息队列
	
	sw_log_info("Memory leak check:");
	sw_heap_check(coreMemCheck, NULL); // 内存泄露检查
	sw_heap_exit();
	
	sw_log_info("\"swapi library\" standard test end.");
	
	return 0;
}
