use arena everywhere + bunch of cool new stuff
This commit is contained in:
parent
8fdecd89a5
commit
ae59f269c2
51 changed files with 5443 additions and 7233 deletions
|
|
@ -4,8 +4,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h> // bool
|
||||
#include <string.h> // memset
|
||||
#include "collatypes.h"
|
||||
#include "tracelog.h" // fatal
|
||||
|
||||
// heavily inspired by https://gist.github.com/Enichan/5f01140530ff0133fde19c9549a2a973
|
||||
|
|
|
|||
204
deprecated/dir.c
Normal file
204
deprecated/dir.c
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
#include "dir.h"
|
||||
#include "tracelog.h"
|
||||
|
||||
#if COLLA_WIN
|
||||
#include "win32_slim.h"
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "strstream.h"
|
||||
|
||||
typedef struct {
|
||||
dir_entry_t cur;
|
||||
dir_entry_t next;
|
||||
HANDLE handle;
|
||||
} _dir_internal_t;
|
||||
|
||||
static dir_entry_t _fillDirEntry(WIN32_FIND_DATAW *data) {
|
||||
return (dir_entry_t) {
|
||||
.type =
|
||||
data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ?
|
||||
FS_TYPE_DIR : FS_TYPE_FILE,
|
||||
.name = strFromWChar(data->cFileName, 0)
|
||||
};
|
||||
}
|
||||
|
||||
static _dir_internal_t _getFirst(const wchar_t *path) {
|
||||
_dir_internal_t res = {0};
|
||||
WIN32_FIND_DATAW data = {0};
|
||||
|
||||
res.handle = FindFirstFileW(path, &data);
|
||||
|
||||
if(res.handle != INVALID_HANDLE_VALUE) {
|
||||
res.next = _fillDirEntry(&data);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _getNext(_dir_internal_t *ctx) {
|
||||
WIN32_FIND_DATAW data = {0};
|
||||
|
||||
BOOL result = FindNextFileW(ctx->handle, &data);
|
||||
if(!result) {
|
||||
if(GetLastError() == ERROR_NO_MORE_FILES) {
|
||||
FindClose(ctx->handle);
|
||||
ctx->handle = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx->next = _fillDirEntry(&data);
|
||||
}
|
||||
|
||||
dir_t dirOpen(const char *path) {
|
||||
DWORD n = GetFullPathName(path, 0, NULL, NULL);
|
||||
outstream_t out = ostrInitLen(n + 3);
|
||||
n = GetFullPathName(path, n, out.buf, NULL);
|
||||
assert(n > 0);
|
||||
out.len += n;
|
||||
switch(ostrBack(out)) {
|
||||
case '\\':
|
||||
case '/':
|
||||
case ':':
|
||||
// directory ends in path separator
|
||||
// NOP
|
||||
break;
|
||||
default:
|
||||
ostrPutc(&out, '\\');
|
||||
}
|
||||
ostrPutc(&out, '*');
|
||||
|
||||
_dir_internal_t *dir = malloc(sizeof(_dir_internal_t));
|
||||
if(dir) {
|
||||
wchar_t *wpath = strToWCHAR(ostrAsStr(out));
|
||||
assert(wpath);
|
||||
*dir = _getFirst(wpath);
|
||||
free(wpath);
|
||||
}
|
||||
ostrFree(out);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
void dirClose(dir_t ctx) {
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
bool dirValid(dir_t ctx) {
|
||||
_dir_internal_t *dir = (_dir_internal_t*)ctx;
|
||||
return dir->handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
dir_entry_t *dirNext(dir_t ctx) {
|
||||
_dir_internal_t *dir = (_dir_internal_t*)ctx;
|
||||
strFree(dir->cur.name);
|
||||
if(!dir->handle) return NULL;
|
||||
dir->cur = dir->next;
|
||||
_getNext(dir);
|
||||
return &dir->cur;
|
||||
}
|
||||
|
||||
void dirCreate(const char *path) {
|
||||
CreateDirectoryA(path, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// taken from https://sites.uclouvain.be/SystInfo/usr/include/dirent.h.html
|
||||
// hopefully shouldn't be needed
|
||||
#ifndef DT_DIR
|
||||
#define DT_DIR 4
|
||||
#endif
|
||||
#ifndef DT_REG
|
||||
#define DT_REG 8
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
DIR *dir;
|
||||
dir_entry_t next;
|
||||
} _dir_internal_t;
|
||||
|
||||
dir_t dirOpen(const char *path) {
|
||||
_dir_internal_t *ctx = (_dir_internal_t *)calloc(1, sizeof(_dir_internal_t));
|
||||
if(ctx) ctx->dir = opendir(path);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void dirClose(dir_t ctx) {
|
||||
if(ctx) {
|
||||
_dir_internal_t *in = (_dir_internal_t *)ctx;
|
||||
closedir(in->dir);
|
||||
free(in);
|
||||
}
|
||||
}
|
||||
|
||||
bool dirValid(dir_t ctx) {
|
||||
_dir_internal_t *dir = (_dir_internal_t*)ctx;
|
||||
return dir->dir != NULL;
|
||||
}
|
||||
|
||||
dir_entry_t *dirNext(dir_t ctx) {
|
||||
if(!ctx) return NULL;
|
||||
_dir_internal_t *in = (_dir_internal_t *)ctx;
|
||||
strFree(in->next.name);
|
||||
struct dirent *dp = readdir(in->dir);
|
||||
if(!dp) return NULL;
|
||||
|
||||
switch(dp->d_type) {
|
||||
case DT_DIR: in->next.type = FS_TYPE_DIR; break;
|
||||
case DT_REG: in->next.type = FS_TYPE_FILE; break;
|
||||
default: in->next.type = FS_TYPE_UNKNOWN; break;
|
||||
}
|
||||
|
||||
in->next.name = strFromStr(dp->d_name);
|
||||
return &in->next;
|
||||
}
|
||||
|
||||
void dirCreate(const char *path) {
|
||||
mkdir(path, 0700);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
bool dirRemove(const char *path) {
|
||||
dir_t dir = dirOpen(path);
|
||||
if (!dirValid(dir)) return false;
|
||||
dir_entry_t *it = NULL;
|
||||
while((it = dirNext(dir))) {
|
||||
if (it->type == FS_TYPE_FILE) {
|
||||
str_t file_path = strFromFmt("%s/%s", path, it->name.buf);
|
||||
if (remove(file_path.buf)) {
|
||||
err("couldn't remove %s > %s", file_path.buf, strerror(errno));
|
||||
}
|
||||
strFree(file_path);
|
||||
}
|
||||
else if (it->type == FS_TYPE_DIR) {
|
||||
if (strcmp(it->name.buf, ".") == 0 || strcmp(it->name.buf, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
str_t new_path = strFromFmt("%s/%s", path, it->name.buf);
|
||||
info("new path: %s--%s -> %s", path, it->name.buf, new_path.buf);
|
||||
if (!dirRemove(new_path.buf)) {
|
||||
err("couldn't delete folder %s", new_path.buf);
|
||||
break;
|
||||
}
|
||||
strFree(new_path);
|
||||
}
|
||||
else {
|
||||
err("%d -> %s", it->type, it->name.buf);
|
||||
}
|
||||
}
|
||||
dirClose(dir);
|
||||
#if COLLA_WIN
|
||||
return RemoveDirectoryA(path);
|
||||
#else
|
||||
return rmdir(path) == 0;
|
||||
#endif
|
||||
}
|
||||
34
deprecated/dir.h
Normal file
34
deprecated/dir.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "str.h"
|
||||
|
||||
typedef void *dir_t;
|
||||
|
||||
typedef enum {
|
||||
FS_TYPE_UNKNOWN,
|
||||
FS_TYPE_FILE,
|
||||
FS_TYPE_DIR,
|
||||
} fs_type_t;
|
||||
|
||||
typedef struct {
|
||||
fs_type_t type;
|
||||
str_t name;
|
||||
} dir_entry_t;
|
||||
|
||||
dir_t dirOpen(const char *path);
|
||||
void dirClose(dir_t ctx);
|
||||
|
||||
bool dirValid(dir_t ctx);
|
||||
|
||||
dir_entry_t *dirNext(dir_t ctx);
|
||||
|
||||
void dirCreate(const char *path);
|
||||
bool dirRemove(const char *path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
#include <assert.h>
|
||||
#include "tracelog.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#if COLLA_WIN
|
||||
#include "win32_slim.h"
|
||||
#include "str.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
* }
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "collatypes.h"
|
||||
#include "cthreads.h"
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "tracelog.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#if COLLA_WIN
|
||||
#include "win32_slim.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "collatypes.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
|
|
|
|||
144
deprecated/jobpool.c
Normal file
144
deprecated/jobpool.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#include "jobpool.h"
|
||||
|
||||
#include "vec.h"
|
||||
|
||||
typedef struct {
|
||||
cthread_func_t func;
|
||||
void *arg;
|
||||
} job_t;
|
||||
|
||||
typedef struct {
|
||||
vec(job_t) jobs;
|
||||
uint32 head;
|
||||
cmutex_t work_mutex;
|
||||
condvar_t work_cond;
|
||||
condvar_t working_cond;
|
||||
int32 working_count;
|
||||
int32 thread_count;
|
||||
bool stop;
|
||||
} _pool_internal_t;
|
||||
|
||||
static job_t _getJob(_pool_internal_t *pool);
|
||||
static int _poolWorker(void *arg);
|
||||
|
||||
jobpool_t poolInit(uint32 num) {
|
||||
if (!num) num = 2;
|
||||
|
||||
_pool_internal_t *pool = malloc(sizeof(_pool_internal_t));
|
||||
*pool = (_pool_internal_t){
|
||||
.work_mutex = mtxInit(),
|
||||
.work_cond = condInit(),
|
||||
.working_cond = condInit(),
|
||||
.thread_count = (int32)num
|
||||
};
|
||||
|
||||
for (usize i = 0; i < num; ++i) {
|
||||
thrDetach(thrCreate(_poolWorker, pool));
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void poolFree(jobpool_t pool_in) {
|
||||
_pool_internal_t *pool = pool_in;
|
||||
if (!pool) return;
|
||||
|
||||
mtxLock(pool->work_mutex);
|
||||
pool->stop = true;
|
||||
condWakeAll(pool->work_cond);
|
||||
mtxUnlock(pool->work_mutex);
|
||||
|
||||
poolWait(pool);
|
||||
|
||||
vecFree(pool->jobs);
|
||||
mtxFree(pool->work_mutex);
|
||||
condFree(pool->work_cond);
|
||||
condFree(pool->working_cond);
|
||||
|
||||
free(pool);
|
||||
}
|
||||
|
||||
bool poolAdd(jobpool_t pool_in, cthread_func_t func, void *arg) {
|
||||
_pool_internal_t *pool = pool_in;
|
||||
if (!pool) return false;
|
||||
|
||||
mtxLock(pool->work_mutex);
|
||||
|
||||
if (pool->head > vecLen(pool->jobs)) {
|
||||
vecClear(pool->jobs);
|
||||
pool->head = 0;
|
||||
}
|
||||
|
||||
job_t job = { func, arg };
|
||||
vecAppend(pool->jobs, job);
|
||||
|
||||
condWake(pool->work_cond);
|
||||
mtxUnlock(pool->work_mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void poolWait(jobpool_t pool_in) {
|
||||
_pool_internal_t *pool = pool_in;
|
||||
if (!pool) return;
|
||||
|
||||
mtxLock(pool->work_mutex);
|
||||
// while its either
|
||||
// - working and there's still some threads doing some work
|
||||
// - not working and there's still some threads exiting
|
||||
while ((!pool->stop && pool->working_count > 0) ||
|
||||
(pool->stop && pool->thread_count > 0)
|
||||
) {
|
||||
condWait(pool->working_cond, pool->work_mutex);
|
||||
}
|
||||
mtxUnlock(pool->work_mutex);
|
||||
}
|
||||
|
||||
// == PRIVATE FUNCTIONS ===================================
|
||||
|
||||
static job_t _getJob(_pool_internal_t *pool) {
|
||||
if (pool->head >= vecLen(pool->jobs)) {
|
||||
pool->head = 0;
|
||||
}
|
||||
job_t job = pool->jobs[pool->head++];
|
||||
return job;
|
||||
}
|
||||
|
||||
static int _poolWorker(void *arg) {
|
||||
_pool_internal_t *pool = arg;
|
||||
|
||||
while (true) {
|
||||
mtxLock(pool->work_mutex);
|
||||
// wait for a new job
|
||||
while (pool->head >= vecLen(pool->jobs) && !pool->stop) {
|
||||
condWait(pool->work_cond, pool->work_mutex);
|
||||
}
|
||||
|
||||
if (pool->stop) {
|
||||
break;
|
||||
}
|
||||
|
||||
job_t job = _getJob(pool);
|
||||
pool->working_count++;
|
||||
mtxUnlock(pool->work_mutex);
|
||||
|
||||
if (job.func) {
|
||||
job.func(job.arg);
|
||||
}
|
||||
|
||||
mtxLock(pool->work_mutex);
|
||||
pool->working_count--;
|
||||
if (!pool->stop &&
|
||||
pool->working_count == 0 &&
|
||||
pool->head == vecLen(pool->jobs)
|
||||
) {
|
||||
condWake(pool->working_cond);
|
||||
}
|
||||
mtxUnlock(pool->work_mutex);
|
||||
}
|
||||
|
||||
pool->thread_count--;
|
||||
condWake(pool->working_cond);
|
||||
mtxUnlock(pool->work_mutex);
|
||||
return 0;
|
||||
}
|
||||
12
deprecated/jobpool.h
Normal file
12
deprecated/jobpool.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "collatypes.h"
|
||||
#include "cthreads.h"
|
||||
|
||||
typedef void *jobpool_t;
|
||||
|
||||
jobpool_t poolInit(uint32 num);
|
||||
void poolFree(jobpool_t pool);
|
||||
|
||||
bool poolAdd(jobpool_t pool, cthread_func_t func, void *arg);
|
||||
void poolWait(jobpool_t pool);
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if COLLA_WIN
|
||||
#define _BUFSZ 128
|
||||
|
||||
#include <lmcons.h>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ extern "C" {
|
|||
#include "str.h"
|
||||
#include "collatypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#if COLLA_WIN
|
||||
#include <stdio.h>
|
||||
#include "win32_slim.h"
|
||||
isize getdelim(char **buf, size_t *bufsz, int delimiter, FILE *fp);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue