本文主要是介绍SylixOS里的资源调度操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概述
SylixOS里有许多动态资源,这些系统资源如下:
名称 | 类型 |
---|---|
Tcb | 线程控制块 |
Event | 事件 |
EventSet | 事件集 |
ThreadVar | 线程私有数据 |
Heap | 堆 |
MsgQueue | 消息队列 |
Timer | 软件定时器 |
Partition | 定长分区内存管理 |
Rms | 精度单调调度器 |
这些资源的调度,即资源的分配及回收操作,是通过单向资源分配表来实现的,为O(1)时间复杂度,这样就保证了资源分配或回收操作的实时性。
这些操作位于libsylixos\SylixOS\kernel\list文件夹中,单向资源分配表的实现和用法见《SylixOS里的单向资源分配表实现》
接口
这些资源和接口如下:
/*********************************************************************************************************THREAD ID RESOURCE
*********************************************************************************************************/
PLW_CLASS_TCB _Allocate_Tcb_Object(VOID);
VOID _Free_Tcb_Object(PLW_CLASS_TCB ptcbFree);
/*********************************************************************************************************EVENT RESOURCE (Semaphore & MsgQueue)
*********************************************************************************************************/
PLW_CLASS_EVENT _Allocate_Event_Object(VOID);
VOID _Free_Event_Object(PLW_CLASS_EVENT pevent);
/*********************************************************************************************************THREAD PRIVATE VAR RESOURCE
*********************************************************************************************************/
PLW_CLASS_THREADVAR _Allocate_ThreadVar_Object(VOID);
VOID _Free_ThreadVar_Object(PLW_CLASS_THREADVAR pthreadvarFree);
/*********************************************************************************************************EVENT SET RESOURCE
*********************************************************************************************************/
PLW_CLASS_EVENTSET _Allocate_EventSet_Object(VOID);
VOID _Free_EventSet_Object(PLW_CLASS_EVENTSET pesFree);
/*********************************************************************************************************HEAP RESOURCE
*********************************************************************************************************/
PLW_CLASS_HEAP _Allocate_Heap_Object(VOID);
VOID _Free_Heap_Object(PLW_CLASS_HEAP pheapFree);
/*********************************************************************************************************MESSAGE QUEUE RESOURCE
*********************************************************************************************************/
PLW_CLASS_MSGQUEUE _Allocate_MsgQueue_Object(VOID);
VOID _Free_MsgQueue_Object(PLW_CLASS_MSGQUEUE pmsgqueueFree);
/*********************************************************************************************************TIMER RESOURCE
*********************************************************************************************************/
PLW_CLASS_TIMER _Allocate_Timer_Object(VOID);
VOID _Free_Timer_Object(PLW_CLASS_TIMER ptmrFree);
/*********************************************************************************************************PARTITION RESOURCE
*********************************************************************************************************/
PLW_CLASS_PARTITION _Allocate_Partition_Object(VOID);
VOID _Free_Partition_Object(PLW_CLASS_PARTITION p_partFree);
/*********************************************************************************************************RMS RESOURCE
*********************************************************************************************************/
PLW_CLASS_RMS _Allocate_Rms_Object(VOID);
VOID _Free_Rms_Object(PLW_CLASS_RMS prmsFree);
实现
这些系统资源调度的接口和实现都是类似的,都需要定义一个资源管理对象,资源类型。其中资源管理对象一定包含表头表尾指针和一些统计计数,资源类型则一定要包含一个节点对象。下面以事件资源为例讲解调度操作。
- 资源管理对象类型定义
必须包含单向资源分配表的表头指针和表尾指针,并且增加了当前使用计数和最大使用计数。
/*********************************************************************************************************系统对象资源结构
*********************************************************************************************************/typedef struct {LW_LIST_MONO_HEADER RESRC_pmonoFreeHeader; /* 空闲链表头 */LW_LIST_MONO_HEADER RESRC_pmonoFreeTail; /* 空闲链表尾 */UINT RESRC_uiUsed; /* 当前使用量 */UINT RESRC_uiMaxUsed; /* 最大使用量 */
} LW_CLASS_OBJECT_RESRC;
- 事件对象类型定义
必须有一项为单向资源分配表节点,其他成员则是事件对象特有的。如果单向资源分配表节点成员为第一项则可以强转为单向资源分配表节点使用;不是第一项的话,则通过宏_LIST_ENTRY
也可以进行对象转换,SylixOS用的是第二种方法。
/*********************************************************************************************************事件控制块 (可用于计数及二进制信号量、互斥信号量量、消息队列、PART内存池)
*********************************************************************************************************/typedef struct {LW_LIST_MONO EVENT_monoResrcList; /* 空闲资源表 */UINT8 EVENT_ucType; /* 事件类型 */PVOID EVENT_pvTcbOwn; /* 占有资源的TCB指针 */ /* 可以在加入死锁检测机制 */ULONG EVENT_ulCounter; /* 计数器值 */ULONG EVENT_ulMaxCounter; /* 最大技术值 */INT EVENT_iStatus;ULONG EVENT_ulOption; /* 事件选项 */UINT8 EVENT_ucCeilingPriority; /* 天花板优先级 */PVOID EVENT_pvPtr; /* 多用途指针 */LW_CLASS_WAITQUEUE EVENT_wqWaitQ[2]; /* 双等待队列 */UINT16 EVENT_usIndex; /* 缓冲区中的下标 */CHAR EVENT_cEventName[LW_CFG_OBJECT_NAME_SIZE]; /* 事件名 */
} LW_CLASS_EVENT;
typedef LW_CLASS_EVENT *PLW_CLASS_EVENT;
- 资源初始化
将静态分配的资源数组初始化为空闲单链表。同时初始化资源块的其他成员。
/*********************************************************************************************************
** 函数名称: _EventInit
** 功能描述: 初始化事件缓冲池
** 输 入 :
** 输 出 :
*********************************************************************************************************/
VOID _EventInit (VOID)
{
#if (LW_CFG_EVENT_EN > 0) && (LW_CFG_MAX_EVENTS > 0)REGISTER ULONG ulI;REGISTER PLW_CLASS_EVENT peventTemp1;REGISTER PLW_LIST_MONO pmonoTemp1;#if LW_CFG_MAX_EVENTS == 1_K_resrcEvent.RESRC_pmonoFreeHeader = &_K_eventBuffer[0].EVENT_monoResrcList;/* 设置资源表头 */peventTemp1 = &_K_eventBuffer[0]; /* 指向缓冲池首地址 */pmonoTemp1 = &peventTemp1->EVENT_monoResrcList; /* 获得资源表 */peventTemp1->EVENT_ucType = LW_TYPE_EVENT_UNUSED; /* 事件类型 */peventTemp1->EVENT_usIndex = 0; /* 事件缓冲区下标 */_INIT_LIST_MONO_HEAD(pmonoTemp1); /* 初始化最后节点 */_K_resrcEvent.RESRC_pmonoFreeTail = pmonoTemp1;#elseREGISTER PLW_CLASS_EVENT peventTemp2;REGISTER PLW_LIST_MONO pmonoTemp2;_K_resrcEvent.RESRC_pmonoFreeHeader = &_K_eventBuffer[0].EVENT_monoResrcList;/* 设置资源表头 */peventTemp1 = &_K_eventBuffer[0]; /* 指向缓冲池首地址 */peventTemp2 = &_K_eventBuffer[1]; /* 指向缓冲池首地址 */for (ulI = 0; ulI < ((LW_CFG_MAX_EVENTS) - 1); ulI++) {pmonoTemp1 = &peventTemp1->EVENT_monoResrcList; /* 获得资源表 */pmonoTemp2 = &peventTemp2->EVENT_monoResrcList; /* 获得资源表 */peventTemp1->EVENT_ucType = LW_TYPE_EVENT_UNUSED; /* 事件类型 */peventTemp1->EVENT_usIndex = (UINT16)ulI; /* 事件缓冲区下标 */_LIST_MONO_LINK(pmonoTemp1, pmonoTemp2); /* 建立资源连接 */peventTemp1++;peventTemp2++;}/* 初始化最后一个节点 */pmonoTemp1 = &peventTemp1->EVENT_monoResrcList; /* 获得资源表 */peventTemp1->EVENT_ucType = LW_TYPE_EVENT_UNUSED; /* 事件类型 */peventTemp1->EVENT_usIndex = (UINT16)ulI; /* 事件缓冲区下标 */_INIT_LIST_MONO_HEAD(pmonoTemp1); /* 初始化最后节点 */_K_resrcEvent.RESRC_pmonoFreeTail = pmonoTemp1;
#endif /* LW_CFG_MAX_EVENTS == 1 */_K_resrcEvent.RESRC_uiUsed = 0;_K_resrcEvent.RESRC_uiMaxUsed = 0;#endif /* (LW_CFG_EVENT_EN > 0) *//* (LW_CFG_MAX_EVENTS > 0) */
}
- 资源分配
从空闲单链表头部拆下一个资源块。后面就可以对该资源块进行操作了,开启 了它的生命周期。
/*********************************************************************************************************
** 函数名称: _Allocate_Event_Object
** 功能描述: 从空闲Event控件池中取出一个空闲Event
** 输 入 :
** 输 出 : 获得的Object地址,失败返回 NULL
*********************************************************************************************************/
PLW_CLASS_EVENT _Allocate_Event_Object (VOID)
{REGISTER PLW_LIST_MONO pmonoFree;REGISTER PLW_CLASS_EVENT peventFree;if (_LIST_MONO_IS_EMPTY(_K_resrcEvent.RESRC_pmonoFreeHeader)) { /* 检查缓冲区是否为空 */return (LW_NULL);}pmonoFree = _list_mono_allocate_seq(&_K_resrcEvent.RESRC_pmonoFreeHeader, &_K_resrcEvent.RESRC_pmonoFreeTail);/* 获得资源 */peventFree = _LIST_ENTRY(pmonoFree, LW_CLASS_EVENT, EVENT_monoResrcList); /* 获得资源表容器地址 */_K_resrcEvent.RESRC_uiUsed++;if (_K_resrcEvent.RESRC_uiUsed > _K_resrcEvent.RESRC_uiMaxUsed) {_K_resrcEvent.RESRC_uiMaxUsed = _K_resrcEvent.RESRC_uiUsed;}return (peventFree);
}
- 资源回收
资源块使用完毕后需要回收,即将一个资源块插入空闲链表头部,这样就可以等待被再次使用了。
/*********************************************************************************************************
** 函数名称: _Free_Event_Object
** 功能描述: 将Event控制块交还缓冲池
** 输 入 :
** 输 出 :
*********************************************************************************************************/
VOID _Free_Event_Object (PLW_CLASS_EVENT pevent)
{REGISTER PLW_LIST_MONO pmonoFree;pmonoFree = &pevent->EVENT_monoResrcList;_list_mono_free_seq(&_K_resrcEvent.RESRC_pmonoFreeHeader, &_K_resrcEvent.RESRC_pmonoFreeTail, pmonoFree);_K_resrcEvent.RESRC_uiUsed--;
}
这篇关于SylixOS里的资源调度操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!