libclod
C library for interacting with NBTs, region files, LOD data and other things.
Loading...
Searching...
No Matches
thread_stdthreads.c
1#include <stdio.h>
2
3#include "clod_thread_config.h"
4#include "thread_impl.h"
5#include <threads.h>
6#include <stdlib.h>
7
9 struct clod_process_common common;
10 thrd_t thrd;
11};
12
13struct thread_args {
14 clod_process_main *main;
15};
16
17int clod_process_stdthreads_main(void *ptr) {
18 struct thread_args *thread_args = ptr;
19 auto args = (struct clod_process_args *)((char*)ptr + ALIGN(sizeof(struct thread_args), 16));
20 thread_args->main(args->arg_count, args->arg_vector);
21 free(thread_args);
22 return 0;
23}
24
25enum clod_process_result clod_process_start_stdthreads(
26 struct clod_process_opts *opts,
27 struct clod_process_common **process_out
28) {
29 if (!opts->main) {
30 #if CLOD_DEBUG_THREAD
31 fprintf(stderr, "libclod: clod_process_start_pthread: no thread main function given.\n");
32 #endif
33 return CLOD_PROCESS_INVALID;
34 }
35 if (opts->type != CLOD_THREAD) {
36 #if CLOD_DEBUG_THREAD
37 fprintf(stderr, "libclod: clod_process_start_stdthreads: given %d, but only CLOD_THREAD (1) is supported here.\n", opts->type);
38 #endif
39 return CLOD_PROCESS_INVALID;
40 }
41
42 struct clod_process_args args_in = {
43 .arg_count = opts->arg_count,
44 .arg_sizes = opts->arg_sizes,
45 .arg_vector = opts->arg_vector
46 };
47
48 char *data = malloc(ALIGN(sizeof(struct thread_args), 16) + args_size(&args_in));
49 auto thread_args = (struct thread_args *)data;
50 auto args = (struct clod_process_args *)(data + ALIGN(sizeof(struct thread_args), 16));
51
52 thread_args->main = opts->main;
53 args_copy(args, &args_in);
54
55 thrd_t thrd;
56 const int res = thrd_create(&thrd, clod_process_stdthreads_main, data);
57 if (res != thrd_success) {
58 free(data);
59 #if CLOD_DEBUG_THREAD
60 fprintf(stderr, "libclod: pthread_create: %d\n", res);
61 #endif
62 if (res == thrd_nomem) return CLOD_PROCESS_NO_MEMORY;
63 return CLOD_PROCESS_INVALID;
64 }
65
66 if (process_out) {
67 struct clod_process_stdthreads *process = malloc(sizeof(struct clod_process_stdthreads));
68 process->common.type = CLOD_THREAD;
69 process->thrd = thrd;
70 *process_out = &process->common;
71 } else {
72 thrd_detach(thrd);
73 }
74
75 return CLOD_PROCESS_OK;
76}
77
78enum clod_process_result clod_process_join_stdthreads(struct clod_process_common *process) {
79 auto stdthreads_process = (struct clod_process_stdthreads*)process;
80 const int res = thrd_join(stdthreads_process->thrd, nullptr);
81 free(stdthreads_process);
82 if (res != thrd_success) return CLOD_PROCESS_INVALID;
83 return CLOD_PROCESS_OK;
84}
@ CLOD_THREAD
Definition thread.h:32
clod_process_main * main
Process entry point.
Definition thread.h:84
int arg_count
Number of arguments passed to main.
Definition thread.h:87
char ** arg_vector
Definition thread.h:91
size_t * arg_sizes
Definition thread.h:95
enum clod_process_type type
Type of process to create.
Definition thread.h:77