Created
March 30, 2022 13:26
-
-
Save Midi12/0a170824786557c82936afdc15985064 to your computer and use it in GitHub Desktop.
slist clone for drafting on wandbox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// LIFO Singly Linked List Windows API Clone for drafting and testing purpose | |
// Not taking account of memory alignment constraints of the original API | |
// | |
typedef uint16_t USHORT; | |
struct _SLIST_ENTRY { | |
struct _SLIST_ENTRY * Next; | |
}; | |
typedef struct _SLIST_ENTRY SLIST_ENTRY; | |
typedef struct _SLIST_ENTRY * PSLIST_ENTRY; | |
struct _SLIST_HEADER { | |
// This is the head | |
// | |
PSLIST_ENTRY Head; | |
// This is the number of elements | |
// | |
USHORT Depth; | |
}; | |
typedef struct _SLIST_HEADER SLIST_HEADER; | |
typedef struct _SLIST_HEADER * PSLIST_HEADER; | |
void InitializeSListHead( PSLIST_HEADER ListHead ) { | |
if ( ListHead == NULL ) | |
return; | |
ListHead->Head = NULL; | |
ListHead->Depth = 0; | |
} | |
USHORT QueryDepthSList( PSLIST_HEADER ListHead ) { | |
if ( ListHead == NULL ) | |
return 0; | |
return ListHead->Depth; | |
} | |
PSLIST_ENTRY RtlFirstEntrySList( const SLIST_HEADER * ListHead ) { | |
if ( ListHead == NULL ) | |
return 0; | |
return ListHead->Head; | |
} | |
PSLIST_ENTRY InterlockedPushEntrySList( PSLIST_HEADER ListHead, PSLIST_ENTRY ListEntry ) { | |
if ( ListHead == NULL ) | |
return NULL; | |
if ( ListEntry == NULL ) | |
return NULL; | |
ListHead->Depth++; | |
PSLIST_ENTRY first = RtlFirstEntrySList( ListHead ); | |
if ( first == NULL ) { | |
ListHead->Head = ListEntry; | |
return NULL; | |
} | |
PSLIST_ENTRY current = NULL; | |
for ( current = first; current->Next != NULL; current = current->Next ) { } | |
current->Next = ListEntry; | |
return current; | |
} | |
PSLIST_ENTRY InterlockedPopEntrySList( PSLIST_HEADER ListHead ) { | |
if ( ListHead == NULL ) | |
return NULL; | |
PSLIST_ENTRY first = RtlFirstEntrySList( ListHead ); | |
if ( first == NULL) | |
return NULL; | |
if ( first->Next == NULL ) { | |
ListHead->Head = NULL; | |
ListHead->Depth--; | |
return first; | |
} | |
PSLIST_ENTRY previous = first; | |
PSLIST_ENTRY current = NULL; | |
for ( current = first->Next; current->Next != NULL; current = current->Next ) { | |
previous = current; | |
} | |
previous->Next = NULL; | |
ListHead->Depth--; | |
return current; | |
} | |
PSLIST_ENTRY InterlockedFlushSList( PSLIST_HEADER ListHead ) { | |
if ( ListHead == NULL ) | |
return NULL; | |
PSLIST_ENTRY first = RtlFirstEntrySList( ListHead ); | |
if ( first == NULL ) { | |
return NULL; | |
} | |
InitializeSListHead( ListHead ); | |
return first; | |
} | |
struct _ITEM { | |
SLIST_ENTRY Entry; | |
int Value; | |
}; | |
typedef struct _ITEM ITEM; | |
int main() { | |
SLIST_HEADER header; | |
memset( &header, 0, sizeof( SLIST_HEADER ) ); | |
ITEM a; | |
memset( &a, 0, sizeof( ITEM ) ); | |
a.Value = 12; | |
ITEM b; | |
memset( &b, 0, sizeof( ITEM ) ); | |
b.Value = 13; | |
ITEM c; | |
memset( &c, 0, sizeof( ITEM ) ); | |
c.Value = 37; | |
printf( "Initialize list header\n" ); | |
InitializeSListHead( &header ); | |
assert( header.Head == NULL ); | |
assert( header.Depth == 0 ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "\n" ); | |
ITEM * ret = NULL; | |
printf( "Push item a\n" ); | |
ret = (ITEM *)InterlockedPushEntrySList( &header, (PSLIST_ENTRY)&a ); | |
assert( header.Head == (PSLIST_ENTRY)&a ); | |
assert( header.Depth == 1 ); | |
assert( ret == NULL ); | |
printf( "&a %p\n", &a ); | |
printf( "a.Value %d\n", a.Value ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
//printf( "ret->Value %d\n", ret->Value ); | |
printf( "\n" ); | |
printf( "Push item b\n" ); | |
ret = (ITEM *)InterlockedPushEntrySList( &header, (PSLIST_ENTRY)&b ); | |
assert( header.Head == (PSLIST_ENTRY)&a ); | |
assert( header.Depth == 2 ); | |
assert( ret == &a ); | |
printf( "&b %p\n", &b ); | |
printf( "b.Value %d\n", b.Value ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
printf( "ret->Value %d\n", ret->Value ); | |
printf( "\n" ); | |
printf( "Push item c\n" ); | |
ret = (ITEM *)InterlockedPushEntrySList( &header, (PSLIST_ENTRY)&c ); | |
assert( header.Head == (PSLIST_ENTRY)&a ); | |
assert( header.Depth == 3 ); | |
assert( ret == &b ); | |
printf( "&c %p\n", &c ); | |
printf( "c.Value %d\n", c.Value ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
printf( "ret->Value %d\n", ret->Value ); | |
printf( "\n" ); | |
printf( "Pop item c\n" ); | |
ret = (ITEM *)InterlockedPopEntrySList( &header ); | |
assert( header.Head == (PSLIST_ENTRY)&a ); | |
assert( header.Depth == 2 ); | |
assert( ret == &c ); | |
printf( "&c %p\n", &c ); | |
printf( "c.Value %d\n", c.Value ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
printf( "ret->Value %d\n", ret->Value ); | |
printf( "\n" ); | |
printf( "Pop item b\n" ); | |
ret = (ITEM *)InterlockedPopEntrySList( &header ); | |
assert( header.Head == (PSLIST_ENTRY)&a ); | |
assert( header.Depth == 1 ); | |
assert( ret == &b ); | |
printf( "&b %p\n", &b ); | |
printf( "b.Value %d\n", b.Value ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
printf( "ret->Value %d\n", ret->Value ); | |
printf( "\n" ); | |
printf( "Pop item a\n" ); | |
ret = (ITEM *)InterlockedPopEntrySList( &header ); | |
assert( header.Head == NULL ); | |
assert( header.Depth == 0 ); | |
assert( ret == &a ); | |
printf( "&a %p\n", &a ); | |
printf( "a.Value %d\n", a.Value ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
printf( "ret->Value %d\n", ret->Value ); | |
printf( "\n" ); | |
printf( "Flush list\n" ); | |
ret = (ITEM *)InterlockedFlushSList( &header ); | |
assert( header.Head == NULL ); | |
assert( header.Depth == 0 ); | |
assert( ret == NULL ); | |
printf( "header.Head %p\n", header.Head ); | |
printf( "header.Depth %d\n", header.Depth ); | |
printf( "ret %p\n", ret ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment