在实时系统中,任务之间的同步与通信需要依赖各种内核对象,如信号量、互斥锁、消息队列等。为了支持进程间共享和快速检索,Xenomai
提供了 xnregistry
,用于统一管理和访问这些内核对象。
xnregistry
是 Xenomai
内核的全局对象注册表,负责管理内核中的命名和未命名对象。它提供了一种机制,允许内核对象以唯一的标识符(如名称)注册,便于在内核和用户空间中查找和访问。
命名内核对象是指在创建时指定了名称的对象,通常用于多个进程之间的共享和通信。常见的命名内核对象包括:
以两个 Xenomai
任务通过信号量进行同步为例:
任务 1 创建一个名为 /tmp/sem1 的信号量:
/* 任务 1 */
sem_t *demo_sem;
demo_sem = sem_open("/tmp/sem1", O_CREAT | O_EXCL, 0666, 0);
if (demo_sem == SEM_FAILED)
perror("sem_open");
sem_wait(demo_sem);
/* ... */
sem_post(demo_sem);
任务 2 打开同名信号量:
/* 任务 2 */
sem_t *demo_sem;
demo_sem = sem_open("/tmp/sem1", 0);
if (demo_sem == SEM_FAILED)
perror("sem_open");
sem_wait(demo_sem);
/* ... */
sem_post(demo_sem);
当任务 1 调用 sem_open 创建信号量时,内核会进行以下操作:
xnobject
结构体:从 registry_obj_slots
中获取一个空闲的 xnobject
,用于表示信号量对象。xnobject
的属性:
/tmp/sem1
。xnobject
插入到 object_index[s]
哈希桶对应的链表中。任务 2 想要打开同名信号量时,执行以下步骤:
/tmp/sem1
进行哈希计算,得到索引值 s。object_index[s]
链表,比较每个 xnobject
的 key
。xnobject
后,获取其 objaddr
,即信号量对象的地址。在成功创建或打开信号量后,系统会生成一个 xnhandle_t
,表示对象的句柄。这个句柄通常是 xnobject
在 registry_obj_slots
数组中的偏移量。任务在后续操作(如 sem_wait
、sem_post
)中,使用这个句柄快速访问信号量对象,避免再次通过名称查找。
未命名内核对象通常用于单个进程或线程内部,不需要跨进程共享。例如:
管理机制
未命名对象在创建时:
xnobject
:同样从 registry_obj_slots
中获取一个 xnobject
。xnhandle_t
,供后续操作使用。访问方式
任务在后续对未命名对象的操作中,使用句柄 xnhandle_t
直接访问对象,而不需要通过名称查找。这种方式提高了访问速度,满足实时系统对性能的要求。
初始化步骤
在系统启动时会初始化 xnregistry
,具体步骤包括:
xnobject
,默认值为 4096。xnobject
加入到空闲链表中,供后续分配使用。object_index
数组,并初始化每个哈希桶。xnregistry
的并发访问是线程安全的。