Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(392)

Side by Side Diff: src/nonsfi/linux/linux_pthread_private.c

Issue 1212613002: Non-SFI mode: Add Linux asynchronous signal support (Closed) Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
Patch Set: Disabled the async signal test for glibc Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 The Native Client Authors. All rights reserved. 2 * Copyright 2014 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include <assert.h> 7 #include <assert.h>
8 #include <errno.h> 8 #include <errno.h>
9 9
10 #include "native_client/src/nonsfi/linux/linux_pthread_private.h" 10 #include "native_client/src/nonsfi/linux/linux_pthread_private.h"
11 #include "native_client/src/nonsfi/linux/linux_syscall_defines.h" 11 #include "native_client/src/nonsfi/linux/linux_syscall_defines.h"
12 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" 12 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h"
13 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" 13 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h"
14 #include "native_client/src/nonsfi/linux/linux_sys_private.h" 14 #include "native_client/src/nonsfi/linux/linux_sys_private.h"
15 #include "native_client/src/public/linux_syscalls/sched.h" 15 #include "native_client/src/public/linux_syscalls/sched.h"
16 #include "native_client/src/public/linux_syscalls/sys/syscall.h" 16 #include "native_client/src/public/linux_syscalls/sys/syscall.h"
17 #include "native_client/src/untrusted/nacl/nacl_irt.h" 17 #include "native_client/src/untrusted/nacl/nacl_irt.h"
18 #include "native_client/src/untrusted/nacl/nacl_thread.h" 18 #include "native_client/src/untrusted/nacl/nacl_thread.h"
19 #include "native_client/src/untrusted/pthread/pthread_internal.h" 19 #include "native_client/src/untrusted/pthread/pthread_internal.h"
20 20
21 struct nacl_irt_thread_v0_2 __libnacl_irt_thread_v0_2;
Mark Seaborn 2015/08/12 01:43:07 I don't think you need this, or the assignment to
Luis Héctor Chávez 2015/08/12 22:14:26 Done.
22
21 /* Convert a return value of a Linux syscall to the one of an IRT call. */ 23 /* Convert a return value of a Linux syscall to the one of an IRT call. */
22 static uint32_t irt_return_call(uintptr_t result) { 24 static uint32_t irt_return_call(uintptr_t result) {
23 if (linux_is_error_result(result)) 25 if (linux_is_error_result(result))
24 return -result; 26 return -result;
25 return 0; 27 return 0;
26 } 28 }
27 29
28 static int nacl_irt_thread_create(void (*start_func)(void), void *stack, 30 static int nacl_irt_thread_create_v0_2(void (*start_func)(void), void *stack,
29 void *thread_ptr) { 31 void *thread_ptr,
32 nacl_irt_tid_t *child_tid) {
30 /* 33 /*
31 * We do not use CLONE_CHILD_CLEARTID as we do not want any 34 * We do not use CLONE_CHILD_CLEARTID as we do not want any
32 * non-private futex signaling. Also, NaCl ABI does not require us 35 * non-private futex signaling. Also, NaCl ABI does not require us
33 * to signal the futex on stack_flag. 36 * to signal the futex on stack_flag.
34 */ 37 */
35 int flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | 38 int flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
36 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS); 39 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS |
40 CLONE_PARENT_SETTID);
41 /*
42 * In order to avoid allowing clone with and without CLONE_PARENT_SETTID, if
43 * |child_tid| is NULL, we provide a valid pointer whose value will be
44 * ignored.
45 */
46 nacl_irt_tid_t ignored;
47 void *ptid = (child_tid != NULL) ? child_tid : &ignored;
48
37 /* 49 /*
38 * linux_clone_wrapper expects start_func's type is "int (*)(void *)". 50 * linux_clone_wrapper expects start_func's type is "int (*)(void *)".
39 * Although |start_func| has type "void (*)(void)", the type mismatching 51 * Although |start_func| has type "void (*)(void)", the type mismatching
40 * will not cause a problem. Passing a dummy |arg| (= 0) does nothing there. 52 * will not cause a problem. Passing a dummy |arg| (= 0) does nothing there.
41 * Also, start_func will never return. 53 * Also, start_func will never return.
42 */ 54 */
43 return irt_return_call(linux_clone_wrapper( 55 return irt_return_call(linux_clone_wrapper(
44 (uintptr_t) start_func, /* arg */ 0, flags, stack, 56 (uintptr_t) start_func, /* arg */ 0, flags, stack,
45 /* ptid */ NULL, thread_ptr, /* ctid */ NULL)); 57 ptid, thread_ptr, /* ctid */ NULL));
58 }
59
60 static int nacl_irt_thread_create(void (*start_func)(void), void *stack,
61 void *thread_ptr) {
62 nacl_irt_tid_t child_tid;
63 return nacl_irt_thread_create_v0_2(start_func, stack, thread_ptr, &child_tid);
46 } 64 }
47 65
48 static void nacl_irt_thread_exit(int32_t *stack_flag) { 66 static void nacl_irt_thread_exit(int32_t *stack_flag) {
49 /* 67 /*
50 * We fill zero to stack_flag by ourselves instead of relying 68 * We fill zero to stack_flag by ourselves instead of relying
51 * on CLONE_CHILD_CLEARTID. We do everything in the following inline 69 * on CLONE_CHILD_CLEARTID. We do everything in the following inline
52 * assembly because we need to make sure we will never touch stack. 70 * assembly because we need to make sure we will never touch stack.
53 * 71 *
54 * We will set the stack pointer to zero at the beginning of the 72 * We will set the stack pointer to zero at the beginning of the
55 * assembly code just in case an async signal arrives after setting 73 * assembly code just in case an async signal arrives after setting
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 * That should never return. Crash hard if it does. 131 * That should never return. Crash hard if it does.
114 */ 132 */
115 __builtin_trap(); 133 __builtin_trap();
116 } 134 }
117 135
118 /* 136 /*
119 * Creates a thread and initializes the IRT-private TLS area. 137 * Creates a thread and initializes the IRT-private TLS area.
120 * Based on code from src/untrusted/irt/irt_thread.c 138 * Based on code from src/untrusted/irt/irt_thread.c
121 */ 139 */
122 int nacl_user_thread_create(void *(*start_func)(void *), void *stack, 140 int nacl_user_thread_create(void *(*start_func)(void *), void *stack,
123 void *thread_ptr) { 141 void *thread_ptr, nacl_irt_tid_t *child_tid) {
124 struct nc_combined_tdb *tdb; 142 struct nc_combined_tdb *tdb;
125 143
126 /* 144 /*
127 * Before we start the thread, allocate the IRT-private TLS area for it. 145 * Before we start the thread, allocate the IRT-private TLS area for it.
128 */ 146 */
129 size_t combined_size = __nacl_tls_combined_size(sizeof(*tdb)); 147 size_t combined_size = __nacl_tls_combined_size(sizeof(*tdb));
130 void *combined_area = malloc(combined_size); 148 void *combined_area = malloc(combined_size);
131 if (combined_area == NULL) 149 if (combined_area == NULL)
132 return EAGAIN; 150 return EAGAIN;
133 151
134 /* 152 /*
135 * Note that __nacl_tls_initialize_memory() is not reversible, 153 * Note that __nacl_tls_initialize_memory() is not reversible,
136 * because it takes a pointer that need not be aligned and can 154 * because it takes a pointer that need not be aligned and can
137 * return a pointer that is aligned. In order to 155 * return a pointer that is aligned. In order to
138 * free(combined_area) later, we must save the value of 156 * free(combined_area) later, we must save the value of
139 * combined_area. 157 * combined_area.
140 */ 158 */
141 void *irt_tp = __nacl_tls_initialize_memory(combined_area, sizeof(*tdb)); 159 void *irt_tp = __nacl_tls_initialize_memory(combined_area, sizeof(*tdb));
142 tdb = get_irt_tdb(irt_tp); 160 tdb = get_irt_tdb(irt_tp);
143 __nc_initialize_unjoinable_thread(tdb); 161 __nc_initialize_unjoinable_thread(tdb);
144 tdb->tdb.irt_thread_data = combined_area; 162 tdb->tdb.irt_thread_data = combined_area;
145 tdb->tdb.start_func = start_func; 163 tdb->tdb.start_func = start_func;
146 tdb->tdb.state = thread_ptr; 164 tdb->tdb.state = thread_ptr;
147 165
148 return nacl_irt_thread_create(irt_start_thread, stack, irt_tp); 166 return nacl_irt_thread_create_v0_2(irt_start_thread, stack, irt_tp,
167 child_tid);
149 } 168 }
150 169
151 /* 170 /*
152 * Destroys a thread created by nacl_user_thread_create. 171 * Destroys a thread created by nacl_user_thread_create.
153 * Based on code from src/untrusted/irt/irt_thread.c 172 * Based on code from src/untrusted/irt/irt_thread.c
154 */ 173 */
155 void nacl_user_thread_exit(int32_t *stack_flag) { 174 void nacl_user_thread_exit(int32_t *stack_flag) {
156 struct nc_combined_tdb *tdb = get_irt_tdb(__nacl_read_tp()); 175 struct nc_combined_tdb *tdb = get_irt_tdb(__nacl_read_tp());
157 176
158 __nc_tsd_exit(); 177 __nc_tsd_exit();
(...skipping 10 matching lines...) Expand all
169 nacl_irt_thread_exit(stack_flag); 188 nacl_irt_thread_exit(stack_flag);
170 } 189 }
171 190
172 void __nc_initialize_interfaces(void) { 191 void __nc_initialize_interfaces(void) {
173 const struct nacl_irt_thread init = { 192 const struct nacl_irt_thread init = {
174 nacl_irt_thread_create, 193 nacl_irt_thread_create,
175 nacl_irt_thread_exit, 194 nacl_irt_thread_exit,
176 nacl_irt_thread_nice, 195 nacl_irt_thread_nice,
177 }; 196 };
178 __libnacl_irt_thread = init; 197 __libnacl_irt_thread = init;
198 const struct nacl_irt_thread_v0_2 init_v0_2 = {
199 nacl_irt_thread_create_v0_2,
200 nacl_irt_thread_exit,
201 nacl_irt_thread_nice,
202 };
203 __libnacl_irt_thread_v0_2 = init_v0_2;
179 } 204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698