mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-10 19:08:39 +00:00
cleanup
This commit is contained in:
parent
4c7026c698
commit
2943d418e2
|
|
@ -10,8 +10,6 @@
|
|||
#define TOS_ASSET_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../object/Vertex.h"
|
||||
#include "../stdlib/HashMap.h"
|
||||
#include "AssetType.h"
|
||||
|
||||
#define MAX_ASSET_NAME_LENGTH 32
|
||||
|
|
|
|||
|
|
@ -10,16 +10,6 @@
|
|||
#define TOS_AUDIO_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/StringUtils.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/UtilsWin32.h"
|
||||
#else
|
||||
#include "../platform/linux/UtilsLinux.h"
|
||||
#endif
|
||||
|
||||
#include "Audio.h"
|
||||
|
||||
struct Audio {
|
||||
// bits per sample
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include "../stdlib/Types.h"
|
||||
#include "../utils/BitUtils.h"
|
||||
#include "../utils/EndianUtils.h"
|
||||
#include "../utils/Utils.h"
|
||||
|
||||
struct HuffmanNode {
|
||||
HuffmanNode* left;
|
||||
|
|
@ -152,7 +151,7 @@ void huffman_dump(const Huffman* hf, byte* out)
|
|||
|
||||
void huffman_load(Huffman* hf, const byte* in)
|
||||
{
|
||||
// load the char -> code relations and convert relative indeces to pointers
|
||||
// load the char -> code relations and convert relative indices to pointers
|
||||
for (int32 i = 0; i < ARRAY_COUNT(hf->code); ++i) {
|
||||
int64 value = SWAP_ENDIAN_LITTLE(*((int64 *) in));
|
||||
in += sizeof(value);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ enum ControllerButton {
|
|||
};
|
||||
|
||||
struct ControllerInput {
|
||||
// @todo should probably include controller_id for xinput and LPDIRECTINPUTDEVICE8 for directinput
|
||||
|
||||
int8 button[MAX_CONTROLLER_KEYS];
|
||||
bool is_analog[MAX_CONTROLLER_KEYS]; // = uses deadzone
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include "Log.h"
|
||||
#include "TimingStat.h"
|
||||
#include "../utils/StringUtils.h"
|
||||
#include "../utils/TestUtils.h"
|
||||
#include "../utils/MathUtils.h"
|
||||
|
||||
global_persist DebugContainer* debug_container = NULL;
|
||||
|
||||
|
|
@ -21,7 +23,7 @@ global_persist DebugContainer* debug_container = NULL;
|
|||
QueryPerformanceFrequency(&perf_counter);
|
||||
debug_container->performance_count_frequency = perf_counter.QuadPart;
|
||||
}
|
||||
#else
|
||||
#elif __linux__
|
||||
void setup_performance_count() {
|
||||
if (!debug_container) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,12 @@
|
|||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "DebugMemory.h"
|
||||
#include "Log.h"
|
||||
#include "TimingStat.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
struct LogMemory {
|
||||
byte* memory;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,17 +10,9 @@
|
|||
#define TOS_LOG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/TestUtils.h"
|
||||
#include "../utils/MathUtils.h"
|
||||
#include "Debug.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef LOG_LEVEL
|
||||
#define LOG_LEVEL 0
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#define TOS_LOG_TIMING_STAT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "../stdlib/Types.h"
|
||||
#include "Debug.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@
|
|||
#include "../log/DebugMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocation.h"
|
||||
#include "../platform/win32/Allocator.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocation.h"
|
||||
#include "../platform/linux/Allocator.h"
|
||||
#endif
|
||||
|
||||
// @question Consider to use element_alignment to automatically align/pad elmeents
|
||||
// @question Consider to use element_alignment to automatically align/pad elements
|
||||
|
||||
struct BufferMemory {
|
||||
byte* memory;
|
||||
|
|
@ -59,9 +59,9 @@ void buffer_free(BufferMemory* buf)
|
|||
{
|
||||
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->size);
|
||||
if (buf->alignment < 2) {
|
||||
platform_free((void **) &buf->memory, buf->size);
|
||||
platform_free((void **) &buf->memory);
|
||||
} else {
|
||||
platform_aligned_free((void **) &buf->memory, buf->size);
|
||||
platform_aligned_free((void **) &buf->memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ void buffer_init(BufferMemory* buf, byte* data, uint64 size, int32 alignment = 6
|
|||
inline
|
||||
void buffer_reset(BufferMemory* buf)
|
||||
{
|
||||
// @bug arent we wasting element 0 (see get_memory, we are not using 0 only next element)
|
||||
// @bug aren't we wasting element 0 (see get_memory, we are not using 0 only next element)
|
||||
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->head - buf->memory);
|
||||
buf->head = buf->memory;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
#include "BufferMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocation.h"
|
||||
#include "../platform/win32/Allocator.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocation.h"
|
||||
#include "../platform/linux/Allocator.h"
|
||||
#endif
|
||||
|
||||
struct ChunkMemory {
|
||||
|
|
@ -66,9 +66,9 @@ void chunk_free(ChunkMemory* buf)
|
|||
{
|
||||
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->size);
|
||||
if (buf->alignment < 2) {
|
||||
platform_free((void **) &buf->memory, buf->size);
|
||||
platform_free((void **) &buf->memory);
|
||||
} else {
|
||||
platform_aligned_free((void **) &buf->memory, buf->size);
|
||||
platform_aligned_free((void **) &buf->memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
154
memory/Heap.h
Normal file
154
memory/Heap.h
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_MEMORY_HEAP_H
|
||||
#define TOS_MEMORY_HEAP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../log/DebugMemory.h"
|
||||
#include "BufferMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocator.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocator.h"
|
||||
#endif
|
||||
|
||||
struct Heap {
|
||||
byte* elements;
|
||||
byte* helper_mem;
|
||||
uint32 element_size;
|
||||
uint64 capacity;
|
||||
uint64 size;
|
||||
int32 (*compare) (const void*, const void*);
|
||||
};
|
||||
|
||||
void heap_alloc(Heap* heap, uint32 element_size, uint64 capacity, int32 (*compare)(const void*, const void*)) {
|
||||
ASSERT_SIMPLE(element_size * capacity);
|
||||
|
||||
heap->elements = (byte *) platform_alloc(element_size * capacity + element_size);
|
||||
if (!heap->elements) {
|
||||
return;
|
||||
}
|
||||
|
||||
heap->element_size = element_size;
|
||||
heap->capacity = capacity;
|
||||
heap->size = 0;
|
||||
heap->compare = compare;
|
||||
heap->helper_mem = heap->elements + element_size;
|
||||
|
||||
DEBUG_MEMORY_INIT((uint64) heap->elements, element_size * capacity);
|
||||
}
|
||||
|
||||
void heap_free(Heap* heap)
|
||||
{
|
||||
DEBUG_MEMORY_DELETE((uint64) heap->elements, heap->element_size * heap->capacity);
|
||||
platform_free((void **) &heap->elements);
|
||||
}
|
||||
|
||||
void heap_init(Heap* heap, BufferMemory* buf, uint32 element_size, uint64 capacity, int32 (*compare)(const void*, const void*)) {
|
||||
ASSERT_SIMPLE(element_size * capacity);
|
||||
|
||||
heap->elements = buffer_get_memory(buf, element_size * capacity, 8, true);
|
||||
if (!heap->elements) {
|
||||
return;
|
||||
}
|
||||
|
||||
heap->element_size = element_size;
|
||||
heap->capacity = capacity;
|
||||
heap->size = 0;
|
||||
heap->compare = compare;
|
||||
|
||||
DEBUG_MEMORY_INIT((uint64) heap->elements, element_size * capacity);
|
||||
}
|
||||
|
||||
void heapify_down(Heap* heap, uint64 index) {
|
||||
uint64 left_child = 2 * index + 1;
|
||||
uint64 right_child = left_child + 1;
|
||||
uint64 largest = index;
|
||||
|
||||
void* largest_element = heap->elements + (largest * heap->element_size);
|
||||
if (left_child < heap->size) {
|
||||
void* left = heap->elements + (left_child * heap->element_size);
|
||||
if (heap->compare(left, largest_element) > 0) {
|
||||
largest = left_child;
|
||||
}
|
||||
}
|
||||
|
||||
if (right_child < heap->size) {
|
||||
void* right = heap->elements + (right_child * heap->element_size);
|
||||
void* current_largest = heap->elements + (largest * heap->element_size);
|
||||
if (heap->compare(right, current_largest) > 0) {
|
||||
largest = right_child;
|
||||
}
|
||||
}
|
||||
|
||||
if (largest != index) {
|
||||
heap_swap(
|
||||
heap->elements + (index * heap->element_size),
|
||||
heap->elements + (largest * heap->element_size),
|
||||
heap->element_size, heap->helper_mem
|
||||
);
|
||||
|
||||
heapify_down(heap, largest);
|
||||
}
|
||||
}
|
||||
|
||||
void heapify_up(Heap* heap, uint64 index) {
|
||||
if (index == 0) {
|
||||
return; // Root node
|
||||
}
|
||||
|
||||
uint64 parent_index = (index - 1) / 2;
|
||||
void* current = heap->elements + (index * heap->element_size);
|
||||
void* parent = heap->elements + (parent_index * heap->element_size);
|
||||
|
||||
if (heap->compare(current, parent) > 0) {
|
||||
heap_swap(current, parent, heap->element_size, heap->helper_mem);
|
||||
heapify_up(heap, parent_index);
|
||||
}
|
||||
}
|
||||
|
||||
void heap_push(Heap* heap, const void* element) {
|
||||
if (heap->size >= heap->capacity) {
|
||||
return;
|
||||
}
|
||||
|
||||
void* target = heap->elements + (heap->size * heap->element_size);
|
||||
memcpy(target, element, heap->element_size);
|
||||
heapify_up(heap, heap->size);
|
||||
++heap->size;
|
||||
}
|
||||
|
||||
void heap_pop(Heap* heap, void* out) {
|
||||
if (heap->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(out, heap->elements, heap->element_size);
|
||||
void* last_element = heap->elements + ((heap->size - 1) * heap->element_size);
|
||||
memcpy(heap->elements, last_element, heap->element_size);
|
||||
--heap->size;
|
||||
heapify_down(heap, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void* heap_peek(Heap* heap) {
|
||||
return heap->elements;
|
||||
}
|
||||
|
||||
inline
|
||||
void heap_swap(void* a, void* b, uint32 size, void* helper_mem) {
|
||||
memcpy(helper_mem, a, size);
|
||||
memcpy(a, b, size);
|
||||
memcpy(b, helper_mem, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -9,110 +9,73 @@
|
|||
#ifndef TOS_MEMORY_QUEUE_H
|
||||
#define TOS_MEMORY_QUEUE_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "RingMemory.h"
|
||||
|
||||
typedef RingMemory Queue;
|
||||
|
||||
inline
|
||||
void queue_alloc(Queue* ring, uint64 size, int32 alignment = 64)
|
||||
void queue_alloc(Queue* queue, uint64 size, uint32 element_size, int32 alignment = 64)
|
||||
{
|
||||
ring_alloc(ring, size, alignment);
|
||||
|
||||
pthread_mutex_init(&ring->mutex, NULL);
|
||||
pthread_cond_init(&ring->cond, NULL);
|
||||
ring_alloc(queue, size, alignment);
|
||||
}
|
||||
|
||||
inline
|
||||
void queue_init(Queue* ring, BufferMemory* buf, uint64 size, int32 alignment = 64)
|
||||
void queue_init(Queue* queue, BufferMemory* buf, uint64 size, uint32 element_size, int32 alignment = 64)
|
||||
{
|
||||
ring_init(ring, buf, size, alignment);
|
||||
|
||||
pthread_mutex_init(&ring->mutex, NULL);
|
||||
pthread_cond_init(&ring->cond, NULL);
|
||||
ring_init(queue, buf, size, alignment);
|
||||
}
|
||||
|
||||
inline
|
||||
void queue_free(Queue* buf)
|
||||
void queue_init(Queue* queue, byte* buf, uint64 size, uint32 element_size, int32 alignment = 64)
|
||||
{
|
||||
ring_free(buf);
|
||||
ring_init(queue, buf, size, alignment);
|
||||
}
|
||||
|
||||
inline
|
||||
void queue_init(Queue* ring, byte* buf, uint64 size, int32 alignment = 64)
|
||||
void queue_free(Queue* queue)
|
||||
{
|
||||
ring_init(ring, buf, size, alignment);
|
||||
ring_free(queue);
|
||||
}
|
||||
|
||||
// Conditional Lock
|
||||
inline
|
||||
void ring_enqueue(Queue* ring, byte* data, uint64 size)
|
||||
void queue_enqueue(Queue* queue, byte* data, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_mutex_lock(&ring->mutex);
|
||||
|
||||
while (!ring_commit_safe(ring, size)) {
|
||||
pthread_cond_wait(&ring->cond, &ring->mutex);
|
||||
}
|
||||
|
||||
byte* mem = ring_get_memory(ring, size);
|
||||
byte* mem = ring_get_memory_nomove(queue, size, aligned);
|
||||
memcpy(mem, data, size);
|
||||
|
||||
pthread_cond_signal(&ring->cond);
|
||||
pthread_mutex_unlock(&ring->mutex);
|
||||
ring_move_pointer(queue, &queue->head, size, aligned);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* ring_enqueue_start(Queue* ring, uint64 size, byte aligned = 0)
|
||||
byte* queue_enqueue_start(Queue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_mutex_lock(&ring->mutex);
|
||||
|
||||
while (!ring_commit_safe(ring, size, aligned)) {
|
||||
pthread_cond_wait(&ring->cond, &ring->mutex);
|
||||
}
|
||||
|
||||
return ring_get_memory(ring, size, aligned);
|
||||
return ring_get_memory_nomove(queue, size, aligned);
|
||||
}
|
||||
|
||||
inline
|
||||
void ring_enqueue_end(Queue* ring)
|
||||
void queue_enqueue_end(Queue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_cond_signal(&ring->cond);
|
||||
pthread_mutex_unlock(&ring->mutex);
|
||||
ring_move_pointer(queue, &queue->head, size, aligned);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* ring_dequeue(Queue* ring, byte* data, uint64 size, byte aligned = 0)
|
||||
byte* queue_dequeue(Queue* queue, byte* data, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_mutex_lock(&ring->mutex);
|
||||
|
||||
while (ring->head == ring->tail) {
|
||||
pthread_cond_wait(&ring->cond, &ring->mutex);
|
||||
}
|
||||
|
||||
memcpy(data, ring->tail, size);
|
||||
ring_move_pointer(ring, &ring->tail, size, aligned);
|
||||
|
||||
pthread_cond_signal(&ring->cond);
|
||||
pthread_mutex_unlock(&ring->mutex);
|
||||
memcpy(data, queue->tail, size);
|
||||
ring_move_pointer(queue, &queue->tail, size, aligned);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* ring_dequeue_start(Queue* ring)
|
||||
byte* queue_dequeue_start(Queue* queue)
|
||||
{
|
||||
pthread_mutex_lock(&ring->mutex);
|
||||
|
||||
while (ring->head == ring->tail) {
|
||||
pthread_cond_wait(&ring->cond, &ring->mutex);
|
||||
}
|
||||
|
||||
return ring->tail;
|
||||
return queue->tail;
|
||||
}
|
||||
|
||||
inline
|
||||
void ring_dequeue_end(Queue* ring, uint64 size, byte aligned = 0)
|
||||
void queue_dequeue_end(Queue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
ring_move_pointer(ring, &ring->tail, size, aligned);
|
||||
|
||||
pthread_cond_signal(&ring->cond);
|
||||
pthread_mutex_unlock(&ring->mutex);
|
||||
ring_move_pointer(queue, &queue->tail, size, aligned);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -21,11 +21,13 @@
|
|||
#include "../log/DebugMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocation.h"
|
||||
#include "../platform/win32/Thread.h"
|
||||
#include "../platform/win32/Allocator.h"
|
||||
#include "../platform/win32/threading/ThreadDefines.h"
|
||||
#include "../platform/win32/threading/Semaphore.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocation.h"
|
||||
#include "../platform/linux/Thread.h"
|
||||
#include "../platform/linux/Allocator.h"
|
||||
#include "../platform/linux/threading/ThreadDefines.h"
|
||||
#include "../platform/linux/threading/Semaphore.h"
|
||||
#endif
|
||||
|
||||
struct RingMemory {
|
||||
|
|
@ -34,7 +36,7 @@ struct RingMemory {
|
|||
|
||||
byte* head;
|
||||
|
||||
// This variable is usually only used by single read/write code mostly found in threads.
|
||||
// This variable is usually only used by single producer/consumer code mostly found in threads.
|
||||
// One thread inserts elements -> updates head
|
||||
// The other thread reads elements -> updates tail
|
||||
// This code itself doesn't change this variable
|
||||
|
|
@ -44,8 +46,13 @@ struct RingMemory {
|
|||
int32 alignment;
|
||||
int32 element_alignment;
|
||||
|
||||
// We support both conditional locking and semaphore locking
|
||||
// These values are not initialized and not used unless you use the queue
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
|
||||
sem_t empty;
|
||||
sem_t full;
|
||||
};
|
||||
|
||||
// @bug alignment should also include the end point, not just the start
|
||||
|
|
@ -114,9 +121,9 @@ inline
|
|||
void ring_free(RingMemory* buf)
|
||||
{
|
||||
if (buf->alignment < 2) {
|
||||
platform_free((void **) &buf->memory, buf->size);
|
||||
platform_free((void **) &buf->memory);
|
||||
} else {
|
||||
platform_aligned_free((void **) &buf->memory, buf->size);
|
||||
platform_aligned_free((void **) &buf->memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,6 +225,41 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zero
|
|||
return offset;
|
||||
}
|
||||
|
||||
// Same as ring_get_memory but DOESN'T move the head
|
||||
byte* ring_get_memory_nomove(RingMemory* ring, uint64 size, byte aligned = 0, bool zeroed = false)
|
||||
{
|
||||
ASSERT_SIMPLE(size <= ring->size);
|
||||
|
||||
if (aligned == 0) {
|
||||
aligned = (byte) OMS_MAX(ring->element_alignment, 1);
|
||||
}
|
||||
|
||||
byte* pos = ring->head;
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) pos;
|
||||
pos += (aligned - (address& (aligned - 1))) % aligned;
|
||||
}
|
||||
|
||||
size = ROUND_TO_NEAREST(size, aligned);
|
||||
if (pos + size > ring->end) {
|
||||
ring_reset(ring);
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) pos;
|
||||
pos += (aligned - (address & (aligned - 1))) % aligned;
|
||||
}
|
||||
}
|
||||
|
||||
if (zeroed) {
|
||||
memset((void *) pos, 0, size);
|
||||
}
|
||||
|
||||
DEBUG_MEMORY_WRITE((uint64) pos, size);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Used if the ring only contains elements of a certain size
|
||||
// This way you can get a certain element
|
||||
inline
|
||||
|
|
|
|||
204
memory/ThreadedQueue.h
Normal file
204
memory/ThreadedQueue.h
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_MEMORY_QUEUE_H
|
||||
#define TOS_MEMORY_QUEUE_H
|
||||
|
||||
#include "RingMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/threading/Thread.h"
|
||||
#include "../platform/win32/threading/Semaphore.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/threading/Thread.h"
|
||||
#include "../platform/linux/threading/Semaphore.h"
|
||||
#endif
|
||||
|
||||
typedef RingMemory ThreadedQueue;
|
||||
|
||||
inline
|
||||
void threaded_queue_alloc(ThreadedQueue* queue, uint64 size, uint32 element_count, int32 alignment = 64)
|
||||
{
|
||||
ring_alloc(queue, size, alignment);
|
||||
|
||||
pthread_mutex_init(&queue->mutex, NULL);
|
||||
pthread_cond_init(&queue->cond, NULL);
|
||||
|
||||
sem_init(&queue->empty, element_count);
|
||||
sem_init(&queue->full, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_init(ThreadedQueue* queue, BufferMemory* buf, uint64 size, uint32 element_count, int32 alignment = 64)
|
||||
{
|
||||
ring_init(queue, buf, size, alignment);
|
||||
|
||||
pthread_mutex_init(&queue->mutex, NULL);
|
||||
pthread_cond_init(&queue->cond, NULL);
|
||||
|
||||
sem_init(&queue->empty, element_count);
|
||||
sem_init(&queue->full, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_init(ThreadedQueue* queue, byte* buf, uint64 size, uint32 element_count, int32 alignment = 64)
|
||||
{
|
||||
ring_init(queue, buf, size, alignment);
|
||||
|
||||
pthread_mutex_init(&queue->mutex, NULL);
|
||||
pthread_cond_init(&queue->cond, NULL);
|
||||
|
||||
sem_init(&queue->empty, element_count);
|
||||
sem_init(&queue->full, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_free(ThreadedQueue* queue)
|
||||
{
|
||||
ring_free(queue);
|
||||
sem_destroy(&queue->empty);
|
||||
sem_destroy(&queue->full);
|
||||
pthread_mutex_destroy(&queue->mutex);
|
||||
pthread_cond_destroy(&queue->cond);
|
||||
}
|
||||
|
||||
// Conditional Lock
|
||||
inline
|
||||
void threaded_queue_enqueue(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
while (!ring_commit_safe(queue, size)) {
|
||||
pthread_cond_wait(&queue->cond, &queue->mutex);
|
||||
}
|
||||
|
||||
byte* mem = ring_get_memory(queue, size, aligned);
|
||||
memcpy(mem, data, size);
|
||||
|
||||
pthread_cond_signal(&queue->cond);
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* threaded_queue_enqueue_start(ThreadedQueue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
while (!ring_commit_safe(queue, size, aligned)) {
|
||||
pthread_cond_wait(&queue->cond, &queue->mutex);
|
||||
}
|
||||
|
||||
return ring_get_memory(queue, size, aligned);
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_enqueue_end(ThreadedQueue* queue)
|
||||
{
|
||||
pthread_cond_signal(&queue->cond);
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* threaded_queue_dequeue(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
|
||||
{
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
while (queue->head == queue->tail) {
|
||||
pthread_cond_wait(&queue->cond, &queue->mutex);
|
||||
}
|
||||
|
||||
memcpy(data, queue->tail, size);
|
||||
ring_move_pointer(queue, &queue->tail, size, aligned);
|
||||
|
||||
pthread_cond_signal(&queue->cond);
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* threaded_queue_dequeue_start(ThreadedQueue* queue)
|
||||
{
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
while (queue->head == queue->tail) {
|
||||
pthread_cond_wait(&queue->cond, &queue->mutex);
|
||||
}
|
||||
|
||||
return queue->tail;
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_dequeue_end(ThreadedQueue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
ring_move_pointer(queue, &queue->tail, size, aligned);
|
||||
|
||||
pthread_cond_signal(&queue->cond);
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
}
|
||||
|
||||
// Semaphore Lock
|
||||
inline
|
||||
void threaded_queue_enqueue_sem(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
|
||||
{
|
||||
sem_wait(&queue->empty);
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
byte* mem = ring_get_memory(queue, size, aligned);
|
||||
memcpy(mem, data, size);
|
||||
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
sem_post(&queue->full);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* threaded_queue_enqueue_start_sem(ThreadedQueue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
sem_wait(&queue->empty);
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
return ring_get_memory(queue, size, aligned);
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_enqueue_end_sem(ThreadedQueue* queue)
|
||||
{
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
sem_post(&queue->full);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* threaded_queue_dequeue_sem(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
|
||||
{
|
||||
sem_wait(&queue->full);
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
memcpy(data, queue->tail, size);
|
||||
ring_move_pointer(queue, &queue->tail, size, aligned);
|
||||
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
sem_post(&queue->empty);
|
||||
}
|
||||
|
||||
inline
|
||||
byte* threaded_queue_dequeue_start_sem(ThreadedQueue* queue)
|
||||
{
|
||||
sem_wait(&queue->full);
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
return queue->tail;
|
||||
}
|
||||
|
||||
inline
|
||||
void threaded_queue_dequeue_end_sem(ThreadedQueue* queue, uint64 size, byte aligned = 0)
|
||||
{
|
||||
ring_move_pointer(queue, &queue->tail, size, aligned);
|
||||
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
sem_post(&queue->empty);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -17,7 +17,7 @@ static const int PRIMARY_STAT_INDICES[] = {0, 1, 2, 3, 4, 5, 6, 7};
|
|||
// Character stats modifiable through leveling (simple +/- buttons)
|
||||
struct PrimaryStatsPoints {
|
||||
uint16 stat_str; // strength : effects health + base damage
|
||||
uint16 stat_int; // inteligence : effects resource + base demage
|
||||
uint16 stat_int; // intelligence : effects resource + base damage
|
||||
uint16 stat_acc; // accuracy : effects critical chance + base damage + miss chance
|
||||
uint16 stat_agi; // agility : effects resource + base damage + dodge chance
|
||||
// @todo not implemented in database
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static const int SECONDARY_STAT_INDICES[] = {
|
|||
* @todo optimize order of struct members to ensure optimal struct size
|
||||
*/
|
||||
|
||||
// Character stats modifiable thorugh skill tree?
|
||||
// Character stats modifiable through skill tree?
|
||||
struct SecondaryStatsPoints {
|
||||
/*
|
||||
@todo
|
||||
|
|
@ -45,15 +45,12 @@ struct SecondaryStatsPoints {
|
|||
// This allows us to create skills with multiple additive damage types AND composite damage that has multiple types at the same time
|
||||
uint16 dmg[MOB_STATS_TYPE_SIZE];
|
||||
|
||||
uint16 dmg_reflection;
|
||||
uint16 dmg_reflection_chance;
|
||||
|
||||
// @question is this a damage number or is this a % number of the total damage?
|
||||
uint16 dmg_crit;
|
||||
uint16 dmg_crit_chance;
|
||||
|
||||
// @question is this similar to the different damage categories, is this a % of the total damage or should this just be a flag
|
||||
uint16 dmg_pircing;
|
||||
uint16 dmg_piercing;
|
||||
|
||||
// Health & Resource
|
||||
uint16 health;
|
||||
|
|
@ -85,6 +82,9 @@ struct SecondaryStatsPoints {
|
|||
uint16 block_chance;
|
||||
uint16 block_amount;
|
||||
|
||||
uint16 dmg_reflection;
|
||||
uint16 dmg_reflection_chance;
|
||||
|
||||
uint16 dodge_chance;
|
||||
uint16 cc_protection;
|
||||
uint16 miss_chance;
|
||||
|
|
@ -162,7 +162,7 @@ struct SecondaryStatsPoints2 {
|
|||
byte dmg_crit_chance;
|
||||
|
||||
// @question is this similar to the different damage categories, is this a % of the total damage or should this just be a flag
|
||||
byte dmg_pircing;
|
||||
byte dmg_piercing;
|
||||
|
||||
// Health & Resource
|
||||
byte health;
|
||||
|
|
@ -257,7 +257,7 @@ struct SecondaryStatsRelPoints2 {
|
|||
byte dmg_crit;
|
||||
byte dmg_crit_chance;
|
||||
|
||||
byte dmg_pircing;
|
||||
byte dmg_piercing;
|
||||
|
||||
// Health & Resource
|
||||
byte health;
|
||||
|
|
@ -281,7 +281,7 @@ struct SecondaryStatsRelPoints2 {
|
|||
byte resource_loss_on_dmg_taken;
|
||||
|
||||
// Defense types
|
||||
// think about it as armor and/or resistence if it helps
|
||||
// think about it as armor and/or resistance if it helps
|
||||
byte defense[MOB_STATS_TYPE_SIZE];
|
||||
|
||||
// Accuracy
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void mesh_from_file_txt(
|
|||
uint32 temp_color_count = 0;
|
||||
|
||||
while (*pos != '\0') {
|
||||
char_skip_empty(&pos);
|
||||
str_skip_empty(&pos);
|
||||
|
||||
if (*pos == '\0') {
|
||||
break;
|
||||
|
|
@ -152,11 +152,11 @@ void mesh_from_file_txt(
|
|||
state = 15;
|
||||
} else {
|
||||
// not supported or comment
|
||||
char_move_to(&pos, '\n');
|
||||
str_move_to(&pos, '\n');
|
||||
}
|
||||
|
||||
// move past keyword
|
||||
char_skip_non_empty(&pos);
|
||||
str_skip_non_empty(&pos);
|
||||
|
||||
// move past whitespaces and newline
|
||||
bool is_next_line = false;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/MathUtils.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
||||
f32 manhattan_2d(v2_f32 a, v2_f32 b) {
|
||||
return fabs(a.x - b.x) + fabs(a.y - b.y);
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
||||
// Manhattan distance for 3D
|
||||
f32 manhattan_3d(v3_f32 a, v3_f32 b) {
|
||||
|
|
|
|||
23
pathfinding/Path.h
Normal file
23
pathfinding/Path.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @package Utils
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PATHFINDING_PATH_H
|
||||
#define TOS_PATHFINDING_PATH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/MathUtils.h"
|
||||
|
||||
struct Path {
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
43
pathfinding/jps/Jps.h
Normal file
43
pathfinding/jps/Jps.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @package Utils
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PATHFINDING_JPS_H
|
||||
#define TOS_PATHFINDING_JPS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/MathUtils.h"
|
||||
|
||||
#include "JpsGrid.h"
|
||||
#include "../Path.h"
|
||||
|
||||
void jps_find_path(
|
||||
v3_int32 start, v3_int32 end,
|
||||
const JpsGrid* grid, Path* path,
|
||||
int32 heuristic, int32 movement
|
||||
) {
|
||||
JpsNode* start_node = &grid->nodes[
|
||||
grid->dimension.x * grid->dimension.y * start.z
|
||||
+ grid->dimension.x * start.y
|
||||
+ start.x
|
||||
];
|
||||
|
||||
JpsNode* end_node = &grid->nodes[
|
||||
grid->dimension.x * grid->dimension.y * end.z
|
||||
+ grid->dimension.x * end.y
|
||||
+ end.x
|
||||
];
|
||||
|
||||
if (!start_node->is_walkable || !end_node->is_walkable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
30
pathfinding/jps/JpsGrid.h
Normal file
30
pathfinding/jps/JpsGrid.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @package Utils
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PATHFINDING_JPS_GRID_H
|
||||
#define TOS_PATHFINDING_JPS_GRID_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/MathUtils.h"
|
||||
|
||||
#include "JpsNode.h"
|
||||
|
||||
struct JpsGrid {
|
||||
// 1. left to right
|
||||
// 2. then front to back
|
||||
// 3. then height
|
||||
JpsNode* nodes;
|
||||
|
||||
v3_int32 dimension;
|
||||
};
|
||||
|
||||
#endif
|
||||
23
pathfinding/jps/JpsNode.h
Normal file
23
pathfinding/jps/JpsNode.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @package Utils
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PATHFINDING_JPS_NODE_H
|
||||
#define TOS_PATHFINDING_JPS_NODE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/MathUtils.h"
|
||||
|
||||
struct JpsNode {
|
||||
bool is_walkable;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -33,7 +33,7 @@ struct NetworkInfo {
|
|||
};
|
||||
|
||||
struct SIMDInfo {
|
||||
f32 sse;
|
||||
int32 sse;
|
||||
int32 avx256;
|
||||
int32 avx512;
|
||||
int32 sve;
|
||||
|
|
@ -89,8 +89,11 @@ struct SystemInfo {
|
|||
GpuInfo gpu[2];
|
||||
int32 gpu_count;
|
||||
|
||||
DisplayInfo display_primary;
|
||||
DisplayInfo display[6];
|
||||
int32 display_count;
|
||||
|
||||
int32 language;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_ALLOCATION_H
|
||||
#define TOS_PLATFORM_LINUX_ALLOCATION_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
inline
|
||||
void aligned_free(void** ptr) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_alloc(size_t size)
|
||||
{
|
||||
ssize_t page_size = sysconf(_SC_PAGESIZE);
|
||||
|
||||
size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_alloc_aligned(size_t size, int32 alignment)
|
||||
{
|
||||
ssize_t page_size = sysconf(_SC_PAGESIZE);
|
||||
if (alignment < page_size) {
|
||||
alignment = page_size;
|
||||
}
|
||||
|
||||
size = (size + alignment - 1) & ~(alignment - 1);
|
||||
|
||||
void* ptr = mmap(NULL, size + alignment + sizeof(void*), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
void* aligned_ptr = (void*)(((uintptr_t)ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
|
||||
((void**) aligned_ptr)[-1] = ptr;
|
||||
|
||||
return aligned_ptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_free(void** ptr, size_t size) {
|
||||
munmap(*ptr, size);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_aligned_free(void** aligned_ptr, size_t size) {
|
||||
void* ptr = ((void**) *aligned_ptr)[-1];
|
||||
munmap(ptr, size + ((uintptr_t) *aligned_ptr - (uintptr_t)ptr));
|
||||
*aligned_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
132
platform/linux/Allocator.h
Normal file
132
platform/linux/Allocator.h
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_ALLOCATOR_H
|
||||
#define TOS_PLATFORM_LINUX_ALLOCATOR_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/TestUtils.h"
|
||||
|
||||
// @todo Currently alignment only effects the starting position, but it should also effect the ending/size
|
||||
// @todo Consider to rename file to Allocator.h
|
||||
|
||||
// @question Since we store at least the size of the memory in the beginning,
|
||||
// does this have a negative impact on caching?
|
||||
// Our Memory doesn't start at the cache line beginning but at least offset by sizeof(size_t)
|
||||
|
||||
inline
|
||||
void* platform_alloc(size_t size)
|
||||
{
|
||||
ssize_t page_size = sysconf(_SC_PAGESIZE);
|
||||
size = (size + sizeof(size_t) + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_SIMPLE(ptr != MAP_FAILED);
|
||||
|
||||
*((size_t *) ptr) = size;
|
||||
|
||||
return (void *) ((uintptr_t) ptr + sizeof(size_t));
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_alloc_aligned(size_t size, int32 alignment)
|
||||
{
|
||||
ssize_t page_size = sysconf(_SC_PAGESIZE);
|
||||
if (alignment < page_size) {
|
||||
alignment = page_size;
|
||||
}
|
||||
|
||||
size += alignment - 1 + sizeof(void *) + sizeof(size_t);
|
||||
|
||||
void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_SIMPLE(ptr != MAP_FAILED);
|
||||
|
||||
// We want an aligned memory area but mmap doesn't really support that.
|
||||
// That's why we have to manually offset our memory area.
|
||||
// However, when freeing the pointer later on we need the actual start of the memory area, not the manually offset one.
|
||||
// We do the same with the size, which is required when freeing
|
||||
uintptr_t raw_address = (uintptr_t) ptr + sizeof(void *) + sizeof(size_t);
|
||||
void* aligned_ptr = (void *) ((raw_address + alignment - 1) & ~(alignment - 1));
|
||||
|
||||
*((void **) ((uintptr_t) aligned_ptr - sizeof(void *) - sizeof(size_t))) = ptr;
|
||||
*((size_t *) ((uintptr_t) aligned_ptr - sizeof(size_t))) = size;
|
||||
|
||||
return aligned_ptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_free(void** ptr) {
|
||||
void* actual_ptr = (void *) ((uintptr_t) *ptr - sizeof(size_t));
|
||||
munmap(actual_ptr, *((size_t *) actual_ptr));
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_aligned_free(void** aligned_ptr) {
|
||||
void* ptr = (void *) ((uintptr_t) *aligned_ptr - sizeof(void *) - sizeof(size_t));
|
||||
munmap(ptr, *((size_t *) ((uintptr_t) ptr + sizeof(void *))));
|
||||
*aligned_ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_shared_alloc(int32* fd, const char* name, size_t size)
|
||||
{
|
||||
*fd = shm_open(name, O_CREAT | O_RDWR, 0666);
|
||||
ASSERT_SIMPLE(*fd != -1);
|
||||
|
||||
ssize_t page_size = sysconf(_SC_PAGESIZE);
|
||||
size = (size + sizeof(size_t) + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
ftruncate(*fd, size);
|
||||
|
||||
void* shm_ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
|
||||
ASSERT_SIMPLE(shm_ptr);
|
||||
|
||||
*((size_t *) shm_ptr) = size;
|
||||
|
||||
return (void *) ((uintptr_t) shm_ptr + sizeof(size_t));
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_shared_open(int32* fd, const char* name, size_t size)
|
||||
{
|
||||
*fd = shm_open(name, O_RDWR, 0666);
|
||||
ASSERT_SIMPLE(*fd != -1);
|
||||
|
||||
ssize_t page_size = sysconf(_SC_PAGESIZE);
|
||||
size = (size + sizeof(size_t) + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
void* shm_ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, *fd, 0);
|
||||
ASSERT_SIMPLE(shm_ptr);
|
||||
|
||||
*((size_t *) shm_ptr) = size;
|
||||
|
||||
return (void *) ((uintptr_t) shm_ptr + sizeof(size_t));
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_shared_free(int32 fd, const char* name, void** ptr)
|
||||
{
|
||||
munmap((void *) ((uintptr_t) *ptr - sizeof(size_t)), *((size_t *) ((uintptr_t) *ptr - sizeof(size_t))));
|
||||
*ptr = NULL;
|
||||
|
||||
shm_unlink(name);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_shared_close(int32 fd)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -62,7 +62,7 @@ bool library_load(Library* lib)
|
|||
}
|
||||
|
||||
lib->is_valid = true;
|
||||
for (int32_t c = 0; c < lib->function_count; ++c) {
|
||||
for (int32 c = 0; c < lib->function_count; ++c) {
|
||||
void* function = dlsym(lib->handle, lib->function_names[c]);
|
||||
if (function) {
|
||||
lib->functions[c] = function;
|
||||
|
|
@ -82,7 +82,7 @@ void library_unload(Library* lib)
|
|||
lib->handle = NULL;
|
||||
}
|
||||
|
||||
for (int32_t c = 0; c < lib->function_count; ++c) {
|
||||
for (int32 c = 0; c < lib->function_count; ++c) {
|
||||
lib->functions[c] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <stdint.h>
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../stdlib/simd/SIMD_Helper.h"
|
||||
#include "../../utils/StringUtils.h"
|
||||
#include "../SystemInfo.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREAD_H
|
||||
#define TOS_PLATFORM_LINUX_THREAD_H
|
||||
|
||||
#include "ThreadDefines.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -6,17 +6,11 @@
|
|||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREAD_DEFINES_H
|
||||
#define TOS_PLATFORM_LINUX_THREAD_DEFINES_H
|
||||
#ifndef TOS_PLATFORM_LINUX_THREADING_ATOMIC_H
|
||||
#define TOS_PLATFORM_LINUX_THREADING_ATOMIC_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
|
||||
typedef void* (*ThreadJobFunc)(void*);
|
||||
|
||||
#define THREAD_RETURN void*
|
||||
#include "../../../stdlib/Types.h"
|
||||
|
||||
inline
|
||||
void atomic_set(volatile int32* value, int32 new_value)
|
||||
15
platform/linux/threading/Semaphore.h
Normal file
15
platform/linux/threading/Semaphore.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREADING_SEMAPHORE_H
|
||||
#define TOS_PLATFORM_LINUX_THREADING_SEMAPHORE_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#endif
|
||||
27
platform/linux/threading/Spinlock.h
Normal file
27
platform/linux/threading/Spinlock.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREADING_SPINLOCK_H
|
||||
#define TOS_PLATFORM_LINUX_THREADING_SPINLOCK_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "../../../stdlib/Types.h"
|
||||
|
||||
typedef volatile int32 spinlock32;
|
||||
|
||||
inline
|
||||
void spinlock_start(spinlock32* lock) {
|
||||
while (__atomic_exchange_n(lock, 1, __ATOMIC_ACQUIRE)) {}
|
||||
}
|
||||
|
||||
inline
|
||||
void spinlock_end(spinlock32* lock) {
|
||||
__atomic_store_n(lock, 0, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
#endif
|
||||
21
platform/linux/threading/Thread.h
Normal file
21
platform/linux/threading/Thread.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREADING_THREAD_H
|
||||
#define TOS_PLATFORM_LINUX_THREADING_THREAD_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "ThreadDefines.h"
|
||||
|
||||
uint32 pcthread_get_num_procs()
|
||||
{
|
||||
return (uint32) sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
|
||||
#endif
|
||||
19
platform/linux/threading/ThreadDefines.h
Normal file
19
platform/linux/threading/ThreadDefines.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREADING_THREAD_DEFINES_H
|
||||
#define TOS_PLATFORM_LINUX_THREADING_THREAD_DEFINES_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef void* (*ThreadJobFunc)(void*);
|
||||
|
||||
#define THREAD_RETURN void*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_ALLOCATION_H
|
||||
#define TOS_PLATFORM_WIN32_ALLOCATION_H
|
||||
|
||||
#include <malloc.h>
|
||||
#include <windows.h>
|
||||
#include "../../stdlib/Types.h"
|
||||
|
||||
inline
|
||||
void* aligned_alloc(size_t alignment, size_t size) {
|
||||
return _aligned_malloc(size, alignment);
|
||||
}
|
||||
|
||||
inline
|
||||
void aligned_free(void** ptr) {
|
||||
_aligned_free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_alloc(size_t size)
|
||||
{
|
||||
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_alloc_aligned(size_t size, int32 alignment)
|
||||
{
|
||||
void* ptr = VirtualAlloc(NULL, size + alignment + sizeof(void*), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
void* aligned_ptr = (void*)(((uintptr_t)ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
|
||||
((void**) aligned_ptr)[-1] = ptr;
|
||||
|
||||
return aligned_ptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_free(void** ptr, size_t) {
|
||||
VirtualFree(*ptr, 0, MEM_RELEASE);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_aligned_free(void** aligned_ptr, size_t) {
|
||||
void* ptr = ((void**) *aligned_ptr)[-1];
|
||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
*aligned_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
92
platform/win32/Allocator.h
Normal file
92
platform/win32/Allocator.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_ALLOCATOR_H
|
||||
#define TOS_PLATFORM_WIN32_ALLOCATOR_H
|
||||
|
||||
#include <malloc.h>
|
||||
#include <windows.h>
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/TestUtils.h"
|
||||
|
||||
// @todo Currently alignment only effects the starting position, but it should also effect the ending/size
|
||||
// @todo Consider to rename file to Allocator.h
|
||||
|
||||
inline
|
||||
void* platform_alloc(size_t size)
|
||||
{
|
||||
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_alloc_aligned(size_t size, int32 alignment)
|
||||
{
|
||||
void* ptr = VirtualAlloc(NULL, size + alignment + sizeof(void*), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
ASSERT_SIMPLE(ptr);
|
||||
|
||||
// We want an aligned memory area but mmap doesn't really support that.
|
||||
// That's why we have to manually offset our memory area.
|
||||
// However, when freeing the pointer later on we need the actual start of the memory area, not the manually offset one.
|
||||
void* aligned_ptr = (void *) (((uintptr_t) ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
|
||||
((void**) aligned_ptr)[-1] = ptr;
|
||||
|
||||
return aligned_ptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_free(void** ptr) {
|
||||
VirtualFree(*ptr, 0, MEM_RELEASE);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_aligned_free(void** aligned_ptr) {
|
||||
void* ptr = ((void**) *aligned_ptr)[-1];
|
||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
*aligned_ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_shared_alloc(HANDLE* fd, const char* name, size_t size)
|
||||
{
|
||||
*fd = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD) size, name);
|
||||
ASSERT_SIMPLE(*fd);
|
||||
|
||||
void* shm_ptr = MapViewOfFile(*fd, FILE_MAP_ALL_ACCESS, 0, 0, size);
|
||||
ASSERT_SIMPLE(shm_ptr);
|
||||
|
||||
return shm_ptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void* platform_shared_open(HANDLE* fd, const char* name, size_t size)
|
||||
{
|
||||
*fd = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, name);
|
||||
ASSERT_SIMPLE(*fd);
|
||||
|
||||
void* shm_ptr = MapViewOfFile(*fd, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, (DWORD) size);
|
||||
ASSERT_SIMPLE(shm_ptr);
|
||||
|
||||
return shm_ptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_shared_free(HANDLE fd, const char*, void** ptr)
|
||||
{
|
||||
UnmapViewOfFile(*ptr);
|
||||
CloseHandle(fd);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void platform_shared_close(HANDLE fd)
|
||||
{
|
||||
CloseHandle(fd);
|
||||
}
|
||||
|
||||
#endif
|
||||
49
platform/win32/FastPipes.h
Normal file
49
platform/win32/FastPipes.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_UTILS_FAST_PIPES_H
|
||||
#define TOS_UTILS_FAST_PIPES_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
#pragma comment(lib, "kernel32.lib")
|
||||
#pragma comment(lib, "user32.lib")
|
||||
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int ENABLE_FAST_PIPES()
|
||||
{
|
||||
int32 result = 0;
|
||||
|
||||
wchar_t pipe_name[32];
|
||||
wsprintfW(pipe_name, L"\\\\.\\pipe\\fastpipe%x", GetCurrentProcessId());
|
||||
HANDLE fast_pip = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||
|
||||
if(fast_pip != INVALID_HANDLE_VALUE) {
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, fast_pip);
|
||||
SetStdHandle(STD_INPUT_HANDLE, fast_pip);
|
||||
|
||||
int32 std_out = _open_osfhandle((intptr_t) fast_pip, O_WRONLY | O_TEXT);
|
||||
int32 std_in = _open_osfhandle((intptr_t) fast_pip, O_RDONLY | O_TEXT);
|
||||
|
||||
_dup2(std_out, _fileno(stdout));
|
||||
_dup2(std_in, _fileno(stdin));
|
||||
|
||||
_close(std_out);
|
||||
_close(std_in);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../network/SocketConnection.h"
|
||||
#include "../../utils/EndianUtils.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <stdint.h>
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../stdlib/simd/SIMD_Helper.h"
|
||||
#include "../../utils/StringUtils.h"
|
||||
#include "../SystemInfo.h"
|
||||
|
||||
#include <psapi.h>
|
||||
|
|
@ -312,8 +311,7 @@ int network_info_get(NetworkInfo* info) {
|
|||
}
|
||||
|
||||
void cpu_info_get(CpuInfo* info) {
|
||||
int32 temp;
|
||||
info->simd.sse = (temp = max_sse_supported()) > 9 ? temp / 10.0f : temp;
|
||||
info->simd.sse = max_sse_supported();
|
||||
info->simd.avx256 = max_avx256_supported();
|
||||
info->simd.avx512 = max_avx512_supported();
|
||||
info->simd.sve = max_sve_supported();
|
||||
|
|
@ -553,7 +551,7 @@ void system_info_render(char* buf, const SystemInfo* info) {
|
|||
info->cpu.cache[1].size, info->cpu.cache[1].line_size,
|
||||
info->cpu.cache[2].size, info->cpu.cache[2].line_size,
|
||||
info->cpu.cache[3].size, info->cpu.cache[3].line_size,
|
||||
info->cpu.simd.sse, info->cpu.simd.avx256, info->cpu.simd.avx512 > 0 ? avx512[info->cpu.simd.avx512 - 1] : "0", info->cpu.simd.sve, info->cpu.simd.neon, (int32) info->cpu.simd.abm,
|
||||
info->cpu.simd.sse > 9 ? (f32) info->cpu.simd.sse / 10.0f : (f32) info->cpu.simd.sse, info->cpu.simd.avx256, info->cpu.simd.avx512 > 0 ? avx512[info->cpu.simd.avx512 - 1] : "0", info->cpu.simd.sve, info->cpu.simd.neon, (int32) info->cpu.simd.abm,
|
||||
info->gpu[0].name, info->gpu[0].vram,
|
||||
info->gpu_count < 2 ? "" : info->gpu[1].name, info->gpu_count < 2 ? 0 : info->gpu[1].vram,
|
||||
info->display[0].name, info->display[0].width, info->display[0].height, info->display[0].hz,
|
||||
|
|
@ -575,6 +573,8 @@ void system_info_get(SystemInfo* info)
|
|||
ram_info_get(&info->ram);
|
||||
info->gpu_count = gpu_info_get(info->gpu);
|
||||
info->display_count = display_info_get(info->display);
|
||||
display_info_get_primary(&info->display_primary);
|
||||
info->language = system_language_code();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREAD_H
|
||||
#define TOS_PLATFORM_WIN32_THREAD_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "ThreadDefines.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void ms_to_timespec(timespec *ts, uint32 ms)
|
||||
{
|
||||
if (ts == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo replace time() with os specifc solution
|
||||
ts->tv_sec = (ms / 1000) + time(0);
|
||||
ts->tv_nsec = (ms % 1000) * 1000000;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int32 pthread_create(pthread_t* thread, void*, ThreadJobFunc start_routine, void* arg)
|
||||
{
|
||||
if (thread == NULL || start_routine == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
*thread = CreateThread(NULL, 0, start_routine, arg, 0, NULL);
|
||||
if (*thread == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_join(pthread_t thread, void**)
|
||||
{
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_detach(pthread_t thread)
|
||||
{
|
||||
CloseHandle(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t*)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_destroy(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_lock(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
EnterCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_unlock(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_init(pthread_cond_t* cond, pthread_condattr_t*)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitializeConditionVariable(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_destroy(pthread_cond_t*)
|
||||
{
|
||||
/* Windows does not have a destroy for conditionals */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD timespec_to_ms(const timespec* abstime)
|
||||
{
|
||||
if (abstime == NULL) {
|
||||
return INFINITE;
|
||||
}
|
||||
|
||||
DWORD t = (DWORD) (((abstime->tv_sec - time(0)) * 1000) + (abstime->tv_nsec / 1000000));
|
||||
|
||||
return t < 0 ? 1 : t;
|
||||
}
|
||||
|
||||
int32 pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime)
|
||||
{
|
||||
if (cond == NULL || mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!SleepConditionVariableCS(cond, mutex, timespec_to_ms(abstime))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
|
||||
{
|
||||
if (cond == NULL || mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return pthread_cond_timedwait(cond, mutex, NULL);
|
||||
}
|
||||
|
||||
int32 pthread_cond_signal(pthread_cond_t* cond)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
WakeConditionVariable(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_broadcast(pthread_cond_t* cond)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
WakeAllConditionVariable(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t*)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitializeSRWLock(&rwlock->lock);
|
||||
rwlock->exclusive = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_destroy(pthread_rwlock_t*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
AcquireSRWLockShared(&rwlock->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return !TryAcquireSRWLockShared(&rwlock->lock);
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&rwlock->lock);
|
||||
rwlock->exclusive = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOLEAN ret = TryAcquireSRWLockExclusive(&rwlock->lock);
|
||||
if (ret) {
|
||||
rwlock->exclusive = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rwlock->exclusive) {
|
||||
rwlock->exclusive = false;
|
||||
ReleaseSRWLockExclusive(&rwlock->lock);
|
||||
} else {
|
||||
ReleaseSRWLockShared(&rwlock->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 pcthread_get_num_procs()
|
||||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
#define pthread_exit(a) {return (a);}
|
||||
#else
|
||||
uint32 pcthread_get_num_procs()
|
||||
{
|
||||
return (uint32) sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
|
|
@ -21,6 +22,7 @@
|
|||
#include "../../utils/Utils.h"
|
||||
#include "../../utils/TestUtils.h"
|
||||
#include "../../memory/RingMemory.h"
|
||||
#include "../../log/Debug.cpp"
|
||||
|
||||
#define strtok_r strtok_s
|
||||
|
||||
|
|
@ -60,9 +62,36 @@ time_t system_time()
|
|||
return ((time_t) (largeInt.QuadPart / 10000000ULL)) - ((time_t) 11644473600ULL);
|
||||
}
|
||||
|
||||
// doesn't return clock time, only to return time since program start
|
||||
// -> can be used for profiling
|
||||
inline
|
||||
uint64 time_mu()
|
||||
{
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter(&counter);
|
||||
|
||||
return (counter.QuadPart * 1000000) / debug_container->performance_count_frequency;
|
||||
}
|
||||
|
||||
inline
|
||||
time_t unix_epoch_s()
|
||||
{
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
ULARGE_INTEGER li;
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
li.HighPart = ft.dwHighDateTime;
|
||||
|
||||
time_t seconds_since_epoch = (li.QuadPart - 116444736000000000ULL) / 10000000ULL;
|
||||
|
||||
return seconds_since_epoch;
|
||||
}
|
||||
|
||||
// @todo Consider to implement directly mapped files (CreateFileMapping) for certain files (e.g. map data or texture data, ...)
|
||||
|
||||
inline void relative_to_absolute(const char* rel, char* path)
|
||||
inline
|
||||
void relative_to_absolute(const char* rel, char* path)
|
||||
{
|
||||
char self_path[MAX_PATH];
|
||||
int32 self_path_length = GetModuleFileNameA(NULL, self_path, MAX_PATH);
|
||||
|
|
@ -130,21 +159,6 @@ file_size(const char* path)
|
|||
return size.QuadPart;
|
||||
}
|
||||
|
||||
inline
|
||||
uint64 time_mu()
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
LARGE_INTEGER counter;
|
||||
|
||||
if (!QueryPerformanceFrequency(&frequency)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
QueryPerformanceCounter(&counter);
|
||||
|
||||
return (counter.QuadPart * 1000000) / frequency.QuadPart;
|
||||
}
|
||||
|
||||
inline
|
||||
bool file_exists(const char* path)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "../../../audio/AudioSetting.h"
|
||||
#include "../../../utils/MathUtils.h"
|
||||
#include "../../../log/Log.h"
|
||||
#include "../../../audio/Audio.cpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#pragma comment(lib, "hid.lib")
|
||||
#pragma comment(lib, "setupapi.lib")
|
||||
|
||||
void hid_init_contorllers(Input* __restrict states, int32 state_count, RingMemory* ring) {
|
||||
void hid_init_controllers(Input* __restrict states, int32 state_count, RingMemory* ring) {
|
||||
|
||||
HANDLE* controller_handles = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@
|
|||
#include "../../../input/ControllerInput.h"
|
||||
#include "controller/DualShock4.h"
|
||||
#include "../../../utils/TestUtils.h"
|
||||
#include "../../../utils/MathUtils.h"
|
||||
#include "../../../memory/RingMemory.h"
|
||||
#include "../../../memory/BufferMemory.h"
|
||||
#include "../../../stdlib/simd/SIMD_I8.h"
|
||||
#include <winDNS.h>
|
||||
|
||||
#define INPUT_MOUSE_BUTTON_1 1
|
||||
|
|
@ -32,7 +29,7 @@
|
|||
#define INPUT_MOUSE_BUTTON_HWHEEL 7
|
||||
|
||||
// IMPORTANT:
|
||||
// Even if it is nowhere documented (at least not to our knowledge) the GetRawInputDeviceInfoA, GetRawInputBuffer functions requried
|
||||
// Even if it is nowhere documented (at least not to our knowledge) the GetRawInputDeviceInfoA, GetRawInputBuffer functions required
|
||||
// aligned memory. So far we only figured out that 4 bytes works, maybe this needs to be 8 in the future?!
|
||||
|
||||
int rawinput_init_mousekeyboard(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
||||
|
|
@ -110,7 +107,7 @@ int rawinput_init_mousekeyboard(HWND hwnd, Input* __restrict states, RingMemory*
|
|||
return i;
|
||||
}
|
||||
|
||||
// WARNING: While this works we highly recommend to use hid_init_contorllers
|
||||
// WARNING: While this works we highly recommend to use hid_init_controllers
|
||||
int rawinput_init_controllers(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
||||
{
|
||||
uint32 device_count;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include <XInput.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "../../../input/Input.h"
|
||||
#include "../../../input/ControllerInput.h"
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "../../../utils/MathUtils.h"
|
||||
|
|
|
|||
|
|
@ -6,28 +6,11 @@
|
|||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREAD_DEFINES_H
|
||||
#define TOS_PLATFORM_WIN32_THREAD_DEFINES_H
|
||||
#ifndef TOS_PLATFORM_WIN32_THREADING_ATOMIC_H
|
||||
#define TOS_PLATFORM_WIN32_THREADING_ATOMIC_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
|
||||
typedef DWORD (WINAPI *ThreadJobFunc)(void*);
|
||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||
typedef void pthread_mutexattr_t;
|
||||
typedef void pthread_condattr_t;
|
||||
typedef void pthread_rwlockattr_t;
|
||||
typedef HANDLE pthread_t;
|
||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||
|
||||
struct pthread_rwlock_t {
|
||||
SRWLOCK lock;
|
||||
bool exclusive;
|
||||
};
|
||||
|
||||
#define THREAD_RETURN DWORD WINAPI
|
||||
#include "../../../stdlib/Types.h"
|
||||
|
||||
inline
|
||||
void atomic_set(volatile int32* value, int32 new_value)
|
||||
37
platform/win32/threading/Semaphore.h
Normal file
37
platform/win32/threading/Semaphore.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREADING_SEMAPHORE_H
|
||||
#define TOS_PLATFORM_WIN32_THREADING_SEMAPHORE_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../stdlib/Types.h"
|
||||
|
||||
typedef HANDLE sem_t;
|
||||
|
||||
void sem_init(sem_t* semaphore, int32 value)
|
||||
{
|
||||
*semaphore = CreateSemaphore(NULL, value, MAX_INT32, NULL);
|
||||
}
|
||||
|
||||
void sem_destroy(sem_t* semaphore)
|
||||
{
|
||||
CloseHandle(*semaphore);
|
||||
}
|
||||
|
||||
// decrement if != 0, if = 0 wait
|
||||
void sem_wait(sem_t* semaphore) {
|
||||
WaitForSingleObject(*semaphore, INFINITE);
|
||||
}
|
||||
|
||||
// increment
|
||||
void sem_post(sem_t* semaphore) {
|
||||
ReleaseSemaphore(*semaphore, 1, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
26
platform/win32/threading/Spinlock.h
Normal file
26
platform/win32/threading/Spinlock.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREADING_SPINLOCK_H
|
||||
#define TOS_PLATFORM_WIN32_THREADING_SPINLOCK_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef volatile long spinlock32;
|
||||
|
||||
inline
|
||||
void spinlock_start(spinlock32* lock) {
|
||||
while (InterlockedExchange(lock, 1) == 1) {}
|
||||
}
|
||||
|
||||
inline
|
||||
void spinlock_end(spinlock32* lock) {
|
||||
InterlockedExchange(lock, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
253
platform/win32/threading/Thread.h
Normal file
253
platform/win32/threading/Thread.h
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREADING_THREAD_H
|
||||
#define TOS_PLATFORM_WIN32_THREADING_THREAD_H
|
||||
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "../UtilsWin32.h"
|
||||
#include "ThreadDefines.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
int32 pthread_create(pthread_t* thread, void*, ThreadJobFunc start_routine, void* arg)
|
||||
{
|
||||
if (thread == NULL || start_routine == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
*thread = CreateThread(NULL, 0, start_routine, arg, 0, NULL);
|
||||
if (*thread == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_join(pthread_t thread, void**)
|
||||
{
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_detach(pthread_t thread)
|
||||
{
|
||||
CloseHandle(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t*)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_destroy(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_lock(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
EnterCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_mutex_unlock(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_init(pthread_cond_t* cond, pthread_condattr_t*)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitializeConditionVariable(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_destroy(pthread_cond_t*)
|
||||
{
|
||||
/* Windows does not have a destroy for conditionals */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD timespec_to_ms(const timespec* abstime)
|
||||
{
|
||||
if (abstime == NULL) {
|
||||
return INFINITE;
|
||||
}
|
||||
|
||||
time_t seconds_since_epoch = unix_epoch_s();
|
||||
DWORD t = (DWORD) (((abstime->tv_sec - seconds_since_epoch) * 1000) + (abstime->tv_nsec / 1000000));
|
||||
|
||||
return t < 0 ? 1 : t;
|
||||
}
|
||||
|
||||
int32 pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime)
|
||||
{
|
||||
if (cond == NULL || mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!SleepConditionVariableCS(cond, mutex, timespec_to_ms(abstime))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
|
||||
{
|
||||
if (cond == NULL || mutex == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return pthread_cond_timedwait(cond, mutex, NULL);
|
||||
}
|
||||
|
||||
int32 pthread_cond_signal(pthread_cond_t* cond)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
WakeConditionVariable(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_cond_broadcast(pthread_cond_t* cond)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
WakeAllConditionVariable(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t*)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitializeSRWLock(&rwlock->lock);
|
||||
rwlock->exclusive = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_destroy(pthread_rwlock_t*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
AcquireSRWLockShared(&rwlock->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return !TryAcquireSRWLockShared(&rwlock->lock);
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&rwlock->lock);
|
||||
rwlock->exclusive = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOLEAN ret = TryAcquireSRWLockExclusive(&rwlock->lock);
|
||||
if (ret) {
|
||||
rwlock->exclusive = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rwlock->exclusive) {
|
||||
rwlock->exclusive = false;
|
||||
ReleaseSRWLockExclusive(&rwlock->lock);
|
||||
} else {
|
||||
ReleaseSRWLockShared(&rwlock->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 pcthread_get_num_procs()
|
||||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
#define pthread_exit(a) {return (a);}
|
||||
|
||||
#endif
|
||||
30
platform/win32/threading/ThreadDefines.h
Normal file
30
platform/win32/threading/ThreadDefines.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREADING_THREAD_DEFINES_H
|
||||
#define TOS_PLATFORM_WIN32_THREADING_THREAD_DEFINES_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef DWORD (WINAPI *ThreadJobFunc)(void*);
|
||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||
typedef void pthread_mutexattr_t;
|
||||
typedef void pthread_condattr_t;
|
||||
typedef void pthread_rwlockattr_t;
|
||||
typedef HANDLE pthread_t;
|
||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||
|
||||
struct pthread_rwlock_t {
|
||||
SRWLOCK lock;
|
||||
bool exclusive;
|
||||
};
|
||||
|
||||
#define THREAD_RETURN DWORD WINAPI
|
||||
|
||||
#endif
|
||||
|
|
@ -9,11 +9,11 @@
|
|||
#ifndef TOS_STDLIB_HASHMAP_H
|
||||
#define TOS_STDLIB_HASHMAP_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "../hash/GeneralHash.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
#include "../memory/BufferMemory.h"
|
||||
#include "../memory/ChunkMemory.h"
|
||||
#include "Types.h"
|
||||
#include "../utils/StringUtils.h"
|
||||
|
||||
#define MAX_KEY_LENGTH 32
|
||||
|
|
@ -406,7 +406,7 @@ int64 hashmap_dump(const HashMap* hm, byte* data)
|
|||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(hm->buf.count);
|
||||
data += sizeof(uint64);
|
||||
|
||||
// Dump the table content where the elements are relative indeces/pointers
|
||||
// Dump the table content where the elements are relative indices/pointers
|
||||
for (int32 i = 0; i < hm->buf.count; ++i) {
|
||||
*((uint64 *) data) = hm->table[i]
|
||||
? SWAP_ENDIAN_LITTLE((uintptr_t) hm->table[i] - (uintptr_t) hm->buf.memory)
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@
|
|||
#include "../stdlib/Types.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/ThreadDefines.h"
|
||||
#include "../platform/win32/Thread.h"
|
||||
#include "../platform/win32/threading/Thread.h"
|
||||
#include "../platform/win32/threading/Atomic.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/ThreadDefines.h"
|
||||
#include "../platform/linux/Thread.h"
|
||||
#include "../platform/linux/threading/Thread.h"
|
||||
#include "../platform/linux/threading/Atomic.h"
|
||||
#endif
|
||||
|
||||
#include "ThreadJob.h"
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
#include "../stdlib/Types.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/ThreadDefines.h"
|
||||
#include "../platform/win32/threading/ThreadDefines.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/ThreadDefines.h"
|
||||
#include "../platform/linux/threading/ThreadDefines.h"
|
||||
#endif
|
||||
|
||||
struct PoolWorker {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
#include "../stdlib/Types.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../platform/win32/Thread.h"
|
||||
#include "../platform/win32/threading/Thread.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Thread.h"
|
||||
#include "../platform/linux/threading/Thread.h"
|
||||
#endif
|
||||
|
||||
#include "ThreadJob.h"
|
||||
|
|
|
|||
24
ui/UITheme.h
24
ui/UITheme.h
|
|
@ -105,7 +105,7 @@ int compare_by_attribute_id(const void* a, const void* b) {
|
|||
// attributes ...
|
||||
// attributes ...
|
||||
|
||||
// WARNING: theme needs to have memory already reserved and asigned to data
|
||||
// WARNING: theme needs to have memory already reserved and assigned to data
|
||||
void theme_from_file_txt(
|
||||
UIThemeStyle* theme,
|
||||
byte* data
|
||||
|
|
@ -127,7 +127,7 @@ void theme_from_file_txt(
|
|||
int32 temp_group_count = 0;
|
||||
while (*pos != '\0') {
|
||||
// Skip all white spaces
|
||||
char_skip_empty(&pos);
|
||||
str_skip_empty(&pos);
|
||||
|
||||
// Is group name
|
||||
if (*pos == '#' || *pos == '.') {
|
||||
|
|
@ -135,7 +135,7 @@ void theme_from_file_txt(
|
|||
}
|
||||
|
||||
// Go to the end of the line
|
||||
char_move_to(&pos, '\n');
|
||||
str_move_to(&pos, '\n');
|
||||
|
||||
// Go to next line
|
||||
if (*pos != '\0') {
|
||||
|
|
@ -154,7 +154,7 @@ void theme_from_file_txt(
|
|||
pos += 8; // move past version
|
||||
|
||||
while (*pos != '\0') {
|
||||
char_skip_empty(&pos);
|
||||
str_skip_empty(&pos);
|
||||
|
||||
if (*pos == '\n') {
|
||||
++pos;
|
||||
|
|
@ -173,7 +173,7 @@ void theme_from_file_txt(
|
|||
last_token_newline = false;
|
||||
|
||||
if (!block_open) {
|
||||
char_copy_move_until(&pos, block_name, " \n", sizeof(" \n") - 1);
|
||||
str_copy_move_until(&pos, block_name, " \n", sizeof(" \n") - 1);
|
||||
|
||||
// All blocks need to start with #. In the past this wasn't the case and may not be in the future. This is why we keep this if here.
|
||||
if (*block_name == '#' || *block_name == '.') {
|
||||
|
|
@ -198,10 +198,10 @@ void theme_from_file_txt(
|
|||
continue;
|
||||
}
|
||||
|
||||
char_copy_move_until(&pos, attribute_name, " :\n", sizeof(" :\n") - 1);
|
||||
str_copy_move_until(&pos, attribute_name, " :\n", sizeof(" :\n") - 1);
|
||||
|
||||
// Skip any white spaces or other delimeters
|
||||
char_skip_list(&pos, " \t:", sizeof(" \t:") - 1);
|
||||
str_skip_list(&pos, " \t:", sizeof(" \t:") - 1);
|
||||
|
||||
ASSERT_SIMPLE((*pos != '\0' && *pos != '\n'));
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ void theme_from_file_txt(
|
|||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TYPE;
|
||||
|
||||
char str[32];
|
||||
char_copy_move_until(&pos, str, '\n');
|
||||
str_copy_move_until(&pos, str, '\n');
|
||||
|
||||
for (int32 j = 0; j < UI_ELEMENT_TYPE_SIZE; ++j) {
|
||||
if (strcmp(str, ui_element_type_to_string_const((UIElementType) j)) == 0) {
|
||||
|
|
@ -225,7 +225,7 @@ void theme_from_file_txt(
|
|||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_STYLE), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_STYLE;
|
||||
|
||||
char_copy_move_until(&pos, attribute.value_str, '\n');
|
||||
str_copy_move_until(&pos, attribute.value_str, '\n');
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_FONT_COLOR), attribute_name) == 0) {
|
||||
++pos; // Skip '#'
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ void theme_from_file_txt(
|
|||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG;
|
||||
|
||||
char_copy_move_until(&pos, attribute.value_str, '\n');
|
||||
str_copy_move_until(&pos, attribute.value_str, '\n');
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY;
|
||||
attribute.value_float = SWAP_ENDIAN_LITTLE(strtof(pos, &pos));
|
||||
|
|
@ -354,7 +354,7 @@ void theme_from_file_txt(
|
|||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_DURATION;
|
||||
attribute.value_float = strtof(pos, &pos);
|
||||
} else {
|
||||
char_move_to(&pos, '\n');
|
||||
str_move_to(&pos, '\n');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -372,7 +372,7 @@ void theme_from_file_txt(
|
|||
++temp_group->attribute_size;
|
||||
}
|
||||
|
||||
char_move_to(&pos, '\n');
|
||||
str_move_to(&pos, '\n');
|
||||
}
|
||||
|
||||
// We still need to sort the last group
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_UTILS_FAST_PIPES_H
|
||||
#define TOS_UTILS_FAST_PIPES_H
|
||||
|
||||
// requires kernel32.lib and user32.lib
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int ENABLE_FAST_PIPES()
|
||||
{
|
||||
int32 result = 0;
|
||||
|
||||
wchar_t pipe_name[32];
|
||||
wsprintfW(pipe_name, L"\\\\.\\pipe\\fastpipe%x", GetCurrentProcessId());
|
||||
HANDLE fast_pip = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||
|
||||
if(fast_pip != INVALID_HANDLE_VALUE) {
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, fast_pip);
|
||||
SetStdHandle(STD_INPUT_HANDLE, fast_pip);
|
||||
|
||||
int32 std_out = _open_osfhandle((intptr_t) fast_pip, O_WRONLY | O_TEXT);
|
||||
int32 std_in = _open_osfhandle((intptr_t) fast_pip, O_RDONLY | O_TEXT);
|
||||
|
||||
_dup2(std_out, _fileno(stdout));
|
||||
_dup2(std_in, _fileno(stdin));
|
||||
|
||||
_close(std_out);
|
||||
_close(std_in);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
#define ENABLE_FAST_PIPES(...) 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -12,12 +12,6 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#if ARM
|
||||
#include "../stdlib/IntrinsicsArm.h"
|
||||
#else
|
||||
#include "../stdlib/Intrinsics.h"
|
||||
#endif
|
||||
|
||||
#define OMS_PI 3.14159265358979323846f
|
||||
#define OMS_PI_OVER_TWO (OMS_PI / 2.0f)
|
||||
#define OMS_PI_OVER_FOUR (OMS_PI / 4.0f)
|
||||
|
|
@ -25,7 +19,7 @@
|
|||
|
||||
#define OMS_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define OMS_MIN(a, b) ((a) > (b) ? (b) : (a))
|
||||
#define OMS_CLAMP(a, b, c) (OMS_MAX(OMS_MIN((a), (b))), (c))
|
||||
#define OMS_CLAMP(a, b, c) (OMS_MAX(OMS_MIN((a), (b)), (c)))
|
||||
#define OMS_ABS(a) ((a) > 0 ? (a) : -(a))
|
||||
#define OMS_DEG2RAD(angle) ((angle) * OMS_PI / 180.0f)
|
||||
#define OMS_RAD2DEG(angle) ((angle) * 180.0f / OMS_PI)
|
||||
|
|
|
|||
|
|
@ -136,12 +136,12 @@ int32 utf8_get_char_at(const char* in, int32 index) {
|
|||
inline
|
||||
void wchar_to_char(wchar_t* str)
|
||||
{
|
||||
char *src = (char*) str;
|
||||
char *dest = (char *) src;
|
||||
char* src = (char*) str;
|
||||
char* dest = src;
|
||||
|
||||
while (*src != '\0' && src[1] != '\0') {
|
||||
if (*src != '\0') {
|
||||
*dest++ = (char) *src;
|
||||
*dest++ = *src;
|
||||
}
|
||||
|
||||
++src;
|
||||
|
|
@ -151,16 +151,14 @@ void wchar_to_char(wchar_t* str)
|
|||
}
|
||||
|
||||
inline
|
||||
void wchar_to_char(const char* str, char* __restrict dest)
|
||||
void wchar_to_char(const char* __restrict str, char* __restrict dest)
|
||||
{
|
||||
char *src = (char*) str;
|
||||
|
||||
while (*src != '\0' && src[1] != '\0') {
|
||||
if (*src != '\0') {
|
||||
*dest++ = (char) *src;
|
||||
while (*str != '\0' && str[1] != '\0') {
|
||||
if (*str != '\0') {
|
||||
*dest++ = (char) *str;
|
||||
}
|
||||
|
||||
++src;
|
||||
++str;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
|
@ -189,8 +187,8 @@ int32 str_to_int(const char *str)
|
|||
inline constexpr
|
||||
int32 int_to_str(int64 number, char *str, const char thousands = ',') {
|
||||
int32 i = 0;
|
||||
int64 sign = number;
|
||||
int32 digit_count = 0;
|
||||
int64 sign = number;
|
||||
|
||||
if (number == 0) {
|
||||
str[i++] = '0';
|
||||
|
|
@ -243,7 +241,8 @@ size_t str_count(const char* __restrict str, const char* __restrict substr)
|
|||
return count;
|
||||
}
|
||||
|
||||
inline char* strsep(const char* *sp, const char* sep)
|
||||
inline
|
||||
char* strsep(const char** sp, const char* sep)
|
||||
{
|
||||
char* p, *s;
|
||||
|
||||
|
|
@ -251,7 +250,7 @@ inline char* strsep(const char* *sp, const char* sep)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
s = (char* ) *sp;
|
||||
s = (char *) *sp;
|
||||
p = s + strcspn(s, sep);
|
||||
|
||||
if (*p != '\0') {
|
||||
|
|
@ -431,8 +430,7 @@ void str_replace(const char* str, const char* __restrict search, const char* __r
|
|||
memcpy(result_ptr, replace, replace_len);
|
||||
result_ptr += replace_len;
|
||||
|
||||
current += search_len;
|
||||
str = current;
|
||||
str = current + search_len;
|
||||
}
|
||||
|
||||
strcpy(result_ptr, str);
|
||||
|
|
@ -476,7 +474,7 @@ bool is_whitespace(char str)
|
|||
}
|
||||
|
||||
inline
|
||||
int32 chars_to_eol(const char* str)
|
||||
int32 str_to_eol(const char* str)
|
||||
{
|
||||
int32 offset = 0;
|
||||
while (!is_eol(str) && *str++ != '\0') {
|
||||
|
|
@ -487,7 +485,7 @@ int32 chars_to_eol(const char* str)
|
|||
}
|
||||
|
||||
inline
|
||||
int32 chars_to(const char* str, char delim)
|
||||
int32 str_to(const char* str, char delim)
|
||||
{
|
||||
int32 offset = 0;
|
||||
while (*str != delim && *str++ != '\0') {
|
||||
|
|
@ -498,7 +496,7 @@ int32 chars_to(const char* str, char delim)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_move_to(char** str, const char delim)
|
||||
void str_move_to(char** str, char delim)
|
||||
{
|
||||
while (**str != delim && **str != '\0') {
|
||||
++(*str);
|
||||
|
|
@ -506,7 +504,7 @@ void char_move_to(char** str, const char delim)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_move_past(char** str, const char delim)
|
||||
void str_move_past(char** str, char delim)
|
||||
{
|
||||
while (**str != delim && **str != '\0') {
|
||||
++(*str);
|
||||
|
|
@ -518,7 +516,7 @@ void char_move_past(char** str, const char delim)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_move_past_alpha_num(char** str)
|
||||
void str_move_past_alpha_num(char** str)
|
||||
{
|
||||
while ((**str >= 48 && **str <= 57)
|
||||
|| (**str >= 65 && **str <= 90)
|
||||
|
|
@ -536,7 +534,7 @@ bool str_is_comment(char* str)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_skip(char** str, const char delim)
|
||||
void str_skip(char** str, char delim)
|
||||
{
|
||||
while (**str == delim) {
|
||||
++(*str);
|
||||
|
|
@ -544,7 +542,7 @@ void char_skip(char** str, const char delim)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_skip_whitespace(char** str)
|
||||
void str_skip_whitespace(char** str)
|
||||
{
|
||||
while (**str == ' ' || **str == '\t') {
|
||||
++(*str);
|
||||
|
|
@ -552,7 +550,7 @@ void char_skip_whitespace(char** str)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_skip_empty(char** str)
|
||||
void str_skip_empty(char** str)
|
||||
{
|
||||
while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\r') {
|
||||
++(*str);
|
||||
|
|
@ -560,7 +558,7 @@ void char_skip_empty(char** str)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_skip_non_empty(char** str)
|
||||
void str_skip_non_empty(char** str)
|
||||
{
|
||||
while (**str != ' ' && **str != '\t' && **str != '\n' && **str != '\0') {
|
||||
++(*str);
|
||||
|
|
@ -568,7 +566,7 @@ void char_skip_non_empty(char** str)
|
|||
}
|
||||
|
||||
inline
|
||||
void char_skip_list(char** __restrict str, const char* __restrict delim, int32 len)
|
||||
void str_skip_list(char** __restrict str, const char* __restrict delim, int32 len)
|
||||
{
|
||||
bool run = true;
|
||||
while (run && **str != '\0') {
|
||||
|
|
@ -586,7 +584,7 @@ void char_skip_list(char** __restrict str, const char* __restrict delim, int32 l
|
|||
}
|
||||
|
||||
inline
|
||||
void char_skip_until_list(char** __restrict str, const char* __restrict delim, int32 len)
|
||||
void str_skip_until_list(char** __restrict str, const char* __restrict delim, int32 len)
|
||||
{
|
||||
while (**str != '\0') {
|
||||
for (int32 i = 0; i < len; ++i) {
|
||||
|
|
@ -600,7 +598,7 @@ void char_skip_until_list(char** __restrict str, const char* __restrict delim, i
|
|||
}
|
||||
|
||||
inline
|
||||
void char_copy_until(const char* __restrict src, char* __restrict dest, char delim)
|
||||
void str_copy_until(const char* __restrict src, char* __restrict dest, char delim)
|
||||
{
|
||||
while (*src != delim && *src != '\0') {
|
||||
*dest++ = *src++;
|
||||
|
|
@ -610,7 +608,7 @@ void char_copy_until(const char* __restrict src, char* __restrict dest, char del
|
|||
}
|
||||
|
||||
inline
|
||||
void char_copy_until(const char* __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
|
||||
void str_copy_until(const char* __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
|
||||
{
|
||||
while (*src != '\0') {
|
||||
for (int32 i = 0; i < len; ++i) {
|
||||
|
|
@ -627,9 +625,37 @@ void char_copy_until(const char* __restrict src, char* __restrict dest, const ch
|
|||
}
|
||||
|
||||
inline
|
||||
void char_copy_move_until(char** __restrict src, char* __restrict dest, char delim)
|
||||
int32 str_copy_until(char* __restrict dest, const char* __restrict src, char delim)
|
||||
{
|
||||
while (**src != delim) {
|
||||
int32 len = 0;
|
||||
while (*src != delim && *src != '\0') {
|
||||
*dest++ = *src++;
|
||||
++len;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
inline
|
||||
int32 str_copy(char* __restrict dest, const char* __restrict src, char delim)
|
||||
{
|
||||
int32 len = 0;
|
||||
while (*src != delim) {
|
||||
*dest++ = *src++;
|
||||
++len;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
inline
|
||||
void str_copy_move_until(char** __restrict src, char* __restrict dest, char delim)
|
||||
{
|
||||
while (**src != delim && **src != '\0') {
|
||||
*dest++ = **src;
|
||||
++(*src);
|
||||
}
|
||||
|
|
@ -638,7 +664,7 @@ void char_copy_move_until(char** __restrict src, char* __restrict dest, char del
|
|||
}
|
||||
|
||||
inline
|
||||
void char_copy_move_until(char** __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
|
||||
void str_copy_move_until(char** __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
|
||||
{
|
||||
while (**src != '\0') {
|
||||
for (int32 i = 0; i < len; ++i) {
|
||||
|
|
@ -655,8 +681,6 @@ void char_copy_move_until(char** __restrict src, char* __restrict dest, const ch
|
|||
*dest = '\0';
|
||||
}
|
||||
|
||||
// @question Do we really need this, isn't char_copy_move_until better?
|
||||
// Maybe create a copy_move_until_eol
|
||||
inline
|
||||
int32 strcpy_to_eol(const char* src, char* dst)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_UTILS_SYSTEM_UTILS_H
|
||||
#define TOS_UTILS_SYSTEM_UTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#endif
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
#define TOS_UTILS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user