【HarmonyOS源码学习系列】系统服务进程foundation

1,418 阅读12分钟

foundation翻译成中文是基础,地基的意思,在鸿蒙操作系统里面,foundation是一个进程(类似Android操作系统的system_server进程),里面运行着重要的系统服务。不管是从字面意思,还是从进程里面运行的服务看,foundation进程都是一个至关重要的系统服务进程。

foundation进程里面运行的服务有:

  • samgr_server // sa manager service
  • abilityms // ability manager service
  • bundlems // bundle manager service
  • dtbschedmgr //
  • ... ...

foundation的代码很简单,它只是一个进程载体。在bin档打包的时候,会把上面的服务模块打包进去。bin档运行的时候,这些服务里面的init()会先于main()函数被执行。

foundation bin档模块源代码位于code-1.0\foundation\distributedschedule\services\safwk_lite\

foundation bin档生成

code-1.0\foundation\distributedschedule\services\safwk_lite\BUILD.gn

if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
    lite_component("safwk_lite") {
        features = [
            ":foundation"
        ]
    }

    # feature: foundation
    executable("foundation") {
        cflags = ["-Wall"]
        cflags_cc = cflags

        sources = [
            "src/main.c",
        ]

        include_dirs = [
            "//utils/native/lite/include",
            "//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
        ]

        ldflags = [
            "-lstdc++",
            "-Wl,-Map=foundation.map",
        ]

        deps = [
            "//foundation/distributedschedule/services/samgr_lite/samgr_server:server",
            "//base/hiviewdfx/frameworks/hilog_lite/featured:hilog_shared",
            "//base/security/services/iam_lite/ipc_auth:ipc_auth_target",
        ]
        if (ohos_kernel_type == "liteos_a") {
            deps += [
                "//base/security/services/iam_lite/pms:pms_target",
                "//foundation/aafwk/services/abilitymgr_lite:abilityms",
                "//foundation/appexecfwk/services/bundlemgr_lite:bundlems",
                "//foundation/distributedschedule/services/dtbschedmgr_lite:dtbschedmgr",
            ]
        }
    }
}

deps这些模块编译生成动态链接库,这些库都会以依赖的形式被打包进bin档。

$ readelf -d foundation

Dynamic section at offset 0x2008 contains 47 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libserver.so]
 0x00000001 (NEEDED)                     Shared library: [libhilog_shared.so]
 0x00000001 (NEEDED)                     Shared library: [libipc_auth_target.so]
 0x00000001 (NEEDED)                     Shared library: [libpms_target.so]
 0x00000001 (NEEDED)                     Shared library: [libabilityms.so]
 0x00000001 (NEEDED)                     Shared library: [libbundlems.so]
 0x00000001 (NEEDED)                     Shared library: [libsamgr.so]

foundation bin档源代码

code-1.0/foundation/distributedschedule/services/safwk_lite/src/main.c

#include "samgr_lite.h"

int main(int argc, char * const argv[])
{
#ifdef DEBUG_SERVICES_SAFWK_LITE
    // 打印调试信息:系统服务进程启动
    printf("[Foundation][D] Start server system, begin. \n");

    struct timeval tvBefore;
    // 获取服务开始启动的时间
    (void)gettimeofday(&tvBefore, NULL);
#endif
    // 调用系统初始化方法
    OHOS_SystemInit();
    
#ifdef DEBUG_SERVICES_SAFWK_LITE
    struct timeval tvAfter;
    // 获取服务全部启动后的时间
    (void)gettimeofday(&tvAfter, NULL);
    // 打印调试信息:输出系统服务启动总耗时
    printf("[Foundation][D] Start server system, end. duration %d seconds and %d microseconds. \n",\
        tvAfter.tv_sec - tvBefore.tv_sec, tvAfter.tv_usec - tvBefore.tv_usec);
#endif

    // 进程进入睡眠状态
    while (1) {
        // pause only returns when a signal was caught and the signal-catching function returned.
        // pause only returns -1, no need to process the return value.
        (void)pause();
    }
}

void __attribute__((weak)) OHOS_SystemInit(void)
{
    // 直接调用
    SAMGR_Bootstrap();
}

SAMGR_Bootstrap()函数是通过头文件samgr_lite.h来调用动态链接库libsamgr.so里面的函数。

下面进入模块samgr,模块编译生成动态链接库libsamgr.so

samgr模块

samgr是系统引导模块,编译生成系统引导库。系统引导从函数SAMGR_Bootstrap()开始。

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/samgr_lite_inner.h

typedef enum {
    BOOT_SYS = 0,
    BOOT_SYS_WAIT = 1,
    BOOT_APP = 2,
    BOOT_APP_WAIT = 3,
    BOOT_DYNAMIC = 4,
    BOOT_DYNAMIC_WAIT = 5,
} BootStatus;

系统引导分为3个阶段,初始阶段为0,是核心系统服务引导阶段。当核心系统服务引导完成后进入BOOT_SYS_WAIT阶段,这个时候可以进入下一阶段BOOT_APP。BOOT_APP是应用启动阶段,当应用启动完成后进入BOOT_APP_WAIT阶段,这个时候可以进入下一个阶段BOOT_DYNAMIC阶段。BOOT_DYNAMIC阶段是系统已经启动完成,可以进行服务动态注册的阶段。

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/samgr_lite.c

void SAMGR_Bootstrap(void)
{
    // 取得系统应用管理类实例
    SamgrLiteImpl *samgr = GetImplement();
    if (samgr->mutex == NULL) {
        HILOG_INFO(HILOG_MODULE_SAMGR, "Samgr is not init, no service!");
        return;
    }
    // 目前的版本,这个函数为空实现,暂不知道有啥作用
    WDT_Reset(WDG_SVC_BOOT_TIME);
    Vector initServices = VECTOR_Make(NULL, NULL);
    // 获取信号锁
    MUTEX_Lock(samgr->mutex);
    samgr->status = TO_NEXT_STATUS(samgr->status);
    int16 size = VECTOR_Size(&(samgr->services));
    int16 i;
    // 遍历samgr里面的服务,如果服务处于SVC_INIT状态,就添加到initServices里面
    // service有三种状态其它两种状态表示服务线程已经启动,INIT表示服务线程尚未启动
    for (i = 0; i < size; ++i) {
        ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(samgr->services), i);
        if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
            continue;
        }
        VECTOR_Add(&initServices, serviceImpl);
    }
    // 释放信号锁
    MUTEX_Unlock(samgr->mutex);
    // 调用上一篇中写到的log api向日志系统写入日志
    HILOG_INFO(HILOG_MODULE_SAMGR, BOOT_FMT(samgr->status), VECTOR_Size(&initServices));
    // 启动所有需要初始化的服务
    InitializeAllServices(&initServices);
    // 清除向量数据结构initServices
    VECTOR_Clear(&initServices);
    // 检查初始化是否完成
    int32 err = InitCompleted();
    if (err != EC_SUCCESS) {
        HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step failed! errno:%d", err);
    }
}

启动所有需要初始化的服务

static void InitializeAllServices(Vector *services)
{
    int16 size = VECTOR_Size(services);
    int16 i;
    for (i = 0; i < size; ++i) {
        ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
        if (serviceImpl == NULL) {
            continue;
        }
        // 调用service的接口分别取得:任务配置信息和服务名称
        TaskConfig config = serviceImpl->service->GetTaskConfig(serviceImpl->service);
        const char *name = serviceImpl->service->GetName(serviceImpl->service);
        AddTaskPool(serviceImpl, &config, name);

        HILOG_INFO(HILOG_MODULE_SAMGR, "Init service:%s TaskPool:%p", name, serviceImpl->taskPool);
        InitializeSingleService(serviceImpl);
    }
    SamgrLiteImpl *samgr = GetImplement();
    MUTEX_Lock(samgr->mutex);
    for (i = 0; i < size; ++i) {
        ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
        if (serviceImpl == NULL) {
            continue;
        }
        const char *name = serviceImpl->service->GetName(serviceImpl->service);
        SAMGR_StartTaskPool(serviceImpl->taskPool, name);
    }
    MUTEX_Unlock(samgr->mutex);
}

