libclod
C library for interacting with NBTs, region files, LOD data and other things.
Loading...
Searching...
No Matches
thread.c
1#include <assert.h>
2#include <string.h>
3
4#include "clod_thread_config.h"
5#include <clod/thread.h>
6
7#include "thread_impl.h"
8
9enum clod_process_result
10clod_process_start(struct clod_process_opts *opts, clod_process *process_out) {
11 struct clod_process_common **common = (struct clod_process_common**)process_out;
12
13 #if CLOD_HAVE_PTHREAD
14 if (opts->type == CLOD_THREAD) {
15 auto res = clod_process_start_pthread(opts, common);
16 if (res == CLOD_PROCESS_OK && common) (*common)->type = CLOD_THREAD;
17 return res;
18 }
19 #elif CLOD_HAVE_STDTHREADS
20 if (opts->type == CLOD_THREAD) {
21 auto res = clod_process_start_stdthreads(opts, common);
22 if (res == CLOD_PROCESS_OK && common) (*common)->type = CLOD_THREAD;
23 return res;
24 }
25 #endif
26
27 #if CLOD_HAVE_LINUX_SCHED
28 if (opts->type == CLOD_DAEMON || opts->type == CLOD_THREAD_BACKGROUND) {
29 auto res = clod_process_start_linux(opts, common);
30 if (res == CLOD_PROCESS_OK && common) (*common)->type = opts->type;
31 return res;
32 }
33 #endif
34
35 return CLOD_PROCESS_UNSUPPORTED;
36}
37
38enum clod_process_result
39clod_process_join(const clod_process process) {
40 struct clod_process_common *common = (struct clod_process_common*)process;
41
42 #if CLOD_HAVE_PTHREAD
43 if (common->type == CLOD_THREAD)
44 return clod_process_join_pthread(common);
45 #elif CLOD_HAVE_STDTHREADS
46 if (common->type == CLOD_THREAD)
47 return clod_process_join_stdthreads(common);
48 #endif
49
50 #if CLOD_HAVE_LINUX_SCHED
51 if (common->type == CLOD_DAEMON || common->type == CLOD_THREAD_BACKGROUND)
52 return clod_process_join_linux(common);
53 #endif
54
55 return CLOD_PROCESS_INVALID;
56}
57
58size_t args_size(const struct clod_process_args *args) {
59 const size_t head_size = sizeof(struct clod_process_args);
60 const size_t sizes_size = sizeof(args->arg_sizes[0]) * (size_t)args->arg_count;
61 const size_t vector_size = sizeof(args->arg_vector[0]) * ((size_t)args->arg_count + 1);
62
63 const size_t sizes_offset = ALIGN(head_size, alignof(typeof(args->arg_sizes[0])));
64 const size_t vector_offset = ALIGN(sizes_offset + sizes_size, alignof(typeof(args->arg_vector[0])));
65 const size_t arg_offset = ALIGN(vector_offset + vector_size, 16);
66
67 size_t size = arg_offset;
68 for (int i = 0; i < args->arg_count; i++) {
69 if (args->arg_vector[i] == nullptr)
70 continue;
71
72 if (args->arg_sizes) {
73 size += ALIGN(args->arg_sizes[i] + 1, 16);
74 } else {
75 size += ALIGN(strlen(args->arg_vector[i]) + 1, 16);
76 }
77 }
78
79 assert(size % 16 == 0);
80 return size;
81}
82void args_copy(struct clod_process_args *dst, const struct clod_process_args *src) {
83 assert((uintptr_t)dst % 16 == 0);
84
85 const size_t head_size = sizeof(struct clod_process_args);
86 const size_t sizes_size = sizeof(src->arg_sizes[0]) * (size_t)src->arg_count;
87 const size_t vector_size = sizeof(src->arg_vector[0]) * ((size_t)src->arg_count + 1);
88
89 const size_t sizes_offset = ALIGN(head_size, alignof(typeof(src->arg_sizes[0])));
90 const size_t vector_offset = ALIGN(sizes_offset + sizes_size, alignof(typeof(src->arg_vector[0])));
91 const size_t arg_offset = ALIGN(vector_offset + vector_size, 16);
92
93 dst->arg_count = src->arg_count;
94 dst->arg_sizes = (size_t*)((char*)dst + sizes_offset);
95 dst->arg_vector = (char**)((char*)dst + vector_offset);
96
97 size_t size = arg_offset;
98 for (int i = 0; i < src->arg_count; i++) {
99 size_t arg_size;
100 if (src->arg_sizes)
101 arg_size = src->arg_sizes[i];
102 else if (src->arg_vector[i])
103 arg_size = strlen(src->arg_vector[i]);
104 else
105 arg_size = 0;
106
107 dst->arg_sizes[i] = arg_size;
108 if (src->arg_vector[i]) {
109 dst->arg_vector[i] = (char*)dst + size;
110 memcpy(dst->arg_vector[i], src->arg_vector[i], arg_size);
111 dst->arg_vector[i][arg_size] = '\0';
112 size += ALIGN(arg_size + 1, 16);
113 } else {
114 dst->arg_vector[i] = nullptr;
115 }
116 }
117
118 if (!src->arg_vector)
119 dst->arg_vector = nullptr;
120 else
121 dst->arg_vector[src->arg_count] = nullptr;
122}
enum clod_process_result clod_process_join(const clod_process process)
Definition thread.c:39
enum clod_process_result clod_process_start(struct clod_process_opts *opts, clod_process *process_out)
Definition thread.c:10
@ CLOD_THREAD_BACKGROUND
Definition thread.h:44
@ CLOD_THREAD
Definition thread.h:32
@ CLOD_DAEMON
Definition thread.h:63
Sized string helpers.
enum clod_process_type type
Type of process to create.
Definition thread.h:77