RT_Thread内核源码分析(二)——链表和对象管理

       

目录

1、链表

1.1 双向链表

1.1.1 链表结构

1.1.2 链表操作

1.1.3 链表遍历

1.2 单向链表

1.2.1 链表结构 

1.2.2 链表操作

1.2.3 链表遍历

2、对象

2.1 内核对象结构

2.2 内核对象分类

2.3 内核对象容器

2.4 内核对象继承 

2.5 内核对象操作

2.6 内核对象钩子


         实时操作系统基本上都是通过一些链表进行线程、信号、队列的管理,RT_Thread也不例外,本章主要讲解RT_Thread的链表结构和对象管理。

本章基于RT_Thread Nano V3.1.5版本分析

      

1、链表

          RT_Thread使用的链表非常简单,链表节点只有节点指针,各节点在实例结构体中定义,可以通过头节点定位链表,可以通过节点在结构体中的偏移定位实例结构体。

1.1 双向链表

1.1.1 链表结构

        双向链表结构声明如下

struct rt_list_node
{
    struct rt_list_node *next;                          /**< 指向下一个节点. */
    struct rt_list_node *prev;                          /**< 指向上一个节点. */
};

        双向链表通过一个头节点对整个链表管理,如下所示,NODE1为头节点,用于定位链表,NODE2~NODEn为被链表管理的节点。

        双向链表主要用于对象、线程、定时器等实例管理,这些管理均需要提前设置头节点,如下所示,为系统内核定义的双链表头节点,还有一些头节点在结构体中定义,此处不再详述。

/********线程全局变量********/
extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; // 就绪线程链表数组
extern rt_list_t rt_thread_defunct;                                // 失效线程链表
/* 软件定时器链表 soft timer list */
static rt_list_t rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
/* 硬件定时器 hard timer list */
static rt_list_t rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL];


1.1.2 链表操作

        链表操作采用内联函数和宏定义的方式,可以免去操作时的环境存储与恢复,提高运行效率。操作接口主要有初始化、插入节点(表头或表尾)、删除节点。

初始化

/*节点初始化(节点指针均指向自己)*/
#define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }

/*链表头节点初始化(节点指针均指向自己)*/
rt_inline void rt_list_init(rt_list_t *l)
{
    l->next = l->prev = l;
}

插入节点至表头

/*节点n插入到链表l的头部*/
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
{
    l->next->prev = n;
    n->next = l->next;

    l->next = n;
    n->prev = l;
}

  NODE1为头节点,用于定位链表,NODE2~NODEn为链表管理的节点,NewNode为新插入的节点。

   插入节点至表尾

/*节点n插入到链表l的尾部*/
rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
{
    l->prev->next = n;
    n->prev = l->prev;

    l->prev = n;
    n->next = l;
}

         NODE1为头节点,用于定位链表,NODE2~NODEn为链表管理的节点,NewNode为新插入的节点。

删除节点

/*链表移除节点n*/ 
rt_inline void rt_list_remove(rt_list_t *n)
{
    n->next->prev = n->prev;
    n->prev->next = n->next;
    n->next = n->prev = n;
}

         NODE1为头节点,用于定位链表,DeleteNode、NODE2~NODEn为链表管理的节点,该图为删除节点DeleteNode。

1.1.3 链表遍历

        链表遍历接口采用内联函数和宏定义的方式,可以免去操作时的环境存储与恢复,提高运行效率。

        链表节点多数存储在各类对象的结构体中,当遍历到一个节点时,可通过节点在结构体中的偏移获取结构体指针。所以链表本质上是对对象(结构体)的管理,因此,链表遍历不仅可以遍历节点,还可以遍历对象(结构体)。

/****判断链表条目数为空****/ 
rt_inline int rt_list_isempty(const rt_list_t *l)
{
    return l->next == l;
}
/****获取链表长度****/
rt_inline unsigned int rt_list_len(const rt_list_t *l)
{
    unsigned int len = 0;
    const rt_list_t *p = l;
    while (p->next != l)
    {
        p = p->next;
        len ++;
    }
    return len;
}
/****遍历链表节点(pos为遍历出的节点,head为头节点)*/
#define rt_list_for_each(pos, head)       \  
for(pos=(head)->next;pos!= (head);pos = pos->next)

