Skip to content

Instantly share code, notes, and snippets.

@Midi12
Created March 30, 2022 13:26
Show Gist options
  • Save Midi12/0a170824786557c82936afdc15985064 to your computer and use it in GitHub Desktop.
Save Midi12/0a170824786557c82936afdc15985064 to your computer and use it in GitHub Desktop.
slist clone for drafting on wandbox
#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