创建任务池

static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name)
{
    if (service->taskPool != NULL) {
        return;
    }
    // 任务的优先级是9-39,如果不在这个范围,则优先级无效,会重新用最低优先级赋值
    if (cfg->priority < PRI_LOW || cfg->priority >= PRI_BUTT) {
        HILOG_ERROR(HILOG_MODULE_SAMGR, "The %s service pri(%d) is out of range!", name, cfg->priority);
        cfg->priority = PRI_LOW;
    }

    switch (cfg->taskFlags) {
        // 如果是共享任务
        case SHARED_TASK: {
            int pos = (int)cfg->priority / PROPERTY_STEP;
            SamgrLiteImpl *samgr = GetImplement();
            // sharedPool数组的长度是8,这里根据优先级分组,只会用到1 2 3 4,其余四个是多余的????
            if (samgr->sharedPool[pos] == NULL) {
                TaskConfig shareCfg = DEFAULT_TASK_CFG(pos);
                // 目前系统配置的DEFAULT_SIZE是1,创建一个只有一个任务的任务池
                samgr->sharedPool[pos] = SAMGR_CreateFixedTaskPool(&shareCfg, name, DEFAULT_SIZE);
            }
            // service使用共享任务池
            service->taskPool = samgr->sharedPool[pos];
            // 共享任务池引用计数加1
            if (SAMGR_ReferenceTaskPool(service->taskPool) == NULL) {
                HILOG_ERROR(HILOG_MODULE_SAMGR, "shared task:%p pri:%d ref is full", service->taskPool, cfg->priority);
                samgr->sharedPool[pos] = NULL;
            }
        }
            break;

        case SPECIFIED_TASK:
        	// 尝试从所有服务中查找符合当前配置的任务池
            service->taskPool = GetSpecifiedTaskPool(cfg);
            // 如果没有找到一个相同配置的任务池,会进入到下面的case,创建一个单人任务的任务池
            if (service->taskPool != NULL) {
                break;
            }
        // 服务独享任务(这个任务只被这一个服务执行)
        case SINGLE_TASK:
            service->taskPool = SAMGR_CreateFixedTaskPool(cfg, name, SINGLE_SIZE);
            break;
        default:
            break;
    }
}

这个方法其实就是给ServiceImpl结构体中的taskPool赋值的过程,taskPool的创建是通过调用SAMGR的函数,这些函数根据task type的不同进行分别调用。

code-1.0\foundation\distributedschedule\services\samgr_lite\samgr\source\task_manager.c

TaskPool *SAMGR_CreateFixedTaskPool(const TaskConfig *config, const char *name, uint8 size)
{
    if (config == NULL || size == 0 || MAX_TASK_SIZE <= THREAD_Total()) {
        return NULL;
    }
    // 根据任务配置信息的消息队列大小和服务名称创建消息队列(队列并没有用name这个参数)
    MQueueId queueId = (MQueueId)QUEUE_Create(name, sizeof(Exchange), config->queueSize);
    if (queueId == NULL) {
        HILOG_ERROR(HILOG_MODULE_SAMGR, "Create Queue<%s> size:%d failed!", name, config->queueSize);
        return NULL;
    }
    // 创建任务池,传入的参数size是1,即创建的任务池大小是1
    TaskPool *taskPool = (TaskPool *)SAMGR_Malloc(sizeof(TaskPool) + sizeof(ThreadId) * size);
    if (taskPool == NULL) {
        HILOG_ERROR(HILOG_MODULE_SAMGR, "Create TaskPool<%s> size:%d failed!", name, config->queueSize);
        QUEUE_Destroy(queueId);
        return NULL;
    }
    // 任务池全部内存初始化为0
    (void)memset_s(taskPool, sizeof(TaskPool) + sizeof(ThreadId) * size, 0,
                   sizeof(TaskPool) + sizeof(ThreadId) * size);
    // 任务池消息ID赋值
    taskPool->queueId = queueId;
    // 任务池堆栈大小赋值
    taskPool->stackSize = config->stackSize;
    // 任务池优先级赋值
    taskPool->priority = (uint8)config->priority;
    // 任务池大小赋值,这里是1
    taskPool->size = size;
    taskPool->top = 0;
    taskPool->ref = 1;
    return taskPool;
}