/*****遍历链表节点(安全模式,防止误删除,pos为遍历出的节点,n指向pos下个节点,head为头节点) */
#define rt_list_for_each_safe(pos, n, head) \
for(pos=(head)->next,n=pos->next; pos!=(head); pos=n, n=pos->next)

/****定位对象(根据节点定位)***/
#define rt_container_of(ptr,type,member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/****获取元素*/
#define rt_list_entry(node, type, member) rt_container_of(node, type, member)

/*****遍历对象*/
#define rt_list_for_each_entry(pos, head, member) \
for(pos=rt_list_entry((head)->next,typeof(*pos),member);&pos->member!=(head);pos = rt_list_entry(pos->member.next, typeof(*pos), member)

/******遍历对象(安全模式,防止误删除)  */
#define rt_list_for_each_entry_safe(pos, n, head, member) \
    for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
         n = rt_list_entry(pos->member.next, typeof(*pos), member); \
         &pos->member != (head); \
         pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))

/*****获取链表第一个对象*/
#define rt_list_first_entry(ptr, type, member)  rt_list_entry((ptr)->next, type, member)

举例,比如遍历定时器,定时器结构体和链表如下所示:

/* 软件定时器链表 */
static rt_list_t rt_soft_timer_list;
/* 定时器结构体 */
struct rt_timer
{
    struct rt_object parent;                        /**< 基类对象*/
    rt_list_t   row;                                /**< 定时器链表节点*/
    void (*timeout_func)(void *parameter);          /**< 定时器函数指针 */
    void *parameter;                                /**< 定时器函数参数*/
    rt_tick_t        init_tick;                     /**< 定时器定时时间*/
    rt_tick_t        timeout_tick;                  /**< 定时器定时时刻*/
};
typedef struct rt_timer *rt_timer_t;
/*临时定时器*/
rt_timer_t  timerTemp;

         定时器链表节点在定时器结构体上的内存偏移为((struct rt_timer*)(0x0)->row),假设节点n为某个定时器的链表节点,获取定时器指针方法如下:

// 直接计算
struct rt_timer* pTimer=&n-((struct rt_timer*)(0x0)->row);
// 使用系统接口
struct rt_timer* pTimer=rt_container_of(&n,struct rt_timer*,row);

        假设定时器timerTemp已经插入到了链表rt_soft_timer_list中,在链表rt_soft_timer_list中定位到timerTemp的方法如下

/*在链表中定位定时器链表节点timerTemp.row*/ 
rt_list_for_each(&timerTemp->row, rt_soft_timer_list, row) 

/*在链表中定位定时器timerTemp*/
rt_list_for_each_entry(&timerTemp, rt_soft_timer_list, row) 

        由上述代码可见,rt_list_for_each与rt_list_for_each_entry接口作用相同,rt_list_for_each无疑性能更优,所以内核代码中并未使用rt_list_for_each_entry,而rt_list_for_each主要用于计算节点个数或判断节点是否连接在链表。

1.2 单向链表

        单向链表主要在内存池管理中使用,本章只罗列单向链表接口,其详细使用过程可以参考双向链表,二者接口相似。

1.2.1 链表结构 

struct rt_slist_node
{
    struct rt_slist_node *next;                         /**< 指向下一个节点*/
};

  1.2.2 链表操作

/*****对象节点初始化(初始化被管理的节点)*****/
#define RT_SLIST_OBJECT_INIT(object) { RT_NULL }

/****链表头节点初始化***/
rt_inline void rt_slist_init(rt_slist_t *l)
{
    l->next = RT_NULL;
}

/*****节点n插入到链表l的尾部*****/
rt_inline void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
{
    struct rt_slist_node *node;
    node = l;
    while (node->next) node = node->next;
    node->next = n;
    n->next = RT_NULL;
}

/*****节点n插入到链表l的头部*****/
rt_inline void rt_slist_insert(rt_slist_t *l, rt_slist_t *n)
{
    n->next = l->next;
    l->next = n;
}

/*****从链表l移除节点n*****/
rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
{
    struct rt_slist_node *node = l;
    while (node->next && node->next != n) node = node->next;
    if (node->next != (rt_slist_t *)0) node->next = node->next->next;
    return l;
}

  1.2.3 链表遍历

 /********定位元素member所在的结构体指针,结构体类型为type**********/
