mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-14 04:49:41 -07:00
136 lines
2.8 KiB
C
136 lines
2.8 KiB
C
// Copyright (c) Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Ring Functions
|
|
|
|
internal Ring *
|
|
make_ring(Arena *arena, U64 size)
|
|
{
|
|
Ring *ring = push_array(arena, Ring, 1);
|
|
ring->size = size;
|
|
ring->base = push_array(arena, U8, ring->size);
|
|
return ring;
|
|
}
|
|
|
|
internal B32
|
|
ring_try_write(Ring *ring, U64 size, void *ptr)
|
|
{
|
|
U64 bytes_unconsumed = (ring->write_pos - ring->read_pos);
|
|
U64 bytes_available = ring->size - bytes_unconsumed;
|
|
B32 result = 0;
|
|
if(bytes_available >= size)
|
|
{
|
|
result = 1;
|
|
ring->write_pos += wrapped_write(ring->base, ring->size, ring->write_pos, ptr, size);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal B32
|
|
ring_try_read(Ring *ring, U64 size, void *ptr)
|
|
{
|
|
U64 bytes_unconsumed = (ring->write_pos - ring->read_pos);
|
|
B32 result = 0;
|
|
if(bytes_unconsumed >= size)
|
|
{
|
|
result = 1;
|
|
ring->read_pos += wrapped_read(ring->base, ring->size, ring->read_pos, ptr, size);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Guarded Ring Functions
|
|
|
|
internal GuardedRing *
|
|
guarded_ring_alloc(Arena *arena, U64 size)
|
|
{
|
|
GuardedRing *gr = push_array(arena, GuardedRing, 1);
|
|
gr->ring = make_ring(arena, size);
|
|
gr->mutex = mutex_alloc();
|
|
gr->cv = cond_var_alloc();
|
|
return gr;
|
|
}
|
|
|
|
internal void
|
|
guarded_ring_release(GuardedRing *ring)
|
|
{
|
|
mutex_release(ring->mutex);
|
|
cond_var_release(ring->cv);
|
|
}
|
|
|
|
internal RingGuard
|
|
guarded_ring_open(GuardedRing *ring)
|
|
{
|
|
RingGuard guard = {ring};
|
|
mutex_take(ring->mutex);
|
|
return guard;
|
|
}
|
|
|
|
internal void
|
|
guarded_ring_close(RingGuard *guard)
|
|
{
|
|
mutex_drop(guard->r->mutex);
|
|
}
|
|
|
|
internal B32
|
|
guarded_ring_try_write(RingGuard *guard, U64 size, void *ptr)
|
|
{
|
|
B32 result = ring_try_write(guard->r->ring, size, ptr);
|
|
if(result)
|
|
{
|
|
cond_var_broadcast(guard->r->cv);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal B32
|
|
guarded_ring_try_read(RingGuard *guard, U64 size, void *ptr)
|
|
{
|
|
B32 result = ring_try_read(guard->r->ring, size, ptr);
|
|
if(result)
|
|
{
|
|
cond_var_broadcast(guard->r->cv);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal B32
|
|
guarded_ring_write_or_wait(RingGuard *guard, U64 size, void *ptr, U64 endt_us)
|
|
{
|
|
B32 write_good = 0;
|
|
for(;!write_good;)
|
|
{
|
|
write_good = guarded_ring_try_write(guard, size, ptr);
|
|
if(now_time_us() >= endt_us)
|
|
{
|
|
break;
|
|
}
|
|
if(!write_good)
|
|
{
|
|
cond_var_wait(guard->r->cv, guard->r->mutex, endt_us);
|
|
}
|
|
}
|
|
return write_good;
|
|
}
|
|
|
|
internal B32
|
|
guarded_ring_read_or_wait(RingGuard *guard, U64 size, void *ptr, U64 endt_us)
|
|
{
|
|
B32 read_good = 0;
|
|
for(;!read_good;)
|
|
{
|
|
read_good = guarded_ring_try_read(guard, size, ptr);
|
|
if(now_time_us() >= endt_us)
|
|
{
|
|
break;
|
|
}
|
|
if(!read_good)
|
|
{
|
|
cond_var_wait(guard->r->cv, guard->r->mutex, endt_us);
|
|
}
|
|
}
|
|
return read_good;
|
|
}
|