初始化单个服务

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/samgr_lite.c

static void InitializeSingleService(ServiceImpl *service)
{
    // 如果service的任务池为NULL,直接进行服务初始化
    if (service->taskPool == NULL) {
        DEFAULT_Initialize(service);
        return;
    }
    // 否则,向这个服务的消息队列发送一个direct类型的消息(这个消息执行的时候进行服务初始化)
    Identity identity = {service->serviceId, INVALID_INDEX, service->taskPool->queueId};
    Request request = {0, 0, service, 0};
    uint32 *ref = NULL;
    (void)SAMGR_SendSharedDirectRequest(&identity, &request, NULL, &ref, HandleInitRequest);
}

启动任务池(线程池)

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/task_manager.c

int32 SAMGR_StartTaskPool(TaskPool *pool, const char *name)
{
    if (pool == NULL) {
        return EC_INVALID;
    }

    if (pool->top > 0) {
        return EC_SUCCESS;
    }
    // 构建线程属性结构体
    // 线程的名字就是服务的名字
    ThreadAttr attr = {name, pool->stackSize, pool->priority, 0, 0};
    // 直接装满线程池,启动全部任务线程
    while (pool->top < pool->size) {
    	// 调用封装的posix接口创建线程
        register ThreadId threadId = (ThreadId)THREAD_Create(TaskEntry, pool->queueId, &attr);
        if (threadId == NULL) {
            HILOG_ERROR(HILOG_MODULE_SAMGR, "Start Task<%s, %d, %d> failed!", name, pool->stackSize, pool->priority);
            break;
        }
        // 保存线程ID
        pool->tasks[pool->top] = threadId;
        ++(pool->top);
    }
    return EC_SUCCESS;
}

static void *TaskEntry(void *argv)
{
    ServiceImpl *serviceImpl = NULL;
    // 设置threadLocal,传入的参数是本线程的消息队列ID
    THREAD_SetThreadLocal(argv);
    // 服务线程最终的归宿
    // 无线循环,处理消息任务
    while (TRUE) {
        Exchange exchange;
        // 尝试从消息队列取出一个消息到exchange,如果消息队列为空,本线程会阻塞在此(不占用CPU,有消息到来时,会被唤醒)
        uint32 msgRcvRet = SAMGR_MsgRecv((MQueueId)argv, (uint8 *)&exchange, sizeof(Exchange));
        if (msgRcvRet != EC_SUCCESS) {
            continue;
        }
        // 收到退出消息,退出线程循环
        if (exchange.type == MSG_EXIT) {
            SAMGR_FreeMsg(&exchange);
            break;
        }

        serviceImpl = CorrectServiceImpl(&exchange, serviceImpl);
        BeginWork(serviceImpl);
        ProcResponse(&exchange);
        ProcDirectRequest(&exchange);
        ProcRequest(&exchange, serviceImpl);
        EndWork(serviceImpl, &exchange);
        SAMGR_FreeMsg(&exchange);
    }
    // 线程退出,销毁消息队列,释放内存
    QUEUE_Destroy((MQueueId)argv);
    return NULL;
}

服务线程处理任务的过程

依次展开上面的5个函数,直接上代码:

static void BeginWork(ServiceImpl *service)
{
	// 如果服务线程不是IDLE状态,则直接返回
    if (service == NULL || service->inited != SVC_IDLE) {
        return;
    }
    // 如果系统处于BOOT_SYS_WAIT阶段
    if (service->ops.step == BOOT_SYS_WAIT) {
    	// WDT_Start()函数目前是空实现
        WDT_Start(MSG_PROC_THRESHOLD);
    }
    // 记录已处理的消息次数
    service->ops.messages++;
    // 记录开始处理消息的时间
    service->ops.timestamp = SAMGR_GetProcessTime();
    // 设置线程状态为BUSY
    service->inited = SVC_BUSY;
}