#define rt_container_of(ptr, type, member)   ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))


/******链表节点个数******/
rt_inline unsigned int rt_slist_len(const rt_slist_t *l)
{
    unsigned int len = 0;
    const rt_slist_t *list = l->next;
    while (list != RT_NULL)
    {
        list = list->next;
        len ++;
    }

    return len;
}
/*******单链表第一个节点*******/
rt_inline rt_slist_t *rt_slist_first(rt_slist_t *l)
{
    return l->next;
}
/*******单链表最后一个节点*******/
rt_inline rt_slist_t *rt_slist_tail(rt_slist_t *l)
{
    while (l->next) l = l->next;
    return l;
}
/*******节点n的下一个节点*******/
rt_inline rt_slist_t *rt_slist_next(rt_slist_t *n)
{
    return n->next;
}
/*******单链表为空*******/
rt_inline int rt_slist_isempty(rt_slist_t *l)
{
    return l->next == RT_NULL;
}

/********获取节点所在的结构体*******/
#define rt_slist_entry(node, type, member)  rt_container_of(node, type, member)

/********遍历链表的节点********/
#define rt_slist_for_each(pos, head) for(pos=(head)->next; pos!=RT_NULL; pos=pos->next)

/*********遍历链表节点对应的结构体****/
#define rt_slist_for_each_entry(pos, head, member) \
  for(pos=rt_slist_entry((head)->next,typeof(*pos),member); &pos->member!=(RT_NULL); \
      pos=rt_slist_entry(pos->member.next,typeof(*pos),member))

/**********获取链表第一个节点对应的结构体 *********/
#define rt_slist_first_entry(ptr, type, member) rt_slist_entry((ptr)->next, type, member)

/**********获取链表最后一个节点对应的结构体*********/
#define rt_slist_tail_entry(ptr,type,member) rt_slist_entry(rt_slist_tail(ptr),type,member)

2、对象

       RT_Thread操作系统为方便统一管理,采用的面相对象的思想,系统定义了内核对象(等同于C++中的基类),线程、信号、消息、内存池等继承内核对象(线程、信号、消息等同于派生类)。

2.1 内核对象结构

        内核对象节点list用于链表管理,flag参数在不同对象中起着不同的含义,比如在定时器对象中表示定时器状态和定时器类型。type参数表示对象类型,见【2.2内核对象分类】

 /*基类  内核对象*/
struct rt_object
{
    char       name[RT_NAME_MAX];                       /**< 内核对象名称 */
    rt_uint8_t type;                                    /**< 内核对象类型 */
    rt_uint8_t flag;                                    /**< 内核对象标志  */
    rt_list_t  list;                                    /**< 内核对象链表节点  */
};

 2.2 内核对象分类

        内核结构中type元素表示对象类型,对象类型如下所示,其中【静态对象掩码】并不是一类独立对象,而是表示对象的属性,即对象是静态对象(静态存储)还是动态对象(申请动态内存存储)。例如:静态内存创建的线程,其类型为RT_Object_Class_Thread+RT_Object_Class_Static=0x81

 /*对象类型枚举*/
enum rt_object_class_type
{
    RT_Object_Class_Null          = 0x00,       /**< 未使用. */
    RT_Object_Class_Thread        = 0x01,       /**< 线程对象. */
    RT_Object_Class_Semaphore     = 0x02,       /**< 信号对象. */
    RT_Object_Class_Mutex         = 0x03,       /**< 互斥对象. */
    RT_Object_Class_Event         = 0x04,       /**< 事件对象. */
    RT_Object_Class_MailBox       = 0x05,       /**< 邮件对象 */
    RT_Object_Class_MessageQueue  = 0x06,       /**< 消息对象. */
    RT_Object_Class_MemHeap       = 0x07,       /**< 内存堆对象. */
    RT_Object_Class_MemPool       = 0x08,       /**< 内存池对象. */
    RT_Object_Class_Device        = 0x09,       /**< 设备驱动对象. */
    RT_Object_Class_Timer         = 0x0a,       /**< 定时器对象. */
    RT_Object_Class_Unknown       = 0x0c,       /**< 未知对象. */
    
