X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_async.h;h=b3c8a0af09fecd21c28f505c7bdc4d46e05c0426;hb=HEAD;hp=366f448108221c18b0a910f1d8d66a84d31c117d;hpb=5324992ccec2857770963843fcdb6e44ce2c1a37;p=vg.git diff --git a/vg_async.h b/vg_async.h index 366f448..e0a2528 100644 --- a/vg_async.h +++ b/vg_async.h @@ -1,16 +1,15 @@ -/* Copyright (C) 2021-2023 Harry Godden (hgn) - All Rights Reserved +/* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved * * primateves that you use when you need to run something from another thread * back in the main loop of vg, at the start of each frame */ -#ifndef VG_ASYNC_H -#define VG_ASYNC_H +#pragma once +#include "vg_engine.h" -#include "vg/vg.h" +static void vg_assert_thread( enum vg_thread_purpose required ); typedef struct vg_async_item vg_async_item; - struct vg_async_item{ vg_async_item *next; @@ -20,7 +19,8 @@ struct vg_async_item{ void (*fn_runner)( void *payload, u32 size ); }; -struct vg_async{ +struct vg_async +{ void *buffer; vg_async_item *start, *end; @@ -28,111 +28,23 @@ struct vg_async{ SDL_sem *sem_wait_for_flush; SDL_SpinLock sl_index; } -static vg_async; - -/* - * Allocate an asynchronous call with a bit of memory - */ -VG_STATIC vg_async_item *vg_async_alloc( u32 size ) -{ - SDL_AtomicLock( &vg_async.sl_index ); - - u32 total_allocation = vg_align8(size) + vg_align8(sizeof(vg_async_item)), - remaining = vg_linear_remaining( vg_async.buffer ), - capacity = vg_linear_get_capacity( vg_async.buffer ); - - if( total_allocation > capacity ){ - SDL_AtomicUnlock( &vg_async.sl_index ); - vg_error( "Requested: %umb. Buffer size: %umb\n", - (total_allocation/1024)/1024, - (capacity/1024)/1024 ); - vg_fatal_exit_loop( "async alloc invalid size\n" ); - } +extern vg_async; - if( total_allocation > remaining ){ - SDL_AtomicUnlock( &vg_async.sl_index ); - SDL_SemWait( vg_async.sem_wait_for_flush ); - SDL_AtomicLock( &vg_async.sl_index ); +/* TODO: Docu */ - remaining = vg_linear_remaining( vg_async.buffer ); - capacity = vg_linear_get_capacity( vg_async.buffer ); - - assert( remaining == capacity ); - assert( vg_async.start == NULL ); - assert( vg_async.end == NULL ); - } - - void *block = vg_linear_alloc( vg_async.buffer, total_allocation ); - - vg_async_item *entry = block; - entry->next = NULL; - entry->payload = ((u8*)block) + vg_align8(sizeof(vg_async_item)); - entry->size = size; - entry->fn_runner = NULL; - - if( vg_async.end ){ - vg_async.end->next = entry; - vg_async.end = entry; - }else{ - vg_async.start = entry; - vg_async.end = entry; - } - - SDL_AtomicUnlock( &vg_async.sl_index ); - - return entry; -} +void vg_async_call( void (*runner)( void *payload, u32 size ), + void *payload, u32 size ); +void vg_run_async_checked(void); +void vg_async_init(void); +vg_async_item *vg_async_alloc( u32 size ); /* * Mark the call as being filled and ready to go */ -VG_STATIC void vg_async_dispatch( vg_async_item *item, - void (*runner)( void *payload, u32 size ) ) -{ - SDL_AtomicLock( &vg_async.sl_index ); - item->fn_runner = runner; - SDL_AtomicUnlock( &vg_async.sl_index ); -} +void vg_async_dispatch( vg_async_item *item, + void (*runner)( void *payload, u32 size ) ); /* - * Run as much of the async buffer as possible + * Wait until the current stack of async calls is completely flushed out */ -VG_STATIC void vg_run_async_checked(void) -{ - SDL_AtomicLock( &vg_async.sl_index ); - - while( vg_async.start ){ - vg_async_item *entry = vg_async.start; - - if( entry->fn_runner ){ - entry->fn_runner( entry->payload, entry->size ); - vg_async.start = entry->next; - - if( vg_async.start == NULL ){ - vg_async.end = NULL; - - vg_linear_clear( vg_async.buffer ); - - if( !SDL_SemValue( vg_async.sem_wait_for_flush ) ){ - SDL_SemPost( vg_async.sem_wait_for_flush ); - } - } - } - else{ - break; - } - - /* TODO: if exceed max frametime.... */ - } - - SDL_AtomicUnlock( &vg_async.sl_index ); -} - -VG_STATIC void vg_async_init(void) -{ - vg_async.sem_wait_for_flush = SDL_CreateSemaphore(0); - vg_async.buffer = vg_create_linear_allocator( NULL, 50*1024*1024, - VG_MEMORY_REALTIME ); -} - -#endif /* VG_ASYNC_H */ +void vg_async_stall(void);