ort_pools.c

#include "ort_prive.h"
#include <stdlib.h>
#include <stdio.h>

ort_task_node_t* ort_task_alloc(void* (*func)(void *), void *arg)
{
  if(arg != NULL)//任务函数参数非空,那么就返回此参数所在的任务节点
    return *((ort_task_node_t **)PP(arg));
  if(func != NULL)
  {//此时任务函数参数为空,但是任务函数存在,获取一个没有参数的任务节点
    arg = ort_taskenv_alloc(0, func);
    return (*((ort_task_node_t **)PP(arg)));//返回此任务节点
  }
  return ort_task_empty_node_alloc();//当任务函数不存在,任务函数参数不存在,就创建一个空的任务节点
}

void ort_task_free(ort_eecb_t *thr, ort_task_node_t* node)
{//此函数用于将指定节点放到指定eecb的回收站中去
  ort_task_node_pool_t *task_node_pool;
  int my_max_mates = thr->tasking.max_mates;

  /* if node was allocated form a node pool */
  if(node->occupied == 1)//待回收的节点是节点池中的节点,修改它的使用情况即可
    node->occupied = 0;
  else /* else store node in my recycle bin */
  {//待回收的节点是从回收站分配的节点

    task_node_pool = thr->tasking.task_node_pool;
    while(task_node_pool != NULL)
    {//从任务节点池队列中搜索该task-func属于那个节点池
      if(task_node_pool->task_func == node->func)
      {//找到了对应的任务节点池
        node->next = task_node_pool->recycler;
        task_node_pool->recycler = node;//将此任务节点重新链接到回收站
        return;
      }
      task_node_pool = task_node_pool->next;//搜寻下一个任务节点池
    }

    //我没有为这个task-func分配一个任务节点池,那么分配一个
    task_node_pool = (ort_task_node_pool_t *) ort_calloc_aligned(sizeof(ort_task_node_pool_t), NULL);
    task_node_pool->task_func = node->func;//指定新建的任务节点池的任务函数
    node->next = NULL;//将待回收的任务节点链接到新建的任务节点池的回收站中
    task_node_pool->recycler = node;
    //创建多个任务节点
    task_node_pool->sub_pool = (ort_task_node_t*) ort_calloc(TASKPOOLSIZE(my_max_mates)*sizeof(ort_task_node_t));
    //将此新建的任务节点池放到链表中去
    task_node_pool->next = thr->tasking.task_node_pool;
    thr->tasking.task_node_pool = task_node_pool;
  }
}

void task_pools_init(ort_eecb_t *t)
{
  ort_tasking_t        *td = &(t->tasking);
  ort_task_node_pool_t *tnp;
  int                   i, teamsize = t->num_siblings;

  if(td->task_node_pool == NULL)
  {
    td->max_mates = teamsize;
    return;
  }
  else if(td->max_mates >= teamsize)
    return;

  //非空并且当前任务节点池的数量不足teamsize
  tnp = td->task_node_pool;
  while(tnp != NULL)
  {
    for (i = 0; i< TASKPOOLSIZE(td->max_mates); i++)
    {//将任务节点池中各个任务节点的任务参数置为空
      if((tnp->sub_pool[i]).funcarg != NULL)
        free((tnp->sub_pool[i]).funcarg);
    }

    //realloc任务节点数组的大小
    tnp->sub_pool = (ort_task_node_t*)
          ort_realloc(tnp->sub_pool, TASKPOOLSIZE(teamsize)*sizeof(ort_task_node_t));

    for (i=0; i< TASKPOOLSIZE(teamsize); i++)
    {//初始化任务节点池中任务节点数组中各个节点的参数
      (tnp->sub_pool[i]).next = NULL;
      (tnp->sub_pool[i]).func = NULL;
      (tnp->sub_pool[i]).occupied = 0;//表示未被使用
      (tnp->sub_pool[i]).funcarg = NULL;
    }

    tnp = tnp->next;//搜寻下一个任务节点池
  }

  td->max_mates = teamsize;//设置任务节点池中节点数组的容量
}