// 处理应答消息
// 首先检查handler和消息类型
// 然后直接调用handler处理消息
static void ProcResponse(Exchange *exchange)
{
    if (exchange->handler == NULL) {
        return;
    }

    if (exchange->type != MSG_ACK) {
        return;
    }

    exchange->handler(&exchange->request, &exchange->response);
}

// 处理直接请求。direct类型的消息是不需要应答的
static void ProcDirectRequest(Exchange *exchange)
{
    if (exchange->handler == NULL) {
        return;
    }

    if (exchange->type != MSG_DIRECT) {
        return;
    }

    exchange->handler(&exchange->request, &exchange->response);
}

static void ProcRequest(Exchange *exchange, ServiceImpl *serviceImpl)
{
    if (serviceImpl == NULL || exchange->type == MSG_ACK || exchange->type == MSG_DIRECT) {
        return;
    }
    // 处理消息的实际逻辑
    DEFAULT_MessageHandle(serviceImpl, &(exchange->id), &(exchange->request));
    // 如果是对话类型的消息,需要发送response给request方
    if (exchange->type == MSG_CON) {
        SAMGR_SendResponse(&exchange->request, &exchange->response);
    }
}

static void EndWork(ServiceImpl *service, const Exchange *exchange)
{
	// 如果服务线程不处于BUSY状态,则直接返回
    if (service == NULL || service->inited != SVC_BUSY) {
        return;
    }
    // 如果系统处于BOOT_SYS_WAIT阶段
    if (service->ops.step == BOOT_SYS_WAIT) {
    	// WDT_Stop()函数目前是空实现
        WDT_Stop();
    }

    uint32 lastTime = service->ops.timestamp;
    // 记录消息被处理完成的时间
    service->ops.timestamp = (uint32)SAMGR_GetProcessTime();
    uint32 interval = GET_INTERVAL(lastTime, service->ops.timestamp);
    // 消息处理时间超过10ms,被认为是不正常的
    if (interval > MSG_PROC_THRESHOLD) {
        const char *name = service->service->GetName(service->service);
        // 打印日志
        HILOG_INFO(HILOG_MODULE_SAMGR, "Message Timeout <service:%s, feature:%d, type:%d, reqId:%d, time:%ums>",
                   name, exchange->id.featureId, exchange->type, exchange->request.msgId, interval);
        // 记录异常消息次数
        service->ops.abnormal++;
    }
    // 服务线程状态置为IDLE
    service->inited = SVC_IDLE;
}

实质处理消息的逻辑

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/service.c

void DEFAULT_MessageHandle(ServiceImpl *serviceImpl, const Identity *identity, Request *msg)
{
    if (serviceImpl->serviceId != identity->serviceId) {
        return;
    }

    if (identity->featureId < 0) {
        if (serviceImpl->service->MessageHandle != NULL) {
        	// 调用服务的MessageHandle()函数处理消息
            serviceImpl->service->MessageHandle(serviceImpl->service, msg);
        }
        return;
    }

    if (VECTOR_Size(&serviceImpl->features) <= identity->featureId) {
        return;
    }

    FeatureImpl *featureImpl = (FeatureImpl *)VECTOR_At(&(serviceImpl->features), identity->featureId);
    if (featureImpl == NULL) {
        return;
    }
    // 调用feature的OnMessage()函数处理消息
    featureImpl->feature->OnMessage(featureImpl->feature, msg);
}

调用service的MessageHandler()或者feature的OnMessage()函数处理消息。MessageHandler()和OnMessage()是系统定义的接口,实现部分在SA的实现者那里。

检查初始化是否完成

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/samgr_lite.c