    RT_Object_Class_Static        = 0x80        /**< 静态对象掩码. */
};

2.3 内核对象容器

        内核对象容器,主要通过双向链表管理对象,其结构体中的链表节点即为链表头节点。

        对象容器结构体

struct rt_object_information
{
    enum rt_object_class_type type;                     /**< 对象类型 */
    rt_list_t                 object_list;              /**< 对象链表 */
    rt_size_t                 object_size;              /**< 对象大小 */
};

        对象容器定义

        通过定义可见,对象容器是一数组,可根据宏定义自动裁剪。

 /*对象容器枚举*/
enum rt_object_info_type
{
    RT_Object_Info_Thread = 0,                         /**< 线程对象. */
#ifdef RT_USING_SEMAPHORE
    RT_Object_Info_Semaphore,                          /**< 信号对象. */
#endif
#ifdef RT_USING_MUTEX
    RT_Object_Info_Mutex,                              /**< 互斥对象. */
#endif
#ifdef RT_USING_EVENT
    RT_Object_Info_Event,                              /**< 事件对象 */
#endif
#ifdef RT_USING_MAILBOX
    RT_Object_Info_MailBox,                            /**< 邮件对象 */
#endif
#ifdef RT_USING_MESSAGEQUEUE
    RT_Object_Info_MessageQueue,                       /**< 消息对象. */
#endif
#ifdef RT_USING_MEMHEAP
    RT_Object_Info_MemHeap,                            /**< 堆对象*/
#endif
#ifdef RT_USING_MEMPOOL
    RT_Object_Info_MemPool,                            /**< 内存池对象. */
#endif
#ifdef RT_USING_DEVICE
    RT_Object_Info_Device,                             /**< 驱动对象 */
#endif
    RT_Object_Info_Timer,                              /**< 定时器对象 */
    RT_Object_Info_Unknown,                            /**< 未知对象. */
};

// 对象监视器初始化(指针指向自己)
#define _OBJ_CONTAINER_LIST_INIT(c) \
{&(rt_object_container[c].object_list),&(rt_object_container[c].object_list)}

// 对象容器
static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
{
    /* 初始化对象容器(线程) */
    {RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},

#ifdef RT_USING_SEMAPHORE
    /* 初始化对象容器(信号) */
    {RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore)},

#endif

#ifdef RT_USING_MUTEX
    /* 初始化对象容器(互斥信号) */
    {RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT
    /* 初始化对象容器(事件) */
    {RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX
    /* 初始化对象容器(邮件)  */
    {RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MailBox), sizeof(struct rt_mailbox)},
#endif

#ifdef RT_USING_MESSAGEQUEUE
    /* 初始化对象容器(队列)  */
    {RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MessageQueue), sizeof(struct rt_messagequeue)},
#endif

#ifdef RT_USING_MEMHEAP
    /* 初始化对象容器(内存堆) */
    {RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemHeap), sizeof(struct rt_memheap)},
#endif

#ifdef RT_USING_MEMPOOL
    /* 初始化对象容器(内存池) */
    {RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemPool), sizeof(struct rt_mempool)},
#endif

#ifdef RT_USING_DEVICE
    /* 初始化对象容器(驱动) */
    {RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device)},
#endif
    /* 初始化对象容器(定时器) */
    {RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer)},
};

对象容器管理图示,容器有2个线程对象。

2.4 内核对象继承 

        线程、信号、互斥等对象的结构体,第一个成员必须是内核对象,等同于C++的public继承;如下例所示:

        

2.5 内核对象操作

/*系统对象(静态对象)初始化*/
void rt_system_object_init(void){}

 /*获取对象所在的容器(依据类型枚举)*/
struct rt_object_information *rt_object_get_information(enum rt_object_class_type type)
{
    int index;
    for (index = 0; index < RT_Object_Info_Unknown; index ++)
        if (rt_object_container[index].type == type) return &rt_object_container[index];
    return RT_NULL;
}

