forked from amir/filehasher
Making the MPMC queue support when producers are consumers at the same time by adding a variable work, mpmc_push_work() that increments work and mpmc_task_done() that decrements work, and if work = 0 calls mpmc_producers_finished() that pushes poinsons to wake up sleeping threads and make them return NULL Replacing DirQueue, a queue growable with realloc with the MPMC queue
72 lines
1.9 KiB
C
72 lines
1.9 KiB
C
#pragma once // ensure that a given header file is included only once in a
|
|
// single compilation unit
|
|
|
|
#include "arena.h"
|
|
#include "base.h"
|
|
#include "lf_mpmc.h"
|
|
|
|
#include "arena.c"
|
|
|
|
#define XXH_VECTOR \
|
|
XXH_AVX2 // not recommanded to compile with gcc see xxhash.h line 4082
|
|
// Must compile with /arch:AVX2 in clang-cl or -mavx2 in clang/gcc
|
|
#define XXH_INLINE_ALL
|
|
#include "xxhash.c"
|
|
#include "xxhash.h"
|
|
|
|
// ----------------------------- Config -------------------------------------
|
|
#define FILE_HASHES_TXT "file_hashes.txt"
|
|
#define HASH_STRLEN 33 // 128-bit hex (32 chars) + null
|
|
#define MAX_PATHLEN 4096
|
|
#define READ_BLOCK (64 * 1024) // 64KB blocks
|
|
|
|
// ----------------------------- Data types ---------------------------------
|
|
typedef struct FileEntry {
|
|
char *path;
|
|
|
|
uint64_t size_bytes;
|
|
uint64_t created_time; // epoch
|
|
uint64_t modified_time; // epoch seconds
|
|
char owner[128]; // resolved owner name
|
|
} FileEntry;
|
|
|
|
void platform_get_file_times(const char *path, uint64_t *out_created,
|
|
uint64_t *out_modified);
|
|
void platform_get_file_owner(const char *path, char *out_owner,
|
|
size_t out_owner_size);
|
|
|
|
/* scan folder timer*/
|
|
typedef struct {
|
|
LARGE_INTEGER start;
|
|
LARGE_INTEGER end;
|
|
} HiResTimer;
|
|
|
|
static LARGE_INTEGER g_qpc_freq;
|
|
|
|
static void timer_init(void) { QueryPerformanceFrequency(&g_qpc_freq); }
|
|
|
|
static void timer_start(HiResTimer *t) { QueryPerformanceCounter(&t->start); }
|
|
|
|
static double timer_stop(HiResTimer *t) {
|
|
QueryPerformanceCounter(&t->end);
|
|
return (double)(t->end.QuadPart - t->start.QuadPart) /
|
|
(double)g_qpc_freq.QuadPart;
|
|
}
|
|
|
|
// Workers context
|
|
|
|
typedef struct {
|
|
u8 num_threads;
|
|
|
|
mem_arena *path_arena;
|
|
mem_arena *meta_arena;
|
|
|
|
MPMCQueue *dir_queue;
|
|
MPMCQueue *file_queue;
|
|
} ScannerContext;
|
|
|
|
typedef struct {
|
|
mem_arena *arena;
|
|
MPMCQueue *file_queue;
|
|
} WorkerContext;
|