static int32 InitCompleted(void)
{
    // Did all services be inited?
    SamgrLiteImpl *manager = GetImplement();
    int16 pos = GetUninitializedPos();
    int16 size = VECTOR_Size(&(manager->services));
    // 如果条件成立,说明还有服务没有初始化,然后就直接返回
    // 每个服务启动完成的最后一步就是调用InitCompleted()函数,当最后一个服务启动完成之后,这个条件就是不在成立
    if (pos < size) {
        return EC_SUCCESS;
    }
    // 如果所有服务都完成初始化了
    MUTEX_Lock(manager->mutex);
    // 如果当前系统引导在BOOT_SYS_WAIT阶段
    if (manager->status == BOOT_SYS_WAIT) {
    	// 设置系统引导进入BOOT_APP阶段
        manager->status = BOOT_APP;
        MUTEX_Unlock(manager->mutex);
        // 打印系统引导信息
        HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all core system services!");
        WDT_Reset(WDG_SVC_REG_TIME);
        // 发送引导阶段的消息
        return SendBootRequest(BOOT_SYS_COMPLETED, pos);
    }
    // 如果当前系统引导在BOOT_APP_WAIT阶段
    if (manager->status == BOOT_APP_WAIT) {
    	// 设置系统引导进入BOOT_DYNAMIC阶段
        manager->status = BOOT_DYNAMIC;
        MUTEX_Unlock(manager->mutex);
        // 打印系统引导信息
        HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all system and application services!");
        WDT_Reset(WDG_SVC_TEST_TIME);
        // 发送引导阶段的消息
        return SendBootRequest(BOOT_APP_COMPLETED, pos);
    }
    MUTEX_Unlock(manager->mutex);
    // 与前面的WDT_Reset()对应
    WDT_Stop();
    return EC_SUCCESS;
}

static int32 SendBootRequest(int msgId, uint32 msgValue)
{
	// 获取服务Bootstrap的Identity
    Identity id = DEFAULT_GetFeatureId(GetService(BOOTSTRAP_SERVICE), NULL);
    Request request = {msgId, 0, NULL, msgValue};
    // 向服务Bootstrap发送消息
    return SAMGR_SendRequest(&id, &request, (Handler)SAMGR_Bootstrap);
}

系统引导服务

code-1.0/foundation/distributedschedule/interfaces/innerkits/samgr_lite/samgr/samgr_lite.h

/**
 * @brief Starts a bootstrap service, which is used by samgr and implemented by system service
 * developers.
 */
#define BOOTSTRAP_SERVICE "Bootstrap"

/**
 * @brief Enumerates the IDs of the message to be processed for starting the bootstrap service.
 *
 * This function is implemented by developers of the system service. \n
 * Messages sent to the bootstrap service when Samgr is started. \n
 *
 */
typedef enum BootMessage {
    /** Message indicating that the core system service is initialized */
    BOOT_SYS_COMPLETED,
    /** Message indicating that the system and application-layer services are initialized */
    BOOT_APP_COMPLETED,
    /** Message indicating service registration during running */
    BOOT_REG_SERVICE,
    /** Maximum number of message IDs */
    BOOTSTRAP_BUTT
} BootMessage;

Bootstrap系统引导服务,开发的操作系统代码并没有给出实现,需要系统服务开发者根据自己的需要进行实现。

这里定义了三条系统引导阶段的消息,分别是:

  • BOOT_SYS_COMPLETED 这条消息标志者核心系统服务启动完成
  • BOOT_APP_COMPLETED 这条消息标志着系统和应用层服务已经启动完成
  • BOOT_REG_SERVICE 这条消息标志着系统运行阶段的服务注册

重要数据结构

任务类型

code-1.0/foundation/distributedschedule/interfaces/innerkits/samgr_lite/samgr/service.h

typedef enum TaskType {
    /** Tasks shared based on their priority by services */
    SHARED_TASK = 0,
    /** Task exclusively occupied by a service */
    SINGLE_TASK = 1,
    /** A specified task shared by multiple services */
    SPECIFIED_TASK = 2,
    /** No task for the service. Generally, this situation does not occur. */
    NO_TASK = 0xFF,
} TaskType;

SHARED_TASK是根据优先级被多个服务共享的任务。任务池最多同时被15个服务使用(MAX_REF_NUM)。

SINGLE_TASK是指属于一个服务的任务。单任务。只有一个任务/线程的任务/线程池。

SPECIFIED_TASK是多个服务共享的任务。多个服务共享同一个任务池。

任务优先级

