zoukankan      html  css  js  c++  java
  • rt_container_of 已知一个结构体里面的成员的地址,反推出该结构体的首地址

    /**
     * rt_container_of - return the member address of ptr, if the type of ptr is the
     * struct type.
     */
    #define rt_container_of(ptr, type, member) 
        ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
    
    /**
     * @brief get the struct for this entry
     * @param node the entry point                  表示一个节点的地址
     * @param type the type of structure            该节点所在的结构体的类型
     * @param member the name of list in structure  该节点在该结构体中的成员名称
     */
    #define rt_list_entry(node, type, member) 
        rt_container_of(node, type, member)

    具体实现算法:

    我们知道了一个节点 tlist 的地址 ptr,现在要推算出该节点所在的 type 类型的结构体的起始地址 f_struct_ptr。我们可以将 ptr的值减去图中灰色部分的偏移的大小就可以得到 f_struct_ptr 的地址,现在的关键是如何计算出灰色部分的偏移大小。这里采取的做法是将 0 地址强制类型类型转换为 type,即(type *)0,然后通过指针访问结构体成员的方式获取到偏移的大小,即(&((type *)0)->member),最后即可算出 f_struct_ptr = ptr -(&((type *)0)->member)。


    这个偏移的计算和<stddef.h>中的宏offsetof(s,m)一样

    用法举例:

    /* 启动系统调度器 */
    void rt_system_scheduler_start(void)
    {
      register struct rt_thread *to_thread;
    
      /* 手动指定第一个运行的线程 */ (1)
      to_thread = rt_list_entry(rt_thread_priority_table[0].next,struct rt_thread,tlist);
       rt_current_thread = to_thread; (2)//将获取到的第一个要运行的线程控制块指针传到全局变量rt_current_thread 中
      /* 切换到第一个线程,该函数在 context_rvds.S 中实现,
         在 rthw.h 声明,用于实现第一次线程切换。
         当一个汇编函数在 C 文件中调用的时候,如果有形参,
         则执行的时候会将形参传人到 CPU 寄存器 r0。*/
      rt_hw_context_switch_to((rt_uint32_t)&to_thread->sp); (3)
    }

    这里只关心rt_list_entry的用法,rt_thread的结构体定义如下(简化了的)。要获取一个rt_thread,则根据链表通过rt_list_entry获得对应的线程。

     struct rt_thread
     {
     void *sp; /* 线程栈指针 */
     void *entry; /* 线程入口地址 */
     void *parameter; /* 线程形参 */
     void *stack_addr; /* 线程栈起始地址 */
     rt_uint32_t stack_size; /* 线程栈大小,单位为字节 */
    
     rt_list_t tlist; /* 线程链表节点 */ (1)
     };
    
    
    
  • 相关阅读:
    [React] Cleaning up Functional Components with Custom Hooks
    [React] useCallback + useMemo to avoid re-render
    [React] Replacing Instance Variables with the useRef Hook
    [Cloud Architect] 4. Introduction to Design for Cost, Performance, & Scalability
    [Cloud Architect] 3. Monitor, React, and Recover
    [Cloud Architect] 3. Business Objectives
    1314:【例3.6】过河卒(Noip2002)
    1313:【例3.5】位数问题
    rk3568 linux sdk Buildroot 开发
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/Rainingday/p/13802374.html
Copyright © 2011-2022 走看看