void *ort_taskenv_alloc(int size, void *(*task_func)(void *))
{//返回一个任务函数的参数节点,size为任务参数结构体的大小(即sizeof(struct __taskenv__)),另一个参数是任务函数的地址
  ort_eecb_t      *me = __MYCB;
  ort_task_node_pool_t *task_node_pool;
  ort_task_node_t      *new_node;
  int i;
  int my_max_mates = me->tasking.max_mates;//存储的是任务节点池的大小,即一个任务节点池中有多少任务节点(有3个任务节点不包含)

  task_node_pool = me->tasking.task_node_pool;//获取任务节点池的头指针

  while(task_node_pool != NULL)
  {//遍历链表
    if(task_node_pool->task_func == task_func)
    {//找到对应的节点池
      //遍历此线程池,找到第一个空的节点
      for(i=0; i<(TASKPOOLSIZE(my_max_mates)); i++)
        if (task_node_pool->sub_pool[i].occupied == 0)
        {//找到一个空的节点
            if(task_node_pool->sub_pool[i].funcarg == NULL)//当前任务节点的任务函数参数为空
                ALLOCATE_ENV(task_node_pool->sub_pool[i], size);//新建一个任务函数参数存储空间,在首位存储任务节点的地址,然后才是真正的参数存储空间


            task_node_pool->sub_pool[i].occupied = 1;//修改该任务节点的使用标志
            return NP(task_node_pool->sub_pool[i].funcarg);//返回指向struct __taskenv__结构体的指针,调用者此时可以向里面填充任务函数的参数值
        }

      /* Pool is full, allocate a task node and return it */
      new_node = task_node_pool->recycler;//获取回收站的第一个任务节点

      if(new_node == NULL)
      {//表明回收站是空的,那么新建一个任务节点
            new_node = (ort_task_node_t *)ort_calloc_aligned(sizeof(ort_task_node_t), NULL);
            new_node->next = NULL;//将新建的任务节点的next设置为空
            ALLOCATE_PENV(new_node, size);//给新建的任务节点分配参数存储空间
            new_node->occupied = 2;//设置任务节点的使用标志
      }
      else
            task_node_pool->recycler = task_node_pool->recycler->next;//回收站非空,指向下一个任务节点

      return NP(new_node->funcarg);//返回指向任务参数存储空间的地址
    }

    task_node_pool = task_node_pool->next;//此任务节点池不属于此任务函数,搜寻下一个
  }

  //此时我并没有在任务节点池链表中找到属于task-func的任务节点池,所以需分配一个属于自己的任务节点池
  task_node_pool = (ort_task_node_pool_t *)ort_calloc_aligned(sizeof(ort_task_node_pool_t), NULL);
  task_node_pool->task_func = task_func;//设置该任务节点池属于那个任务函数
  task_node_pool->recycler = NULL;//设置初始回收站指向为空,表示回收站中没有任务节点
  //新建多个任务节点
  task_node_pool->sub_pool = (ort_task_node_t*) ort_calloc(TASKPOOLSIZE(my_max_mates)*sizeof(ort_task_node_t));

  //将此任务节点池链接到任务节点池链表中
  task_node_pool->next = me->tasking.task_node_pool;
  me->tasking.task_node_pool = task_node_pool;

  ALLOCATE_ENV(task_node_pool->sub_pool[0], size);//分配一个任务函数参数的存储空间
  task_node_pool->sub_pool[0].occupied = 1;//设置第一个任务节点的使用标志
  return NP(task_node_pool->sub_pool[0].funcarg);//返回任务函数参数的地址,调用者使用具体值来填充此地址
}

ort_task_node_t* ort_task_empty_node_alloc(void)
{
  ort_eecb_t      *me = __MYCB;
  ort_task_node_pool_t *task_node_pool;
  ort_task_node_t      *new_node;
  int i;
  int my_max_mates = me->tasking.max_mates;

  task_node_pool = me->tasking.task_node_pool;

  while(task_node_pool != NULL)
  {//搜索本eecb的任务节点池链表,看是否有空的任务节点池,若有则返回此节点池中一个没有使用的任务节点
    if(task_node_pool->task_func == NULL)
    {
      //搜索这个空的任务节点池
      for(i=0; i<(TASKPOOLSIZE(my_max_mates)); i++)
        if (task_node_pool->sub_pool[i].occupied == 0)
        {//找到一个没有使用的任务节点
            task_node_pool->sub_pool[i].funcarg = NULL;
            task_node_pool->sub_pool[i].occupied = 1;//设置使用标志
            return &(task_node_pool->sub_pool[i]);//返回这个空的任务节点的地址
        }

      //这个任务节点池中的节点都已被占用,那么从回收站中获取一个任务节点
      new_node = task_node_pool->recycler;

      if(new_node == NULL)
      {//回收站中没有节点,新建一个任务节点
        new_node = (ort_task_node_t *)ort_calloc_aligned(sizeof(ort_task_node_t), NULL);
        new_node->next = NULL;
        new_node->occupied = 2;//此标志表明该任务节点最终会被回收到回收站中
      }
      else//回收站中有任务节点
        task_node_pool->recycler = task_node_pool->recycler->next;//修改回收站的起始位置

      return new_node;//返回回收站中的此任务节点
    }
    task_node_pool = task_node_pool->next;//搜寻下一个任务节点池
  }

  //没有找到空的任务节点池,那么新建一个任务节点池
  task_node_pool = (ort_task_node_pool_t *)ort_calloc_aligned(sizeof(ort_task_node_pool_t), NULL);
  task_node_pool->task_func = NULL;//没有确定该任务节点池属于哪个任务函数
  task_node_pool->recycler = NULL;//设置回收站中当前节点为空
  //给该任务节点池创建多个任务节点,这是一个节点数组,此中节点的回收方式为1.
  task_node_pool->sub_pool = (ort_task_node_t*)ort_calloc(TASKPOOLSIZE(my_max_mates)*sizeof(ort_task_node_t));

  //将此任务节点池放入链表中
  task_node_pool->next = me->tasking.task_node_pool;
  me->tasking.task_node_pool = task_node_pool;

  //从任务节点数组中取出第一个节点,设置其任务函数参数为空,并设置此节点的回收方式
  task_node_pool->sub_pool[0].funcarg = NULL;
  task_node_pool->sub_pool[0].occupied = 1;//设置此标志为1表示回收时只需要将此标志修改为0即可
  return &(task_node_pool->sub_pool[0]);//返回这个节点的地址
}

void ort_taskenv_free(void *ptr, void *(*task_func)(void *))
{
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值