LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_agent/adapter/async - ra_adp_pool.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.8 % 118 93
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include <sys/prctl.h>
      12              : #include <pthread.h>
      13              : #include "securec.h"
      14              : #include "user_log.h"
      15              : #include "ra_hdc.h"
      16              : #include "ra_rs_err.h"
      17              : #include "ra_adp_pool.h"
      18              : 
      19            2 : STATIC void *RaHdcWorkerThread(void *arg)
      20              : {
      21            2 :     struct RaHdcThreadPool *pool = (struct RaHdcThreadPool *)arg;
      22            2 :     pthread_t tidp = pthread_self();
      23            2 :     struct RaHdcTask task = {0};
      24              : 
      25            2 :     (void)prctl(PR_SET_NAME, (uintptr_t) "hccp_rs_work", 0, 0, 0);
      26              : 
      27              :     while (1) {
      28            2 :         RA_PTHREAD_MUTEX_LOCK(&pool->poolMutex);
      29              :         // block thread until task received
      30            4 :         while (pool->taskNum == 0 && pool->shutdown != SHUTDOWN_SIGNAL) {
      31            2 :             pthread_cond_wait(&pool->condition, &pool->poolMutex);
      32              :         }
      33            2 :         if (pool->shutdown == SHUTDOWN_SIGNAL) {
      34            2 :             pool->threadNum--;
      35            2 :             RA_PTHREAD_MUTEX_UNLOCK(&pool->poolMutex);
      36            2 :             break;
      37              :         }
      38              : 
      39              :         // consume a task
      40            0 :         task.func = pool->taskQueue[pool->queueCi].func;
      41            0 :         task.args.chipId = pool->taskQueue[pool->queueCi].args.chipId;
      42            0 :         task.args.recvBuf = pool->taskQueue[pool->queueCi].args.recvBuf;
      43            0 :         task.args.recvLen = pool->taskQueue[pool->queueCi].args.recvLen;
      44            0 :         pool->queueCi = (pool->queueCi + 1) % pool->queueSize;
      45            0 :         pool->taskNum--;
      46              : 
      47              :         // notify manager to produce
      48            0 :         pthread_cond_signal(&pool->condition);
      49            0 :         RA_PTHREAD_MUTEX_UNLOCK(&pool->poolMutex);
      50              : 
      51              :         // do task
      52            0 :         task.func(task.args.chipId, task.args.recvBuf, task.args.recvLen);
      53            0 :         free(task.args.recvBuf);
      54            0 :         task.args.recvBuf = NULL;
      55              :     }
      56              : 
      57            2 :     hccp_run_info("tidp:%ld exit", tidp);
      58            2 :     return NULL;
      59              : }
      60              : 
      61            2 : STATIC int RaHdcPoolMutexCondInit(struct RaHdcThreadPool *pool)
      62              : {
      63              :     int ret;
      64              : 
      65            2 :     ret = pthread_mutex_init(&pool->poolMutex, NULL);
      66            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("pool_mutex mutex_init failed ret %d", ret), -ESYSFUNC);
      67              : 
      68            2 :     ret = pthread_cond_init(&pool->condition, NULL);
      69            2 :     if (ret != 0) {
      70            0 :         hccp_err("condition cond_init failed ret %d", ret);
      71            0 :         ret = -ESYSFUNC;
      72            0 :         goto deinit_pool_mutex;
      73              :     }
      74              : 
      75            2 :     return 0;
      76              : 
      77            0 : deinit_pool_mutex:
      78            0 :     pthread_mutex_destroy(&pool->poolMutex);
      79            0 :     return ret;
      80              : }
      81              : 
      82            2 : STATIC void RaHdcPoolMutexCondDeinit(struct RaHdcThreadPool *pool)
      83              : {
      84            2 :     pthread_cond_destroy(&pool->condition);
      85            2 :     pthread_mutex_destroy(&pool->poolMutex);
      86            2 : }
      87              : 
      88            2 : STATIC void RaHdcPoolFreeWorkers(struct RaHdcThreadPool *pool)
      89              : {
      90            2 :     int timeout = RA_THREAD_TRY_TIME;
      91              :     unsigned int i;
      92              : 
      93            2 :     RA_PTHREAD_MUTEX_LOCK(&pool->poolMutex);
      94            2 :     pool->shutdown = SHUTDOWN_SIGNAL;
      95            4 :     for (i = 0; i < pool->threadNum; i++) {
      96            2 :         pthread_cond_signal(&pool->condition);
      97              :     }
      98            2 :     RA_PTHREAD_MUTEX_UNLOCK(&pool->poolMutex);
      99              : 
     100              :     // wait for all threads exit until time out: RA_THREAD_TRY_TIME * RA_THREAD_SLEEP_TIME us
     101            3 :     while (pool->threadNum > 0 && timeout > 0) {
     102            1 :         usleep(RA_THREAD_SLEEP_TIME);
     103            1 :         timeout--;
     104              :     }
     105            2 :     if (pool->threadNum > 0 && timeout <= 0) {
     106            0 :         hccp_warn("destroy thread pool timeout, threadNum:%u > 0 and timeout:%d <= 0", pool->threadNum, timeout);
     107              :     }
     108            2 : }
     109              : 
     110            2 : struct RaHdcThreadPool *RaHdcPoolCreate(unsigned int queueSize, unsigned int threadNum)
     111              : {
     112            2 :     struct RaHdcThreadPool *pool = NULL;
     113              :     unsigned int i;
     114              :     int ret;
     115              : 
     116            2 :     pool = (struct RaHdcThreadPool *)calloc(1, sizeof(struct RaHdcThreadPool));
     117            2 :     CHK_PRT_RETURN(pool == NULL, hccp_err("calloc pool failed"), NULL);
     118            2 :     pool->taskQueue = (struct RaHdcTask *)calloc(queueSize, sizeof(struct RaHdcTask));
     119            2 :     if (pool->taskQueue == NULL) {
     120            0 :         hccp_err("calloc task_queue failed, queueSize:%u", queueSize);
     121            0 :         goto free_pool;
     122              :     }
     123            2 :     pool->queueSize = queueSize;
     124              : 
     125            2 :     ret = RaHdcPoolMutexCondInit(pool);
     126            2 :     if (ret != 0) {
     127            0 :         hccp_err("ra_hdc_pool_mutex_cond_init failed, ret:%d", ret);
     128            0 :         goto free_queue;
     129              :     }
     130              : 
     131            2 :     pool->workerThreads = (pthread_t *)calloc(threadNum, sizeof(pthread_t));
     132            2 :     if (pool->workerThreads == NULL) {
     133            0 :         hccp_err("calloc worker_threads failed, threadNum:%u", threadNum);
     134            0 :         goto free_cond;
     135              :     }
     136            4 :     for (i = 0; i < threadNum; i++) {
     137            3 :         ret = pthread_create(&pool->workerThreads[i], NULL, (void *)RaHdcWorkerThread, pool);
     138            3 :         if (ret != 0) {
     139            1 :             hccp_err("Create pthread i:%u failed, ret:%d", i, ret);
     140            1 :             pool->threadNum = i;
     141            1 :             goto free_thread;
     142              :         }
     143              :     }
     144            1 :     pool->threadNum = threadNum;
     145              : 
     146            1 :     return pool;
     147            1 : free_thread:
     148            1 :     RaHdcPoolFreeWorkers(pool);
     149            1 :     free(pool->workerThreads);
     150            1 :     pool->workerThreads = NULL;
     151            1 : free_cond:
     152            1 :     RaHdcPoolMutexCondDeinit(pool);
     153            1 : free_queue:
     154            1 :     free(pool->taskQueue);
     155            1 :     pool->taskQueue = NULL;
     156            1 : free_pool:
     157            1 :     free(pool);
     158            1 :     pool = NULL;
     159            1 :     return NULL;
     160              : }
     161              : 
     162            1 : void RaHdcPoolAddTask(struct RaHdcThreadPool *pool, TaskFuncT func, unsigned int chipId, void *recvBuf,
     163              :     unsigned int recvLen)
     164              : {
     165            1 :     RA_PTHREAD_MUTEX_LOCK(&pool->poolMutex);
     166              :     // block until task can be received
     167            1 :     while (pool->taskNum == pool->queueSize) {
     168            0 :         pthread_cond_wait(&pool->condition, &pool->poolMutex);
     169              :     }
     170              : 
     171              :     // produce a task
     172            1 :     pool->taskQueue[pool->queuePi].func = func;
     173            1 :     pool->taskQueue[pool->queuePi].args.chipId = chipId;
     174            1 :     pool->taskQueue[pool->queuePi].args.recvBuf = recvBuf;
     175            1 :     pool->taskQueue[pool->queuePi].args.recvLen = recvLen;
     176            1 :     pool->queuePi = (pool->queuePi + 1) % pool->queueSize;
     177            1 :     pool->taskNum++;
     178              : 
     179              :     // notify worker to consume
     180            1 :     pthread_cond_signal(&pool->condition);
     181            1 :     RA_PTHREAD_MUTEX_UNLOCK(&pool->poolMutex);
     182            1 : }
     183              : 
     184            1 : int RaHdcPoolDestroy(struct RaHdcThreadPool *pool)
     185              : {
     186            1 :     CHK_PRT_RETURN(pool == NULL, hccp_err("param invalid, pool is NULL"), -EINVAL);
     187              : 
     188            1 :     RaHdcPoolFreeWorkers(pool);
     189            1 :     if (pool->taskQueue != NULL) {
     190            1 :         free(pool->taskQueue);
     191            1 :         pool->taskQueue = NULL;
     192              :     }
     193            1 :     if (pool->workerThreads) {
     194            1 :         free(pool->workerThreads);
     195            1 :         pool->workerThreads = NULL;
     196              :     }
     197            1 :     RaHdcPoolMutexCondDeinit(pool);
     198            1 :     free(pool);
     199            1 :     pool = NULL;
     200            1 :     return 0;
     201              : }
        

Generated by: LCOV version 2.0-1