211 lines
4.1 KiB
C
211 lines
4.1 KiB
C
/*
|
|
* ne_monitor.c -- provide iot-system thread protect operation interface.
|
|
*
|
|
*
|
|
* ORIGINAL AUTHOR:
|
|
*
|
|
* Copyright (c) 2018 Netease Corporation
|
|
*/
|
|
#include "c_types.h"
|
|
#include "ne_device.h"
|
|
#include "user_main.h"
|
|
#include "cfg.h"
|
|
#include "log.h"
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "freertos/semphr.h"
|
|
#include "freertos/timers.h"
|
|
|
|
#include "ne_monitor.h"
|
|
|
|
|
|
static ne_thread_monitor_t ne_thread_monitor;
|
|
|
|
/*
|
|
* system get ticks.
|
|
*/
|
|
uint32 ne_os_ticks_ms(uint32 ticks)
|
|
{
|
|
return (ticks) * (portTICK_RATE_MS);
|
|
}
|
|
|
|
/*
|
|
* system thread monitor check name.
|
|
*/
|
|
static int32 ne_thread_monitor_check_name(uint8 *name, ne_thread_monitor_t *ctx)
|
|
{
|
|
int i;
|
|
|
|
for(i=0;i<NE_THREAD_MONITOR_MAX;i++){
|
|
if(!ctx->thread_handle[i].is_valid)
|
|
continue;
|
|
|
|
if(strcmp(ctx->thread_handle[i].name, name))
|
|
continue;
|
|
|
|
return i;
|
|
}
|
|
|
|
return -ERR_FAIL;
|
|
}
|
|
|
|
/*
|
|
* system thread monitor unregister.
|
|
*/
|
|
int32 ne_thread_monitor_unregister(uint8 *name)
|
|
{
|
|
int32 index;
|
|
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
|
|
|
|
/* lock and check name whether exist */
|
|
xSemaphoreTake(ctx->sema, portMAX_DELAY);
|
|
index = ne_thread_monitor_check_name(name, ctx);
|
|
if (index < 0) {
|
|
LOG_EX(LOG_Error, "not found!\r\n");
|
|
|
|
/* unlock */
|
|
xSemaphoreGive(ctx->sema);
|
|
return -ERR_FAIL;
|
|
}
|
|
|
|
/* unregistered */
|
|
memset(&ctx->thread_handle[index], 0, sizeof(ne_thread_handle_t));
|
|
|
|
/* unlock */
|
|
xSemaphoreGive(ctx->sema);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
* system thread monitor register.
|
|
*/
|
|
int32 ne_thread_monitor_register(void *thread_name, uint32 check_interval, int32 (* is_sick)(uint32 cmsec))
|
|
{
|
|
int32 i,ret;
|
|
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
|
|
|
|
if(thread_name == NULL || is_sick == NULL)
|
|
return -ERR_FAIL;
|
|
|
|
/* lock and check name whether registered */
|
|
xSemaphoreTake(ctx->sema, portMAX_DELAY);
|
|
ret = ne_thread_monitor_check_name(thread_name, ctx);
|
|
if(ret >= 0){
|
|
LOG_EX(LOG_Error, "already exit!\r\n");
|
|
}
|
|
|
|
/* register */
|
|
for(i=0;i<NE_THREAD_MONITOR_MAX;i++){
|
|
if(!ctx->thread_handle[i].is_valid){
|
|
ctx->thread_handle[i].is_valid = 1;
|
|
memcpy(ctx->thread_handle[i].name, thread_name, strlen(thread_name));
|
|
ctx->thread_handle[i].check_interval = check_interval;
|
|
ctx->thread_handle[i].is_sick = is_sick;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* unlock */
|
|
xSemaphoreGive(ctx->sema);
|
|
|
|
if(i >= NE_THREAD_MONITOR_MAX){
|
|
LOG_EX(LOG_Error, "register fail!\r\n");
|
|
|
|
return -ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
* system thread monitor loop work.
|
|
*/
|
|
static void ne_thread_monitor_loop(void *arg)
|
|
{
|
|
int32 i,ret;
|
|
uint32 cmsec;
|
|
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
|
|
|
|
ctx->run_flag = 1;
|
|
while(ctx->run_flag){
|
|
xSemaphoreTake(ctx->sema, portMAX_DELAY);
|
|
|
|
for(i=0;i<NE_THREAD_MONITOR_MAX;i++){
|
|
|
|
cmsec = ne_os_ticks_ms(xTaskGetTickCount());
|
|
|
|
/* check valid */
|
|
if(!ctx->thread_handle[i].is_valid){
|
|
continue;
|
|
}
|
|
|
|
if(cmsec < ctx->thread_handle[i].lmsec + ctx->thread_handle[i].check_interval * 1000){
|
|
continue;
|
|
}
|
|
|
|
if(ctx->thread_handle[i].is_sick){
|
|
/* check thread */
|
|
ctx->thread_handle[i].is_sick(cmsec);
|
|
ctx->thread_handle[i].lmsec = cmsec;
|
|
}
|
|
|
|
}
|
|
|
|
xSemaphoreGive(ctx->sema);
|
|
vTaskDelay(100 / portTICK_RATE_MS);
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* system thread monitor start.
|
|
*/
|
|
int32 ne_thread_monitor_start(void)
|
|
{
|
|
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
|
|
|
|
if(!ctx->init_flag)
|
|
return -ERR_FAIL;
|
|
|
|
if(ctx->start_flag)
|
|
return ERR_OK;
|
|
|
|
if(xTaskCreate(ne_thread_monitor_loop, "thread_manage", 256, NULL, 5, NULL) !=pdPASS){
|
|
LOG_EX(LOG_Error, "start error!\r\n");
|
|
|
|
return -ERR_FAIL;
|
|
}
|
|
|
|
ctx->start_flag = 1;
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
* system thread monitor init.
|
|
*/
|
|
int32 ne_thread_monitor_init(void)
|
|
{
|
|
int32 ret;
|
|
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
|
|
|
|
if(ctx->init_flag)
|
|
return ERR_OK;
|
|
|
|
ctx->sema = xSemaphoreCreateMutex();
|
|
if (ctx->sema == NULL) {
|
|
LOG_EX(LOG_Info, "init fail!\r\n");
|
|
|
|
return -ERR_FAIL;
|
|
}
|
|
|
|
ctx->init_flag = 1;
|
|
|
|
return ERR_OK;
|
|
}
|
|
|