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

Side by Side Diff: src/trusted/service_runtime/win/thread_suspension.c

Issue 11543028: Allow creating a NaClAppThread without creating a new host OS thread (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Review: Add NACL_WUR Created 8 years 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 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 <windows.h> 7 #include <windows.h>
8 8
9 #include "native_client/src/shared/platform/nacl_check.h" 9 #include "native_client/src/shared/platform/nacl_check.h"
10 #include "native_client/src/shared/platform/nacl_sync_checked.h" 10 #include "native_client/src/shared/platform/nacl_sync_checked.h"
11 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" 11 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
12 #include "native_client/src/trusted/service_runtime/sel_ldr.h" 12 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
13 #include "native_client/src/trusted/service_runtime/thread_suspension.h" 13 #include "native_client/src/trusted/service_runtime/thread_suspension.h"
14 14
15 15
16 struct NaClAppThreadSuspendedRegisters { 16 struct NaClAppThreadSuspendedRegisters {
17 CONTEXT context; 17 CONTEXT context;
18 }; 18 };
19 19
20 static HANDLE GetHostThreadHandle(struct NaClAppThread *natp) {
21 CHECK(natp->host_thread_is_defined);
22 return natp->host_thread.tid;
23 }
24
20 void NaClAppThreadSetSuspendState(struct NaClAppThread *natp, 25 void NaClAppThreadSetSuspendState(struct NaClAppThread *natp,
21 enum NaClSuspendState old_state, 26 enum NaClSuspendState old_state,
22 enum NaClSuspendState new_state) { 27 enum NaClSuspendState new_state) {
23 /* 28 /*
24 * Claiming suspend_mu here blocks a trusted/untrusted context 29 * Claiming suspend_mu here blocks a trusted/untrusted context
25 * switch while the thread is suspended or a suspension is in 30 * switch while the thread is suspended or a suspension is in
26 * progress. 31 * progress.
27 */ 32 */
28 NaClXMutexLock(&natp->suspend_mu); 33 NaClXMutexLock(&natp->suspend_mu);
29 DCHECK(natp->suspend_state == old_state); 34 DCHECK(natp->suspend_state == old_state);
30 natp->suspend_state = new_state; 35 natp->suspend_state = new_state;
31 NaClXMutexUnlock(&natp->suspend_mu); 36 NaClXMutexUnlock(&natp->suspend_mu);
32 } 37 }
33 38
34 void NaClUntrustedThreadSuspend(struct NaClAppThread *natp, 39 void NaClUntrustedThreadSuspend(struct NaClAppThread *natp,
35 int save_registers) { 40 int save_registers) {
36 /* 41 /*
37 * We claim suspend_mu here to block trusted/untrusted context 42 * We claim suspend_mu here to block trusted/untrusted context
38 * switches by blocking NaClAppThreadSetSuspendState(). This blocks 43 * switches by blocking NaClAppThreadSetSuspendState(). This blocks
39 * any untrusted->trusted context switch that might happen before 44 * any untrusted->trusted context switch that might happen before
40 * SuspendThread() takes effect. It blocks any trusted->untrusted 45 * SuspendThread() takes effect. It blocks any trusted->untrusted
41 * context switch that might happen if the syscall running in the 46 * context switch that might happen if the syscall running in the
42 * target thread returns. 47 * target thread returns.
43 */ 48 */
44 NaClXMutexLock(&natp->suspend_mu); 49 NaClXMutexLock(&natp->suspend_mu);
45 if (natp->suspend_state == NACL_APP_THREAD_UNTRUSTED) { 50 if (natp->suspend_state == NACL_APP_THREAD_UNTRUSTED) {
46 CONTEXT temp_context; 51 CONTEXT temp_context;
47 CONTEXT *context; 52 CONTEXT *context;
53 HANDLE thread_handle = GetHostThreadHandle(natp);
48 54
49 if (SuspendThread(natp->thread.tid) == (DWORD) -1) { 55 if (SuspendThread(thread_handle) == (DWORD) -1) {
50 NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: " 56 NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: "
51 "SuspendThread() call failed\n"); 57 "SuspendThread() call failed\n");
52 } 58 }
53 59
54 if (save_registers) { 60 if (save_registers) {
55 if (natp->suspended_registers == NULL) { 61 if (natp->suspended_registers == NULL) {
56 natp->suspended_registers = malloc(sizeof(*natp->suspended_registers)); 62 natp->suspended_registers = malloc(sizeof(*natp->suspended_registers));
57 if (natp->suspended_registers == NULL) { 63 if (natp->suspended_registers == NULL) {
58 NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: malloc() failed\n"); 64 NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: malloc() failed\n");
59 } 65 }
(...skipping 12 matching lines...) Expand all
72 * able to return a snapshot of the register state once the 78 * able to return a snapshot of the register state once the
73 * thread has actually suspended. 79 * thread has actually suspended.
74 * 80 *
75 * If save_registers=0, the set of registers we request via 81 * If save_registers=0, the set of registers we request via
76 * ContextFlags is unimportant as long as it is non-empty. 82 * ContextFlags is unimportant as long as it is non-empty.
77 */ 83 */
78 context = &temp_context; 84 context = &temp_context;
79 context->ContextFlags = CONTEXT_CONTROL; 85 context->ContextFlags = CONTEXT_CONTROL;
80 } 86 }
81 87
82 if (!GetThreadContext(natp->thread.tid, context)) { 88 if (!GetThreadContext(thread_handle, context)) {
83 NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: " 89 NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: "
84 "GetThreadContext() failed\n"); 90 "GetThreadContext() failed\n");
85 } 91 }
86 } 92 }
87 /* 93 /*
88 * We leave suspend_mu held so that NaClAppThreadSetSuspendState() 94 * We leave suspend_mu held so that NaClAppThreadSetSuspendState()
89 * will block. 95 * will block.
90 */ 96 */
91 } 97 }
92 98
93 void NaClUntrustedThreadResume(struct NaClAppThread *natp) { 99 void NaClUntrustedThreadResume(struct NaClAppThread *natp) {
94 if (natp->suspend_state == NACL_APP_THREAD_UNTRUSTED) { 100 if (natp->suspend_state == NACL_APP_THREAD_UNTRUSTED) {
95 if (ResumeThread(natp->thread.tid) == (DWORD) -1) { 101 if (ResumeThread(GetHostThreadHandle(natp)) == (DWORD) -1) {
96 NaClLog(LOG_FATAL, "NaClUntrustedThreadResume: " 102 NaClLog(LOG_FATAL, "NaClUntrustedThreadResume: "
97 "ResumeThread() call failed\n"); 103 "ResumeThread() call failed\n");
98 } 104 }
99 } 105 }
100 NaClXMutexUnlock(&natp->suspend_mu); 106 NaClXMutexUnlock(&natp->suspend_mu);
101 } 107 }
102 108
103 void NaClAppThreadGetSuspendedRegistersInternal( 109 void NaClAppThreadGetSuspendedRegistersInternal(
104 struct NaClAppThread *natp, struct NaClSignalContext *regs) { 110 struct NaClAppThread *natp, struct NaClSignalContext *regs) {
105 NaClSignalContextFromHandler(regs, natp->suspended_registers); 111 NaClSignalContextFromHandler(regs, natp->suspended_registers);
106 } 112 }
107 113
108 void NaClAppThreadSetSuspendedRegistersInternal( 114 void NaClAppThreadSetSuspendedRegistersInternal(
109 struct NaClAppThread *natp, const struct NaClSignalContext *regs) { 115 struct NaClAppThread *natp, const struct NaClSignalContext *regs) {
110 NaClSignalContextToHandler(natp->suspended_registers, regs); 116 NaClSignalContextToHandler(natp->suspended_registers, regs);
111 if (!SetThreadContext(natp->thread.tid, 117 if (!SetThreadContext(GetHostThreadHandle(natp),
112 &natp->suspended_registers->context)) { 118 &natp->suspended_registers->context)) {
113 NaClLog(LOG_FATAL, "NaClAppThreadSetSuspendedRegistersInternal: " 119 NaClLog(LOG_FATAL, "NaClAppThreadSetSuspendedRegistersInternal: "
114 "SetThreadContext() failed\n"); 120 "SetThreadContext() failed\n");
115 } 121 }
116 } 122 }
117 123
118 int NaClAppThreadUnblockIfFaulted(struct NaClAppThread *natp, int *signal) { 124 int NaClAppThreadUnblockIfFaulted(struct NaClAppThread *natp, int *signal) {
119 DWORD previous_suspend_count; 125 DWORD previous_suspend_count;
120 126
121 if (natp->fault_signal == 0) { 127 if (natp->fault_signal == 0) {
122 return 0; 128 return 0;
123 } 129 }
124 *signal = natp->fault_signal; 130 *signal = natp->fault_signal;
125 natp->fault_signal = 0; 131 natp->fault_signal = 0;
126 AtomicIncrement(&natp->nap->faulted_thread_count, -1); 132 AtomicIncrement(&natp->nap->faulted_thread_count, -1);
127 /* 133 /*
128 * Decrement Windows' suspension count for the thread. This undoes 134 * Decrement Windows' suspension count for the thread. This undoes
129 * the effect of debug_exception_handler.c's SuspendThread() call. 135 * the effect of debug_exception_handler.c's SuspendThread() call.
130 */ 136 */
131 previous_suspend_count = ResumeThread(natp->thread.tid); 137 previous_suspend_count = ResumeThread(GetHostThreadHandle(natp));
132 if (previous_suspend_count == (DWORD) -1) { 138 if (previous_suspend_count == (DWORD) -1) {
133 NaClLog(LOG_FATAL, "NaClAppThreadUnblockIfFaulted: " 139 NaClLog(LOG_FATAL, "NaClAppThreadUnblockIfFaulted: "
134 "ResumeThread() call failed\n"); 140 "ResumeThread() call failed\n");
135 } 141 }
136 /* 142 /*
137 * This thread should already have been suspended using 143 * This thread should already have been suspended using
138 * NaClUntrustedThreadSuspend(), so the thread will not actually 144 * NaClUntrustedThreadSuspend(), so the thread will not actually
139 * resume until NaClUntrustedThreadResume() is called. 145 * resume until NaClUntrustedThreadResume() is called.
140 */ 146 */
141 DCHECK(previous_suspend_count >= 2); 147 DCHECK(previous_suspend_count >= 2);
142 return 1; 148 return 1;
143 } 149 }
OLDNEW
« no previous file with comments | « src/trusted/service_runtime/thread_suspension_test.cc ('k') | tests/minnacl/minimal_test_host.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698