RT-Thread源码阅读(3)——内核对象管理

_object_container对象容器数组

在RT-Thread操作系统中,_object_container数组的作用是按类型分类管理内核对象,提供高效的类型检查、资源管理和统计功能

struct rt_list_node
{struct rt_list_node *next;                          /**< point to next node. */struct rt_list_node *prev;                          /**< point to prev node. */
};
typedef struct rt_list_node rt_list_t;                  /**< Type for lists. */struct rt_object_information
{enum rt_object_class_type type;                     /**< object class type */rt_list_t                 object_list;              /**< object list */rt_size_t                 object_size;              /**< object size */
};#define _OBJ_CONTAINER_LIST_INIT(c)     \{&(_object_container[c].object_list), &(_object_container[c].object_list)}static struct rt_object_information _object_container[RT_Object_Info_Unknown] =
{/* initialize object container - thread */{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},/* initialize object container - semaphore */{RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore)},// ......
}

从源码可以看出,_object_container包含了所有对象,如threadsem

_OBJ_CONTAINER_LIST_INIT可能比较难理解,里面有两个一模一样的&(_object_container[c].object_list),乍一看rt_object_information结构体也才3个元素,这里宏展开后一共都有4个元素了?

其实不然,_OBJ_CONTAINER_LIST_INIT用了花括号,只代表一个元素rt_list_t object_list,花括号里的值代表着nextprev

至于为什么是两个一模一样的值,看过rt_list_init函数就理解了,这也和这个宏的名字对上了,即初始化

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



rt_object_allocate(用于动态创建对象)

rt_object_allocate为新创建的对象申请句柄内存,并将其加入到链表中

以下是动态创建线程的接口代码:

rt_thread_t rt_thread_create(const char *name, void (*entry)(void *parameter), void *parameter, rt_uint32_t stack_size,rt_uint8_t priority, rt_uint32_t tick)
{struct rt_thread *thread;void *stack_start;thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread, name);stack_start = (void *)RT_KERNEL_MALLOC(stack_size);_thread_init(thread, name, entry, parameter, stack_start, stack_size, priority, tick);return thread;
}rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{struct rt_object *object;rt_base_t level;struct rt_object_information *information;// 获取对应类型对象管理结构体information = rt_object_get_information(type);// 为句柄申请空间object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);rt_memset(object, 0x0, information->object_size);object->type = type;object->flag = 0;rt_strncpy(object->name, name, RT_NAME_MAX);// 将新创建的链表加入到对象管理结构体的链表中rt_list_insert_after(&(information->object_list), &(object->list));return object;
}



list_find_init(用于遍历对象)

在FinSH命令行插件中,有查看对象状态的功能,如list_thread

其示意代码如下:

typedef struct
{rt_list_t *list;rt_list_t **array;rt_uint8_t type;int nr;     // 最大个数int nr_out; // 实际个数
} list_get_next_t;static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
{struct rt_object_information *info;rt_list_t *list;// 返回对应的对象管理结构体info = rt_object_get_information((enum rt_object_class_type)type);// 找到最关键的链表list = &info->object_list;p->list = list;p->type = type;p->array = array;p->nr = nr;p->nr_out = 0;
}long list_thread(void)
{list_get_next_t find_arg;rt_list_t *obj_list[LIST_FIND_OBJ_NR];rt_list_t *next = (rt_list_t *)RT_NULL;list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));do{// 这里给obj_list数组赋值,里面存着每个对象的链表// 这里一次最多获取LIST_FIND_OBJ_NR个对象next = list_get_next(next, &find_arg);{int i;// 循环打印对象信息for (i = 0; i < find_arg.nr_out; i++){struct rt_object *obj;struct rt_thread *thread;// 通过结构体中的元素找到结构体本身,第一章中有详细讲解rt_list_entryobj = rt_list_entry(obj_list[i], struct rt_object, list);thread = (struct rt_thread *)obj;// 打印相关信息}}} while (next != (rt_list_t *)RT_NULL);return 0;
}



rt_object 结构体

基础的结构体,所有内核对象结构体的开头都会定义struct rt_object parent;

但是不知道为什么rt_thread结构体开头把rt_object 展开了,但是效果和offset都是一致的

/*** Base structure of Kernel object*/
struct rt_object
{char       name[RT_NAME_MAX];                       /**< name of kernel object */rt_uint8_t type;                                    /**< type of kernel object */rt_uint8_t flag;                                    /**< flag of kernel object */rt_list_t  list;                                    /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t;                  /**< Type for kernel objects. */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《智能医学》征稿通知:7天可见刊,专科及以上可发表

香港科学出版社(Hong Kong Scientific Publishers Journals)是一家全球独立高质量的学术出版机构&#xff0c;遵循国际开放获取的出版(OA)原则。现已与科检易学术携手共同征集高质量文章。目前可出版来自高等学校、科研院所和企业的先进科技成果。包括理、工、农、医、经、管、…

如何利用categraf的exec插件实现对Linux主机系统用户及密码有效期进行监控及告警?

需求描述 Categraf作为夜莺监控平台的数据采集工具&#xff0c;为了保障Linux主机的安全&#xff0c;需要实现对系统用户密码有效期的监控&#xff0c;并在密码即将到期时及时告警&#xff0c;以提醒运维人员更改密码。本章将详细介绍如何利用Categraf的exec插件来实现这一功能…

RV1126-OPENCV 交叉编译

一.下载opencv-3.4.16.zip到自己想装的目录下 二.解压并且打开 opencv 目录 先用 unzip opencv-3.4.16.zip 来解压 opencv 的压缩包&#xff0c;并且进入 opencv 目录(cd opencv-3.4.16) 三. 修改 opencv 的 cmake 脚本的内容 先 cd platforms/linux 然后修改 arm-gnueabi.to…

如何加载私钥为 SecKeyRef

本文介绍如何在 iOS/macOS 下将私钥加载为 SecKeyRef&#xff0c;涵盖 PEM 格式的 ECC 密钥读取、X9.63 数据构建、以及与 Keychain 的集成。 1. 使用 SecKeyCreateWithData 加载私钥 Apple 提供的 SecKeyCreateWithData 方法可以直接将密钥数据加载为 SecKeyRef 对象。 SecK…

Missashe考研日记—Day44-Day50

Missashe考研日记—Day44-Day50 写在面前 本系列博客用于记录博主一周的学习进度&#xff0c;具体知识总结在目前已有的笔记中&#xff1a;1.高数强化学习笔记2.计网复习笔记3.新增&#xff1a;线代题型总结 专业课408 这周先是把计网第三章数据链路层剩下的局域网以及之后…

Windows下安装并使用kubectl查看K8S日志

【1】安装kubectl 官网文档&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后得到 kubectl.exe&#xff0c;放到一个目录下&#xff0c;然后配置环境变量。 此时CMD 进入DOS命令窗口 kubectl version【2】配置config文件 其实就是…

攻防世界János-the-Ripper

打开压缩包是一个文件&#xff0c;用010Editor打开可以发现里面有隐藏文件flag.txt 此时想到分离文件&#xff0c;利用binwalk工具 利用binwalk生成出的是一个压缩包&#xff0c;解压缩但是发现竟然解压需要密码 这里就可以开始暴力破解密码了&#xff0c;这里我用的是ARCHPR工…

XPlifeapp:高效打印,便捷生活

在数字化时代&#xff0c;虽然电子设备的使用越来越普遍&#xff0c;但打印的需求依然存在。无论是学生需要打印课表、资料&#xff0c;还是职场人士需要打印名片、报告&#xff0c;一个高效便捷的打印软件都能大大提高工作效率。XPlifeapp就是这样一款超级好用的手机打印软件&…

【计算机网络】第2章:应用层—Web and HTTP

目录 一、Web 与 HTTP 二、总结 &#xff08;一&#xff09;Web 的定义与功能 &#xff08;二&#xff09;HTTP 协议的定义与功能 &#xff08;三&#xff09;HTTP 协议的核心机制 1. HTTP 请求与响应流程 2. HTTP 的连接类型 3. HTTP 的状态码 &#xff08;四&#xf…

如何实现 LRU 缓存:基于LinkedHashMap?

全文目录&#xff1a; 开篇语前言1. LinkedHashMap 简介1.1 LinkedHashMap 的构造方法 2. 基于 LinkedHashMap 实现 LRU 缓存2.1 设计思路2.2 实现步骤2.3 代码说明2.4 测试案例2.5 解释 3. LRU 缓存优化3.1 removeEldestEntry() 方法的灵活性3.2 内存管理 4. 总结文末 开篇语 …

Spring Boot测试框架全面解析

Spring Boot测试框架基础 Spring Boot通过增强Spring测试框架的能力,为开发者提供了一系列简化测试流程的新注解和特性。该框架建立在成熟的Spring测试基础之上,通过自动化配置和专用注解显著提升了测试效率。 核心依赖配置 要使用Spring Boot的全部测试功能,只需在项目中…

Spring Boot 整合 Spring Data JPA、strategy 的策略区别、什么是 Spring Data JPA

DAY29.2 Java核心基础 Spring Boot 整合 Spring Data JPA Spring Data JPA根据具体的数据库分为不同的子模块&#xff0c;无论是关系型数据库和非关系型数据库&#xff0c;Spring Data都提供了支持 Mysql&#xff1a;Spring Data JPA Redis&#xff1a;Spring Data Redis …

Ubuntu 服务器配置与 Cloudflare Tunnel 部署指南 免费内网穿透家用服务器

Ubuntu 服务器配置与 Cloudflare Tunnel 部署指南 本文档总结了服务器配置相关内容&#xff0c;包括 Ubuntu 服务器配置、硬盘扩容、静态 IP 设置以及 Cloudflare Tunnel 的部署步骤。 目录 硬盘分区与扩容设置静态 IPCloudflare Tunnel 部署SSH 通过 Cloudflare Tunnel常见…

降低实验检测报告编制耗时 质检LIMS系统的应用策略

在质检工作流程中&#xff0c;检测报告编制往往是耗时耗力的关键环节。传统人工编制报告不仅效率低下&#xff0c;还容易出现数据错误、格式不统一等问题。质检 LIMS 系统凭借其强大的自动化、智能化功能&#xff0c;为检测报告编制带来革命性变革&#xff0c;能够将编制时间减…

同为.net/C#的跨平台运行时的mono和.net Core有什么区别?

Mono 和 .NET Core&#xff08;现已统一为 .NET&#xff09;都是 .NET 生态的跨平台实现&#xff0c;但它们在设计目标、技术特性和应用场景上有显著区别。以下是详细对比&#xff1a; ​​1. 历史背景​​ ​​项目​​​​诞生时间​​​​开发者​​​​当前状态​​​​Mo…

Android AIDL Hal最低保证出现的问题

1. AIDL HAL 的“最低保证”特性 &#xff08;1&#xff09;协议层级的强制支持 在 IComposer AIDL 接口定义中&#xff08;如 android.hardware.graphics.composer3&#xff09;&#xff0c;Google 已经将部分功能列为 必须支持的特性&#xff08;MUST&#xff09;。例如&am…

苹果FINDMY和谷歌FIND HUB增强共享位置功能

近期&#xff0c;苹果Findmy增强了追踪和分享丢失物品位置方面的功能&#xff0c;“共享物品位置”&#xff0c;用户可以安全地与航空a公司等第三方分享丢失物品的位置&#xff0c;以便于行李找回。 iOS 18.2的这一新功能使用户可以轻松、安全地与航空公司等第三方分享AirTag或…

基于GA遗传优化的FIR滤波器幅频相频均衡补偿算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 在数字信号处理领域&#xff0c;有限冲激响应&#xff08;FIR&#xff09;滤波器因其结构简单、稳定性好且易于实现线性相位等优点被广泛应用。然而&#xff0c;实…

双路物理CPU机器上安装Ubuntu并部署KVM以实现系统多开

在双路物理CPU机器上安装Ubuntu并部署KVM以实现系统多开&#xff0c;并追求性能最优&#xff0c;需要从硬件、宿主机系统、KVM配置、虚拟机配置等多个层面进行优化。 以下是详细的操作指南和优化建议&#xff1a; 阶段一&#xff1a;BIOS/UEFI 设置优化 (重启进入) 启用虚拟化…

adb查看、设置cpu相关信息

查内存 adb shell dumpsys meminfo查CPU top -m 10打开 system_monitor adb shell am start -n eu.chainfire.perfmon/.LaunchActivity设置CPU的核心数 在/sys/devices/system/cpu目录下可以看到你的CPU有几个核心&#xff0c;如果是双核&#xff0c;就是cpu0和cpu1&#xff0c…