diff options
Diffstat (limited to 'include/os/posix/thread.c')
-rw-r--r-- | include/os/posix/thread.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/include/os/posix/thread.c b/include/os/posix/thread.c new file mode 100644 index 0000000..6fdce13 --- /dev/null +++ b/include/os/posix/thread.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | * DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #include <nvgpu/bug.h> | ||
24 | #include <nvgpu/thread.h> | ||
25 | |||
26 | #include <nvgpu/posix/thread.h> | ||
27 | |||
28 | /** | ||
29 | * Use pthreads to mostly emulate the Linux kernel APIs. There are some things | ||
30 | * that are quite different - especially the stop/should_stop notions. In user | ||
31 | * space threads can send signals to one another but of course within the kernel | ||
32 | * that is not as simple. | ||
33 | * | ||
34 | * This could use some nice debugging some day as well. | ||
35 | */ | ||
36 | |||
37 | /* | ||
38 | * nvgpu thread functions return int. POSIX threads return void *. This little | ||
39 | * wrapper takes the int returning nvgpu thread and instead passes that int back | ||
40 | * through the void * pointer. | ||
41 | */ | ||
42 | static void *__nvgpu_posix_thread_wrapper(void *data) | ||
43 | { | ||
44 | struct nvgpu_posix_thread_data *nvgpu = data; | ||
45 | |||
46 | return ERR_PTR(nvgpu->fn(nvgpu->data)); | ||
47 | } | ||
48 | |||
49 | int nvgpu_thread_create(struct nvgpu_thread *thread, | ||
50 | void *data, | ||
51 | int (*threadfn)(void *data), const char *name) | ||
52 | { | ||
53 | int ret; | ||
54 | |||
55 | BUG_ON(thread->running); | ||
56 | |||
57 | memset(thread, 0, sizeof(*thread)); | ||
58 | |||
59 | /* | ||
60 | * By subtracting 1 the above memset ensures that we have a zero | ||
61 | * terminated string. | ||
62 | */ | ||
63 | strncpy(thread->tname, name, NVGPU_THREAD_POSIX_MAX_NAMELEN - 1); | ||
64 | |||
65 | thread->nvgpu.data = data; | ||
66 | thread->nvgpu.fn = threadfn; | ||
67 | |||
68 | ret = pthread_create(&thread->thread, NULL, | ||
69 | __nvgpu_posix_thread_wrapper, | ||
70 | &thread->nvgpu); | ||
71 | if (ret != 0) | ||
72 | return ret; | ||
73 | |||
74 | #ifdef _GNU_SOURCE | ||
75 | pthread_setname_np(thread->thread, thread->tname); | ||
76 | #endif | ||
77 | |||
78 | thread->running = true; | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | void nvgpu_thread_stop(struct nvgpu_thread *thread) | ||
84 | { | ||
85 | thread->should_stop = true; | ||
86 | } | ||
87 | |||
88 | bool nvgpu_thread_should_stop(struct nvgpu_thread *thread) | ||
89 | { | ||
90 | return thread->should_stop; | ||
91 | } | ||
92 | |||
93 | bool nvgpu_thread_is_running(struct nvgpu_thread *thread) | ||
94 | { | ||
95 | return thread->running; | ||
96 | } | ||
97 | |||
98 | void nvgpu_thread_join(struct nvgpu_thread *thread) | ||
99 | { | ||
100 | (void) pthread_join(thread->thread, NULL); | ||
101 | } | ||