Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
- Remove printf() call on release builds. This is more deterministic
  than printf() modifiers. We only use it printing u64, f32 variables.
- Add unit tests.
- Add checking if there is enough stack memory available
- Fixed trying to open gamepad when it is disconnecting
  • Loading branch information
e2dk4r committed Oct 27, 2024
1 parent 78ad948 commit 6afb6d1
Show file tree
Hide file tree
Showing 14 changed files with 1,673 additions and 527 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: install packages
run: sudo apt-get install -y --no-install-recommends --no-install-suggests
meson ninja-build
libevdev-dev liburing-dev
liburing-dev
libwayland-dev libwayland-client0 wayland-protocols

- name: configure
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: test

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: install packages
run: sudo apt-get install -y --no-install-recommends --no-install-suggests
meson ninja-build
liburing-dev
libwayland-dev libwayland-client0 wayland-protocols

- name: configure
run: meson setup build --buildtype release -Dtest=true

- name: test
run: meson test -C build
15 changes: 15 additions & 0 deletions include/assert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#if GAMEPAD_IDLE_INHIBIT_DEBUG
#define debug_assert(x) \
if (!(x)) { \
__builtin_debugtrap(); \
}
#else
#define debug_assert(x)
#endif

#define runtime_assert(x) \
if (!(x)) { \
__builtin_trap(); \
}
57 changes: 57 additions & 0 deletions include/math.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include "type.h"

/*
* Returns binary logarithm of 𝑥.
*
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
* 0x00000000 wut 32 0 wut 32
* 0x00000001 0 0 1 0 31
* 0x80000001 0 0 1 31 0
* 0x80000000 31 31 32 31 0
* 0x00000010 4 4 5 4 27
* 0x08000010 4 4 5 27 4
* 0x08000000 27 27 28 27 4
* 0xffffffff 0 0 1 31 0
*
* @param x is a 64-bit integer
* @return number in range 0..63 or undefined if 𝑥 is 0
*
* @note Adapted from https://github.com/jart/cosmopolitan/blob/master/libc/intrin/bsrl.c
* @copyright
* ╒══════════════════════════════════════════════════════════════════════════════╕
* │ Copyright 2023 Justine Alexandra Roberts Tunney │
* │ │
* │ Permission to use, copy, modify, and/or distribute this software for │
* │ any purpose with or without fee is hereby granted, provided that the │
* │ above copyright notice and this permission notice appear in all copies. │
* │ │
* │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
* │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
* │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
* │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
* │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
* │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
* │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
* │ PERFORMANCE OF THIS SOFTWARE. │
* └──────────────────────────────────────────────────────────────────────────────┘
*/
static inline u8
bsrl(s64 x)
{
static const u8 kDebruijn[64] = {
0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42,
21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43,
31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63,
};

x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
return kDebruijn[(x * 0x03f79d71b4cb0a89ull) >> 58];
}
131 changes: 131 additions & 0 deletions include/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#pragma once

#include "assert.h"
#include "type.h"

#if __has_builtin(__builtin_bzero)
#define bzero(address, size) __builtin_bzero(address, size)
#else
#error bzero must be supported by compiler
#endif

#if __has_builtin(__builtin_alloca)
#define alloca(size) __builtin_alloca(size)
#else
#error alloca must be supported by compiler
#endif

#if __has_builtin(__builtin_memcpy)
#define memcpy(dest, src, n) __builtin_memcpy(dest, src, n)
#else
#error memcpy must be supported by compiler
#endif

struct memory_block {
void *block;
u64 used;
u64 total;
};

struct memory_chunk {
void *block;
u64 size;
u64 max;
};

struct memory_temp {
struct memory_block *memory;
u64 startedAt;
};

static void *
MemPush(struct memory_block *mem, u64 size)
{
debug_assert(mem->used + size <= mem->total);
void *result = mem->block + mem->used;
mem->used += size;
return result;
}

static struct memory_chunk *
MemPushChunk(struct memory_block *mem, u64 size, u64 max)
{
struct memory_chunk *chunk = MemPush(mem, sizeof(*chunk) + max * sizeof(u8) + max * size);
chunk->block = chunk + sizeof(*chunk);
chunk->size = size;
chunk->max = max;
for (u64 index = 0; index < chunk->max; index++) {
u8 *flag = (u8 *)chunk->block + (sizeof(u8) * index);
*flag = 0;
}
return chunk;
}

static inline b8
MemChunkIsDataAvailableAt(struct memory_chunk *chunk, u64 index)
{
u8 *flags = (u8 *)chunk->block;
return *(flags + index);
}

static inline void *
MemChunkGetDataAt(struct memory_chunk *chunk, u64 index)
{
void *dataBlock = (u8 *)chunk->block + chunk->max;
void *result = dataBlock + index * chunk->size;
return result;
}

static void *
MemChunkPush(struct memory_chunk *chunk)
{
void *result = 0;
void *dataBlock = chunk->block + sizeof(u8) * chunk->max;
for (u64 index = 0; index < chunk->max; index++) {
u8 *flag = chunk->block + sizeof(u8) * index;
if (*flag == 0) {
result = dataBlock + index * chunk->size;
*flag = 1;
return result;
}
}

return result;
}

static void
MemChunkPop(struct memory_chunk *chunk, void *block)
{
void *dataBlock = chunk->block + sizeof(u8) * chunk->max;
debug_assert((block >= dataBlock && block <= dataBlock + (chunk->size * chunk->max)) &&
"this block is not belong to this chunk");
u64 index = (block - dataBlock) / chunk->size;
u8 *flag = chunk->block + sizeof(u8) * index;
*flag = 0;
}

static struct memory_temp
MemTempBegin(struct memory_block *memory)
{
return (struct memory_temp){
.memory = memory,
.startedAt = memory->used,
};
}

static void
MemTempEnd(struct memory_temp *tempMemory)
{
struct memory_block *memory = tempMemory->memory;
memory->used = tempMemory->startedAt;
}

#include "text.h"
static struct string
MemPushString(struct memory_block *memory, u64 size)
{
return (struct string){
.value = MemPush(memory, size),
.length = size,
};
}
Loading

0 comments on commit 6afb6d1

Please sign in to comment.