switch to async system
[vg.git] / vg_async.h
index 366f448108221c18b0a910f1d8d66a84d31c117d..190b5a8271552ae1dae6ff71646a45febca94b82 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef VG_ASYNC_H
 #define VG_ASYNC_H
 
+#define VG_GAME
 #include "vg/vg.h"
 
 typedef struct vg_async_item vg_async_item;
@@ -30,11 +31,21 @@ struct vg_async{
 }
 static vg_async;
 
+VG_STATIC enum vg_thread_purpose vg_thread_purpose(void);
+VG_STATIC enum engine_status _vg_engine_status(void);
+
 /*
  * Allocate an asynchronous call with a bit of memory
  */
 VG_STATIC vg_async_item *vg_async_alloc( u32 size )
 {
+   /* ditch out here if engine crashed. this serves as the 'quit checking' */
+
+   if( _vg_engine_status() == k_engine_status_crashed ){
+      assert( vg_thread_purpose() == k_thread_purpose_loader );
+      longjmp( vg.env_loader_exit, 1 );
+   }
+
    SDL_AtomicLock( &vg_async.sl_index );
 
    u32 total_allocation = vg_align8(size) + vg_align8(sizeof(vg_async_item)),
@@ -46,7 +57,8 @@ VG_STATIC vg_async_item *vg_async_alloc( u32 size )
       vg_error( "Requested: %umb. Buffer size: %umb\n",
                   (total_allocation/1024)/1024,
                   (capacity/1024)/1024 );
-      vg_fatal_exit_loop( "async alloc invalid size\n" );
+
+      vg_fatal_error( "async alloc invalid size\n" );
    }
 
    if( total_allocation > remaining ){
@@ -66,7 +78,10 @@ VG_STATIC vg_async_item *vg_async_alloc( u32 size )
 
    vg_async_item *entry = block;
    entry->next = NULL;
-   entry->payload = ((u8*)block) + vg_align8(sizeof(vg_async_item)); 
+
+   if( size ) entry->payload = ((u8*)block) + vg_align8(sizeof(vg_async_item)); 
+   else entry->payload = NULL;
+
    entry->size = size;
    entry->fn_runner = NULL;
 
@@ -83,12 +98,21 @@ VG_STATIC vg_async_item *vg_async_alloc( u32 size )
    return entry;
 }
 
+VG_STATIC void vg_async_stall(void)
+{
+   vg_info( "async_stall: %d\n", SDL_SemValue( vg_async.sem_wait_for_flush ) );
+   SDL_SemWait( vg_async.sem_wait_for_flush );
+}
+
 /*
  * 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 ) )
 {
+   if( SDL_SemValue(vg_async.sem_wait_for_flush) )
+      SDL_SemWait(vg_async.sem_wait_for_flush);
+
    SDL_AtomicLock( &vg_async.sl_index );
    item->fn_runner = runner;
    SDL_AtomicUnlock( &vg_async.sl_index );
@@ -119,12 +143,17 @@ VG_STATIC void vg_run_async_checked(void)
          }
       }
       else{
-         break;
+         SDL_AtomicUnlock( &vg_async.sl_index );
+         return;
       }
 
       /* TODO: if exceed max frametime.... */
    }
 
+   if( !SDL_SemValue( vg_async.sem_wait_for_flush ) ){
+      SDL_SemPost( vg_async.sem_wait_for_flush );
+   }
+
    SDL_AtomicUnlock( &vg_async.sl_index );
 }
 
@@ -132,7 +161,7 @@ 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 );
+                                                 VG_MEMORY_SYSTEM );
 }
 
 #endif /* VG_ASYNC_H */