前言
- 20201010
- 在阅读 RTOS LiteOS 内核源码时发现该内核使用的链表时通用链表,而 FreeRTOS 内核使用的时非通用链表,所以,有必要发布一下关于链表实现的笔记。
- 以下内容为个人笔记,涉及一些非专业词汇,敬请谅解,谢谢。
链接
参考
头文件 lssList.h
#ifndef _LSS_LIST_H_
#define _LSS_LIST_H_
#include "LssAppConfig.h"
#define lssLIST_MAX_VALUE 0XFFFFFFFF
#define lssLIST_BASE_TYPE unsigned long
struct LIST_ITEM_LSS_T
{
uint32_t xItemValue;
struct LIST_ITEM_LSS_T * pxNext;
struct LIST_ITEM_LSS_T * pxPrevious;
void * pvOwner;
void * pvContainer;
};
typedef struct LIST_ITEM_LSS_T listItem_t;
struct LIST_MINI_ITEM_LSS_T
{
uint32_t xItemValue;
struct LIST_ITEM_LSS_T * pxNext;
struct LIST_ITEM_LSS_T * pxPrevious;
};
typedef struct LIST_MINI_ITEM_LSS_T listMiniItem_t;
struct LIST_LSS_T
{
uint32_t uxNumberOfItems;
struct LIST_ITEM_LSS_T * pxIndex;
struct LIST_MINI_ITEM_LSS_T xListEnd;
};
typedef struct LIST_LSS_T list_t;
void listInit(list_t * const list);
void listItemInit(listItem_t * const item);
void listInsertEnd( list_t * const pxList, listItem_t * const pxNewListItem );
void listInsert( list_t * const pxList, listItem_t * const pxNewListItem );
uint32_t listRemove( listItem_t * const pxItemToRemove );
#define lssSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) \
( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
#define lssGET_LIST_ITEM_OWNER( pxListItem ) \
( ( pxListItem )->pvOwner )
#define lssSET_LIST_ITEM_VALUE( pxListItem, xValue ) \
( ( pxListItem )->xItemValue = ( xValue ) )
#define lssGET_LIST_ITEM_VALUE( pxListItem ) \
( ( pxListItem )->xItemValue )
#define lssGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) \
( ( ( pxList )->xListEnd ).pxNext->xItemValue )
#define lssGET_HEAD_ENTRY( pxList ) \
( ( ( pxList )->xListEnd ).pxNext )
#define lssGET_NEXT( pxListItem ) \
( ( pxListItem )->pxNext )
#define lssGET_END_MARKER( pxList ) \
( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
#define lssLIST_IS_EMPTY( pxList ) \
( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) )
#define lssCURRENT_LIST_LENGTH( pxList ) \
( ( pxList )->uxNumberOfItems )
#define lssGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
{ \
list_t * const pxConstList = ( pxList ); \ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
{ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;\
} \
}
#endif
源文件 lssList.c
#include "lssList.h"
void listInit(list_t * const list)
{
list->pxIndex = (listItem_t *) &(list->xListEnd);
list->xListEnd.xItemValue = lssLIST_MAX_VALUE;
list->xListEnd.pxNext = ( listItem_t * ) &( list->xListEnd );
list->xListEnd.pxPrevious = ( listItem_t * ) &( list->xListEnd );
list->uxNumberOfItems = (lssLIST_BASE_TYPE)0U;
}
void listItemInit(listItem_t * const item)
{
item->pvContainer = NULL;
}
void listInsertEnd( list_t * const pxList, listItem_t * const pxNewListItem )
{
listItem_t * const pxIndex = pxList->pxIndex;
pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem;
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
void listInsert( list_t * const pxList, listItem_t * const pxNewListItem )
{
listItem_t *pxIterator;
const lssLIST_BASE_TYPE xValueOfInsertion = pxNewListItem->xItemValue;
if( xValueOfInsertion == lssLIST_MAX_VALUE )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
for( pxIterator = ( listItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
uint32_t listRemove( listItem_t * const pxItemToRemove )
{
list_t * const pxList = ( list_t * ) pxItemToRemove->pvContainer;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
pxItemToRemove->pvContainer = NULL;
( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems;
}
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现