/*获取对象所在链表长度,既同类对象个数 (依据类型枚举)*/
int rt_object_get_length(enum rt_object_class_type type)
{
    int count = 0;
    rt_ubase_t level;
    struct rt_list_node *node = RT_NULL;
    struct rt_object_information *information = RT_NULL;
    information = rt_object_get_information((enum rt_object_class_type)type);
    if (information == RT_NULL) return 0;
	// 进入临界区
    level = rt_hw_interrupt_disable();
    /*计算有效对象个数*/
    rt_list_for_each(node, &(information->object_list))
    {
        count ++;
    }
	// 退出临界区
    rt_hw_interrupt_enable(level);
    return count;
}

 /* 复制type类型的对象指针至pointers中,最大maxlen个*/
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen)
{
    int index = 0;
    rt_ubase_t level;
    struct rt_object *object;
    struct rt_list_node *node = RT_NULL;
    struct rt_object_information *information = RT_NULL;
    if (maxlen <= 0) return 0;
	// 获取对应容器
    information = rt_object_get_information((enum rt_object_class_type)type);
    if (information == RT_NULL) return 0;
	// 进入临界区
    level = rt_hw_interrupt_disable();
    /* 检索节点,并复制对象指针*/
    rt_list_for_each(node, &(information->object_list))
    {   
        /*根据节点获取对象指针*/
        object = rt_list_entry(node, struct rt_object, list);
        pointers[index] = object;
        index ++;
        if (index >= maxlen) break;
    }
	// 退出临界区
    rt_hw_interrupt_enable(level);
    return index;
}

/*初始化静态内核对象 */
void rt_object_init(struct rt_object         *object,
                    enum rt_object_class_type type,
                    const char               *name)
{
    register rt_base_t temp;
    struct rt_list_node *node = RT_NULL;
    struct rt_object_information *information;
    /*获取对象容器*/
    information = rt_object_get_information(type);
    RT_ASSERT(information != RT_NULL);
    /* 退出线程调度*/
    rt_enter_critical();
	
    /* 检查对象,避免重复初始化*/
for(node=information->object_list.next;node!=&(information->object_list);node=node->next)
    {
        struct rt_object *obj;
        obj = rt_list_entry(node, struct rt_object, list);
        if (obj)
        {
        	/*检查是否存在重复初始化*/
            RT_ASSERT(obj != object);
        }
    }
    /* 恢复线程调度*/
    rt_exit_critical();
    /* 设置静态标识*/
    object->type = type | RT_Object_Class_Static;
    /* 设置名称 */
    rt_strncpy(object->name, name, RT_NAME_MAX);
	/* 对象新增函数调用钩子*/
    RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
    /* 进入临界区lock interrupt */
    temp = rt_hw_interrupt_disable();
    /*对象插入值链表头部*/
    rt_list_insert_after(&(information->object_list), &(object->list));
    /* 退出临界区*/
    rt_hw_interrupt_enable(temp);
}
 /*移除静态内核对象*/
void rt_object_detach(rt_object_t object)
{
    register rt_base_t temp;
    /* 断言*/
    RT_ASSERT(object != RT_NULL);
	/* 执行对象移除钩子 */
    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
    /*清除对象类型*/
    object->type = 0;
    /* 进入临界区*/
    temp = rt_hw_interrupt_disable();
    /* 从链表 移除对象*/
    rt_list_remove(&(object->list));
    /* 退出临界区 */
    rt_hw_interrupt_enable(temp);
}
 /*初始化动态内核对象(依据类型分配)*/
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{
    struct rt_object *object;
    register rt_base_t temp;
    struct rt_object_information *information;
	/*中断断言*/
    RT_DEBUG_NOT_IN_INTERRUPT;
    /* 获取对象容器*/
    information = rt_object_get_information(type);
	//断言
    RT_ASSERT(information != RT_NULL);
	/*动态内存申请*/
    object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
    if (object == RT_NULL)
    {
        /*动态内存申请失败*/
        return RT_NULL;
    }
    /* 动态内存初始化为0*/
    rt_memset(object, 0x0, information->object_size);
    /* 设置对象类型 */
    object->type = type;
    /* 清除对象标志 */
    object->flag = 0;
    /* 设置名称 */
    rt_strncpy(object->name, name, RT_NAME_MAX);
	/* 执行钩子 */
    RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
    /* 进入临界区*/
    temp = rt_hw_interrupt_disable();
    /* 插入对象至管理器链表头部*/
    rt_list_insert_after(&(information->object_list), &(object->list));
    /* 退出临界区*/
    rt_hw_interrupt_enable(temp);
    /* 返回对象指针*/
    return object;
}

