Update gb.h
This commit is contained in:
parent
84afc68e05
commit
15647e5a0b
|
@ -4,7 +4,7 @@ gb single-file public domain libraries for C & C++
|
|||
|
||||
library | latest version | category | description
|
||||
----------------|----------------|----------|-------------
|
||||
**gb.h** | 0.26d | misc | Helper library (Standard library _improvement_)
|
||||
**gb.h** | 0.27 | misc | Helper library (Standard library _improvement_)
|
||||
**gb_math.h** | 0.07c | math | Vector math library geared towards game development
|
||||
**gb_gl.h** | 0.05 | graphics | OpenGL Helper Library
|
||||
**gb_string.h** | 0.95a | strings | A better string library (this is built into gb.h too with custom allocator support!)
|
||||
|
|
148
gb.h
148
gb.h
|
@ -1,4 +1,4 @@
|
|||
/* gb.h - v0.26d - Ginger Bill's C Helper Library - public domain
|
||||
/* gb.h - v0.27 - Ginger Bill's C Helper Library - public domain
|
||||
- no warranty implied; use at your own risk
|
||||
|
||||
This is a single header file with a bunch of useful stuff
|
||||
|
@ -58,6 +58,7 @@ TODOS
|
|||
- More date & time functions
|
||||
|
||||
VERSION HISTORY
|
||||
0.27 - OSX fixes and Linux gbAffinity
|
||||
0.26d - Minor changes to how gbFile works
|
||||
0.26c - gb_str_to_f* fix
|
||||
0.26b - Minor fixes
|
||||
|
@ -276,6 +277,8 @@ extern "C" {
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#if !defined(GB_NO_WINDOWS_H)
|
||||
#define NOMINMAX 1
|
||||
|
@ -296,6 +299,9 @@ extern "C" {
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#ifndef _IOSC11_SOURCE
|
||||
#define _IOSC11_SOURCE
|
||||
#endif
|
||||
#include <stdlib.h> // NOTE(bill): malloc on linux
|
||||
#include <sys/mman.h>
|
||||
#if !defined(GB_SYSTEM_OSX)
|
||||
|
@ -309,18 +315,18 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <copyfile.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <copyfile.h>
|
||||
#include <mach/clock.h>
|
||||
#endif
|
||||
|
||||
#if defined(GB_SYSTEM_UNIX)
|
||||
#include <semaphore.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -412,21 +418,20 @@ typedef i32 Rune; // NOTE(bill): Unicode codepoint
|
|||
#define GB_RUNE_EOF cast(Rune)(-1)
|
||||
|
||||
|
||||
// NOTE(bill): I think C99 and C++ `bool` is stupid for numerous reasons but there are too many
|
||||
// to write in this small comment.
|
||||
typedef i8 b8;
|
||||
typedef i16 b16;
|
||||
typedef i32 b32; // NOTE(bill): Prefer this!!!
|
||||
|
||||
// NOTE(bill): Get true and false
|
||||
#if !defined(__cplusplus)
|
||||
#if (defined(_MSC_VER) && _MSC_VER <= 1800) || !defined(__STDC_VERSION__)
|
||||
#if (defined(_MSC_VER) && _MSC_VER <= 1800) || (!defined(_MSC_VER) && !defined(__STDC_VERSION__))
|
||||
#ifndef true
|
||||
#define true (0 == 0)
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false (0 != 0)
|
||||
#endif
|
||||
typedef b8 bool;
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
@ -615,7 +620,7 @@ extern "C++" {
|
|||
//
|
||||
// NOTE: C++11 (and above) only!
|
||||
//
|
||||
#if defined(__cplusplus) && ((defined(_MSC_VER) && _MSC_VER >= 1400) || (__cplusplus >= 201103L))
|
||||
#if !defined(GB_NO_DEFER) && defined(__cplusplus) && ((defined(_MSC_VER) && _MSC_VER >= 1400) || (__cplusplus >= 201103L))
|
||||
extern "C++" {
|
||||
// NOTE(bill): Stupid fucking templates
|
||||
template <typename T> struct gbRemoveReference { typedef T Type; };
|
||||
|
@ -1004,7 +1009,12 @@ typedef struct gbAffinity {
|
|||
} gbAffinity;
|
||||
|
||||
#elif defined(GB_SYSTEM_LINUX)
|
||||
#error TODO(bill): Implement gbAffinity for linux
|
||||
typedef struct gbAffinity {
|
||||
b32 is_accurate;
|
||||
isize core_count;
|
||||
isize thread_count;
|
||||
isize threads_per_core;
|
||||
} gbAffinity;
|
||||
#else
|
||||
#error TODO(bill): Unknown system
|
||||
#endif
|
||||
|
@ -4113,7 +4123,7 @@ gb_inline i64 gb_atomic64_fetch_and(gbAtomic64 volatile *a, i64 operand) {
|
|||
|
||||
gb_inline i64 gb_atomic64_fetch_or(gbAtomic64 volatile *a, i64 operand) {
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
return _InterlockedAnd64(cast(i64 volatile *)a, operand);
|
||||
return _InterlockedOr64(cast(i64 volatile *)a, operand);
|
||||
#elif GB_CPU_X86
|
||||
i64 expected = a->value;
|
||||
for (;;) {
|
||||
|
@ -4820,18 +4830,15 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) {
|
|||
#else
|
||||
// TODO(bill): *nix version that's decent
|
||||
case gbAllocation_Alloc: {
|
||||
gbAllocationHeader *header;
|
||||
isize total_size = size + alignment + gb_size_of(gbAllocationHeader);
|
||||
ptr = malloc(total_size);
|
||||
header = cast(gbAllocationHeader *)ptr;
|
||||
ptr = gb_align_forward(header+1, alignment);
|
||||
gb_allocation_header_fill(header, ptr, size);
|
||||
if (flags & gbAllocatorFlag_ClearToZero)
|
||||
posix_memalign(&ptr, alignment, size);
|
||||
|
||||
if (flags & gbAllocatorFlag_ClearToZero) {
|
||||
gb_zero_size(ptr, size);
|
||||
}
|
||||
} break;
|
||||
|
||||
case gbAllocation_Free: {
|
||||
free(gb_allocation_header(old_memory));
|
||||
free(old_memory);
|
||||
} break;
|
||||
|
||||
case gbAllocation_Resize: {
|
||||
|
@ -4928,7 +4935,7 @@ isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
|
|||
void gb_affinity_init(gbAffinity *a) {
|
||||
usize count, count_size = gb_size_of(count);
|
||||
|
||||
a->is_accurate = false;
|
||||
a->is_accurate = false;
|
||||
a->thread_count = 1;
|
||||
a->core_count = 1;
|
||||
a->threads_per_core = 1;
|
||||
|
@ -4978,7 +4985,83 @@ isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
|
|||
}
|
||||
|
||||
#elif defined(GB_SYSTEM_LINUX)
|
||||
#error TODO(bill): Implement gbAffinity for linux
|
||||
// IMPORTANT TODO(bill): This gbAffinity stuff for linux needs be improved a lot!
|
||||
// NOTE(zangent): I have to read /proc/cpuinfo to get the number of threads per core.
|
||||
#include <stdio.h>
|
||||
|
||||
void gb_affinity_init(gbAffinity *a) {
|
||||
b32 accurate = true;
|
||||
isize threads = 0;
|
||||
|
||||
a->thread_count = 1;
|
||||
a->core_count = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
a->threads_per_core = 1;
|
||||
|
||||
|
||||
if(a->core_count <= 0) {
|
||||
a->core_count = 1;
|
||||
accurate = false;
|
||||
}
|
||||
|
||||
// Parsing /proc/cpuinfo to get the number of threads per core.
|
||||
// NOTE(zangent): This calls the CPU's threads "cores", although the wording
|
||||
// is kind of weird. This should be right, though.
|
||||
if (fopen("/proc/cpuinfo", "r") != NULL) {
|
||||
for (;;) {
|
||||
// The 'temporary char'. Everything goes into this char,
|
||||
// so that we can check against EOF at the end of this loop.
|
||||
char c;
|
||||
|
||||
#define AF__CHECK(letter) ((c = getc(cpu_info)) == letter)
|
||||
if (AF__CHECK('c') && AF__CHECK('p') && AF__CHECK('u') && AF__CHECK(' ') &&
|
||||
AF__CHECK('c') && AF__CHECK('o') && AF__CHECK('r') && AF__CHECK('e') && AF__CHECK('s')) {
|
||||
// We're on a CPU info line.
|
||||
while (!AF__CHECK(EOF)) {
|
||||
if (c == '\n') {
|
||||
break;
|
||||
} else if (c < '0' || '9' > c) {
|
||||
continue;
|
||||
}
|
||||
threads = threads * 10 + (c - '0');
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
while (!AF__CHECK('\n')) {
|
||||
if (c==EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c == EOF) {
|
||||
break;
|
||||
}
|
||||
#undef AF__CHECK
|
||||
}
|
||||
}
|
||||
|
||||
if (threads == 0) {
|
||||
threads = 1;
|
||||
accurate = false;
|
||||
}
|
||||
|
||||
a->threads_per_core = threads;
|
||||
a->thread_count = a->threads_per_core * a->core_count;
|
||||
a->is_accurate = accurate;
|
||||
|
||||
}
|
||||
|
||||
void gb_affinity_destroy(gbAffinity *a) {
|
||||
gb_unused(a);
|
||||
}
|
||||
|
||||
b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
|
||||
GB_ASSERT(0 <= core && core < a->core_count);
|
||||
return a->threads_per_core;
|
||||
}
|
||||
#else
|
||||
#error TODO(bill): Unknown system
|
||||
#endif
|
||||
|
@ -7759,7 +7842,18 @@ char *gb_path_get_full_name(gbAllocator a, char const *path) {
|
|||
return gb_alloc_str_len(a, buf, len+1);
|
||||
#else
|
||||
// TODO(bill): Make work on *nix, etc.
|
||||
return gb_alloc_str_len(a, path, gb_strlen(path));
|
||||
char* p = realpath(path, 0);
|
||||
GB_ASSERT(p && "file does not exist");
|
||||
|
||||
isize len = gb_strlen(p);
|
||||
|
||||
// bill... gb_alloc_str_len refused to work for this...
|
||||
char* ret = gb_alloc(a, sizeof(char) * len + 1);
|
||||
gb_memmove(ret, p, len);
|
||||
ret[len] = 0;
|
||||
free(p);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue