exectos/xtoskrnl/rtl/plist.c
Rafal Kupiec 01d127f49e
All checks were successful
Builds / ExectOS (amd64) (push) Successful in 57s
Builds / ExectOS (i686) (push) Successful in 55s
Consider not initialized list as empty, what prevents page faults
2024-05-14 15:53:21 +02:00

176 lines
4.0 KiB
C

/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/plist.c
* DESCRIPTION: Linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* This routine initializes a structure representing the head of a double-linked list.
*
* @param ListHead
* Pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RtlInitializeListHead(IN PLIST_ENTRY ListHead)
{
ListHead->Blink = ListHead;
ListHead->Flink = ListHead;
}
/**
* This routine initializes a structure representing the head of a 32bit double-linked list.
*
* @param ListHead
* Pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RtlInitializeListHead32(IN PLIST_ENTRY32 ListHead)
{
ListHead->Blink = PtrToUlong(ListHead);
ListHead->Flink = PtrToUlong(ListHead);
}
/**
* This routine inserts an entry at the head of a doubly linked list.
*
* @param ListHead
* Pointer to the head of the list.
*
* @param Entry
* Pointer to the entry that will be inserted in the list.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
Entry->Flink = ListHead->Flink;
Entry->Blink = ListHead;
ListHead->Flink->Blink = Entry;
ListHead->Flink = Entry;
}
/**
* This routine inserts an entry at the tail of a doubly linked list.
*
* @param ListHead
* Pointer to the head of the list.
*
* @param Entry
* Pointer to the entry that will be inserted in the list.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RtlInsertTailList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
Entry->Flink = ListHead;
Entry->Blink = ListHead->Blink;
ListHead->Blink->Flink = Entry;
ListHead->Blink = Entry;
}
/**
* Indicates whether a doubly linked list structure is empty, or not initialized at all.
*
* @param ListHead
* Pointer to a structure that represents the head of the list.
*
* @return TRUE if there are currently no entries in the list or FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
RtlListEmpty(IN PLIST_ENTRY ListHead)
{
return (((ListHead->Flink == NULL) && (ListHead->Blink == NULL)) || (ListHead->Flink == ListHead));
}
/**
* This routine detects a loop in a doubly linked list.
*
* @param ListHead
* Pointer to a structure that represents the head of the list.
*
* @return TRUE if linked list contains a loop or FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
RtlListLoop(IN PLIST_ENTRY ListHead)
{
PLIST_ENTRY SlowEntry, FastEntry;
/* Check if list exists */
if(ListHead == NULL)
{
/* No loop in non-existen list */
return FALSE;
}
/* Make both references pointing to the start of the list */
FastEntry = ListHead;
SlowEntry = ListHead;
/* Iterate through the linked list to find a loop */
while(SlowEntry != NULL && FastEntry != NULL && FastEntry->Flink != NULL)
{
/* Move slow and fast pointers by one and two positions accordingly */
SlowEntry = SlowEntry->Flink;
FastEntry = FastEntry->Flink->Flink;
/* Compare both pointers */
if(SlowEntry == FastEntry)
{
/* Loop found */
return TRUE;
}
}
/* No loop found */
return FALSE;
}
/**
* This routine removes an entry from a doubly linked list.
*
* @param Entry
* Pointer to the entry that will be removed from the list.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RtlRemoveEntryList(IN PLIST_ENTRY Entry)
{
Entry->Flink->Blink = Entry->Blink;
Entry->Blink->Flink = Entry->Flink;
}