/**删除并释放动态对象*/
void rt_object_delete(rt_object_t object)
{
    register rt_base_t temp;
    /* 断言 */
    RT_ASSERT(object != RT_NULL);
    RT_ASSERT(!(object->type & RT_Object_Class_Static));
    RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
    /* 清除类型 */
    object->type = RT_Object_Class_Null;
    /* 进入临界区 */
    temp = rt_hw_interrupt_disable();
    /* 从链表移除*/
    rt_list_remove(&(object->list));
    /* 退出临界区*/
    rt_hw_interrupt_enable(temp);
    /* 释放对象内存 */
    RT_KERNEL_FREE(object);
}
#endif

/**检查对象类型是否为系统类型(静态类型)*/
rt_bool_t rt_object_is_systemobject(rt_object_t object)
{
    /* 对象断言*/
    RT_ASSERT(object != RT_NULL);
    if (object->type & RT_Object_Class_Static)
        return RT_TRUE;
    return RT_FALSE;
}

/**获取对象类型*/
rt_uint8_t rt_object_get_type(rt_object_t object)
{
    /*断言*/
    RT_ASSERT(object != RT_NULL);
    return object->type & ~RT_Object_Class_Static;
}

/*查找对象(name对象名称,type对象类型,依据对象名称和类型,该函数不能在中断调用)*/
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
{
    struct rt_object *object = RT_NULL;
    struct rt_list_node *node = RT_NULL;
    struct rt_object_information *information = RT_NULL;
    /*获取对象容器*/
    information = rt_object_get_information((enum rt_object_class_type)type);
    /* 参数检查 */
    if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;
    /* which is invoke in interrupt status */
    RT_DEBUG_NOT_IN_INTERRUPT;
    /* 退出线程调度*/
    rt_enter_critical();
    /* 遍历对象节点 */
    rt_list_for_each(node, &(information->object_list))
    {
        /*获取对象*/
        object = rt_list_entry(node, struct rt_object, list);
        /*判断对象*/
        if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
        {
            /* 恢复线程调度*/
            rt_exit_critical();
            return object;
        }
    }
    /* 恢复线程调度 */
    rt_exit_critical();
    return RT_NULL;
}

2.6 内核对象钩子

        操作系统通过钩子(函数指针)给用户侧提供调试、监视或其他用途的接口,这些接口分布在对象操作的重要位置,用户侧可以根据需求选配使用。

/*****对象钩子*****/
static void (*rt_object_attach_hook)(struct rt_object *object); // 对象增加调用钩子
static void (*rt_object_detach_hook)(struct rt_object *object); // 对象移除调用钩子
void (*rt_object_trytake_hook)(struct rt_object *object);       // 对象将被占用调用钩子
void (*rt_object_take_hook)(struct rt_object *object);          // 对象已经被占用调用钩子
void (*rt_object_put_hook)(struct rt_object *object);           // 对象被释放调用钩子


 /*****对象动态增加调用钩子设置*****/
void rt_object_attach_sethook(void (*hook)(struct rt_object *object))
{
    rt_object_attach_hook = hook;
}
 /*****对象移除调用钩子设置*****/
void rt_object_detach_sethook(void (*hook)(struct rt_object *object))
{
    rt_object_detach_hook = hook;
}
 /*****对象将要占用调用钩子设置,主要应用于信号、互斥信号、事件、邮件、消息队列将要阻塞线程时*****/
void rt_object_trytake_sethook(void (*hook)(struct rt_object *object))
{
    rt_object_trytake_hook = hook;
}
 /*****对象已经占用调用钩子设置,主要应用于信号、互斥信号、事件、邮件、消息队列、定时器返回线程,检测阻塞***/
void rt_object_take_sethook(void (*hook)(struct rt_object *object))
{
    rt_object_take_hook = hook;
}
/****对象释放调用钩子设置,比如消息对象发送消息,释放线程****/
void rt_object_put_sethook(void (*hook)(struct rt_object *object))
{
    rt_object_put_hook = hook;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿来不是梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值