typedef enum TaskPriority {
    /** Low-priority: (9, 15) */
    PRI_LOW = 9,
    /** Lower than the normal priority: [16, 23) */
    PRI_BELOW_NORMAL = 16,
    /** Normal priority: [24, 31). The log service is available. */
    PRI_NORMAL = 24,
    /** Higher than the normal priority: [32, 39). The communication service is available. */
    PRI_ABOVE_NORMAL = 32,
    /** Upper limit of the priority */
    PRI_BUTT = 39,
} TaskPriority;

任务优先级,优先级范围是9-39,9的优先级最低,39的优先级最高。

任务池

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/source/task_manager.h

struct TaskPool {
    MQueueId queueId;   // 消息队列id,其实就是一个void*类型的指针
    uint16 stackSize;   // 堆栈大小
    uint8 priority;     // 里面任务的优先级
    uint8 size;         // 任务池大小(可以容纳多少个任务,即可以开启多少个线程)
    uint8 top;          // 已经开启的线程数量
    int8 ref;			// 任务池可以在多个服务见共享,这个参数表示目前有几个服务在同时使用这个任务池
    ThreadId tasks[0];  // 存放已开启的线程ID
};

任务配置信息

code-1.0\foundation\distributedschedule\interfaces\innerkits\samgr_lite\samgr\service.h

struct TaskConfig {
    /**
     * ID of a multi-service sharing task. For details about the level definition,
     * see {@link SpecifyTag}.
     */
    int16 level;
    /** Task priority. For details about the definition of priority, see {@link TaskPriority}. */
    int16 priority;
    /** Size of a task stack */
    uint16 stackSize;
    /** Size of a task queue */
    uint16 queueSize;
    /** Task type. For details about the taskFlags definition, see {@link TaskType}. */
    uint8 taskFlags;
};

定义服务的任务配置信息,包括任务的优先级、堆栈大小、队列长度(可以存放的消息个数)、任务类型、多服务共享任务ID。

Exchange

code-1.0\foundation\distributedschedule\services\samgr_lite\samgr\source\message_inner.h

struct Exchange {
    Identity id; /**< The target service or feature identity. */
    Request request;        // 请求数据
    Response response;      // 回应数据
    short type;  /**< The exchange type. */
    Handler handler;   /**< async response or immediately request callback function */
    uint32 *sharedRef; /**< use to share the request and response for saving memory */
};

Exchange交换的意思,消息交换。

ServiceImpl

code-1.0\foundation\distributedschedule\services\samgr_lite\samgr\source\service_impl.h

struct ServiceImpl {
    Service *service;       // 函数指针,可以调用服务接口:GetName/Initialize/MessageHandle/GetTaskConfig
    IUnknown *defaultApi;   // default feature api
    TaskPool *taskPool;     // 任务池
    Vector features;        // 其它feature
    int16 serviceId;        // service id
    uint8 inited;           // 标识服务的状态,三个可选值:INIT/IDLE/BUSY
    Operations ops;
};

struct Operations {
    uint8 abnormal;			// 记录异常处理消息的次数(处理时间超过10ms的消息)
    uint8 step;				// 记录系统的开机阶段(BOOT_SYS、BOOT_SYS_WAIT、BOOT_APP等)
    uint16 messages;     	// 记录已处理消息的数量
    uint32 timestamp;		// 记录最后一条消息开始/结束被处理的时间
};

服务线程在开始工作和结束工作的时候会设置服务状态标识。

  • 初始状态 SVC_INIT
  • 服务初始化,服务线程启动处理第一个消息时,会设置状态为SVC_IDLE(在函数HandleInitRequest里面)
  • 开始工作 SVC_IDLE -> SVC_BUSY
  • 结束工作 SVC_BUSY -> SVC_IDLE

线程属性

code-1.0/foundation/distributedschedule/services/samgr_lite/samgr/adapter/thread_adapter.h

typedef struct ThreadAttr ThreadAttr;
struct ThreadAttr {
    const char *name;   // name of the thread
    uint32 stackSize;   // size of stack
    uint8 priority;     // initial thread priority
    uint8 reserved1;    // reserved1 (must be 0)
    uint16 reserved2;   // reserved2 (must be 0)
};

线程属性,依次是:名字、堆栈大小、优先级和两个保留字段。