头文件:
#ifndef __AOS_THREADPOOL_H__
#define __AOS_THREADPOOL_H__
typedef void (*aos_worker_thread_func)( void *arg, U32 ulTaskId );
int aos_threadpool_alloc(aos_worker_thread_func f, void * arg);
int aos_threadpool_init();
#endif
实现文件:
#include "syscfg.h"
#include "aos.h"
typedef struct tagWorkTask
{
struct aos_list list;
aos_worker_thread_func func;
void * arg;
}AOS_WORKTASK_T;
typedef struct tagThreadPool
{
struct aos_list list;
struct aos_list taskhdr;
U32 ulTaskId;
}AOS_THREADPOOL_T;
static AOS_MUTEX_T * g_ThreadPoolMutex;
static struct aos_list g_ThreadPoolHdr;
static struct aos_list g_TaskList;
static AOS_MUTEX_T * g_TaskMutex;
static U32 g_ulTaskThreadId;
static BOOL_T g_blThreadPoolInit = FALSE;
static U32 g_ulThreadPoolIndex = 1;
/* 提交请求, 异步创建工作线程 */
int aos_threadpool_alloc(aos_worker_thread_func f, void * arg)
{
AOS_WORKTASK_T * pstTask;
if(!g_blThreadPoolInit)
{
if(AOS_SUCC != aos_threadpool_init())
{
AOS_LOG(0);
return AOS_FAIL;
}
g_blThreadPoolInit = TRUE;
}
pstTask = aos_dmem_alloc(MPE_SYS, 0, sizeof(AOS_WORKTASK_T));
if(NULL == pstTask)
{
return AOS_FAIL;
}
aos_memzero(pstTask, sizeof(AOS_WORKTASK_T));
pstTask->arg = arg;
pstTask->func = f;
aos_list_init(&pstTask->list);
//加入到队列中
aos_mutex_lock(g_TaskMutex);
aos_list_add_tail(&g_TaskList, &pstTask->list);
aos_mutex_unlock(g_TaskMutex);
aos_event_post(g_ulTaskThreadId, MSG_SYNC_EVENT);
return AOS_SUCC;
}
/* 工作线程调用外壳, 唤醒后调用注册的入口函数 */
static void aos_threadpool_worker_thread(void * param)
{
AOS_THREADPOOL_T * pstThread = param;
struct aos_list * plist;
AOS_WORKTASK_T * pstTask;
U32 event;
while(1)
{
aos_event_wait(U32_BUTT, AOS_WAIT_ANY, 0, &event);
plist= aos_list_fetch(&pstThread->taskhdr);
if(NULL == plist)
{
continue;
}
pstTask = aos_list_entry(plist, AOS_WORKTASK_T, list);
pstTask->func( pstTask->arg, pstThread->ulTaskId );
aos_dmem_free(pstTask);
//把自己挂到空闲队列中
aos_mutex_lock(g_ThreadPoolMutex);
aos_list_add_tail(&g_ThreadPoolHdr, &pstThread->list);
aos_mutex_unlock(g_ThreadPoolMutex);
//唤醒一下分发线程
aos_event_post(g_ulTaskThreadId, MSG_SYNC_EVENT);
}
}
/* 创建工作线程调用外壳 */
static AOS_THREADPOOL_T * aos_threadpool_new()
{
int ret;
S8 name[AOS_NAME_LEN+1];
AOS_THREADPOOL_T * pstThread;
pstThread = aos_dmem_alloc(MPE_SYS, 0, sizeof(AOS_THREADPOOL_T));
aos_list_init(&pstThread->list);
aos_list_init(&pstThread->taskhdr);
snprintf( name, AOS_NAME_LEN+1, "workthread-%d", g_ulThreadPoolIndex++ );
ret = aos_task_create( name,
WORKTHREAD_TASK_STACK_SIZE,
TASK_PRIO_NORMAL,
AOS_TASK_NOPREEMPT,
aos_threadpool_worker_thread,
pstThread,
&pstThread->ulTaskId);
if(AOS_SUCC != ret)
{
AOS_LOG(0);
aos_dmem_free(pstThread);
return NULL;
}
return pstThread;
}
static void aos_task_dispatch_thread(void * param)
{
U32 event;
struct aos_list * plist;
AOS_WORKTASK_T * pstTask;
AOS_THREADPOOL_T * pThread;
while(1)
{
aos_event_wait(U32_BUTT, AOS_WAIT_ANY, 0, &event);
while(1)
{
aos_mutex_lock(g_TaskMutex);
if(aos_list_is_empty(&g_TaskList))
{
//任务队列为空了,就可以退出循环了
aos_mutex_unlock(g_TaskMutex);
break;
}
plist = aos_list_fetch(&g_TaskList);
aos_mutex_unlock(g_TaskMutex);
pstTask = aos_list_entry(plist, AOS_WORKTASK_T, list);
//分配线程池中的线程
aos_mutex_lock(g_ThreadPoolMutex);
if(aos_list_is_empty(&g_ThreadPoolHdr))
{
aos_mutex_unlock(g_ThreadPoolMutex);
//申请一个线程
pThread = aos_threadpool_new();
if(NULL == pThread)
{
//把任务挂回到队列头部
aos_mutex_lock(g_TaskMutex);
aos_list_add_head(&g_TaskList, &pstTask->list);
aos_mutex_unlock(g_TaskMutex);
break;
}
}
else
{
plist = aos_list_fetch(&g_ThreadPoolHdr);
aos_mutex_unlock(g_ThreadPoolMutex);
pThread = aos_list_entry(plist, AOS_THREADPOOL_T, list);
}
//把任务挂到队列中去,唤醒线程
aos_list_add_tail(&pThread->taskhdr, &pstTask->list);
aos_event_post(pThread->ulTaskId, MSG_SYNC_EVENT);
}
}
}
int aos_threadpool_init()
{
int ret;
aos_list_init(&g_ThreadPoolHdr);
aos_list_init(&g_TaskList);
g_ThreadPoolMutex = NULL;
ret = aos_mutex_init_simple("threadpool", &g_ThreadPoolMutex);
if(ret)
{
return ret;
}
ret = aos_mutex_init_simple("taskmutex", &g_TaskMutex);
if(ret)
{
return ret;
}
ret = aos_task_create("taskthread",
THREADPOOL_TASK_STACK_SIZE,
TASK_PRIO_NORMAL,
AOS_TASK_NOPREEMPT,
aos_task_dispatch_thread,
NULL,
&g_ulTaskThreadId);
return ret;
}