| OLD | NEW |
| 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 <stdexcept> | 7 #include <stdexcept> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "native_client/src/shared/platform/nacl_log.h" | 10 #include "native_client/src/shared/platform/nacl_log.h" |
| 11 #include "native_client/src/trusted/gdb_rsp/abi.h" | 11 #include "native_client/src/trusted/gdb_rsp/abi.h" |
| 12 #include "native_client/src/trusted/port/mutex.h" | 12 #include "native_client/src/trusted/port/mutex.h" |
| 13 #include "native_client/src/trusted/port/platform.h" | 13 #include "native_client/src/trusted/port/platform.h" |
| 14 #include "native_client/src/trusted/port/thread.h" | 14 #include "native_client/src/trusted/port/thread.h" |
| 15 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" // only
for NaClAppThread->nap |
| 15 #include "native_client/src/trusted/service_runtime/nacl_signal.h" | 16 #include "native_client/src/trusted/service_runtime/nacl_signal.h" |
| 17 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
| 16 | 18 |
| 17 /* | 19 /* |
| 18 * Define the OS specific portions of IThread interface. | 20 * Define the OS specific portions of IThread interface. |
| 19 */ | 21 */ |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 const int kX86TrapFlag = 1 << 8; | 25 const int kX86TrapFlag = 1 << 8; |
| 24 | 26 |
| 25 } // namespace | 27 } // namespace |
| 26 | 28 |
| 27 namespace port { | 29 namespace port { |
| 28 | 30 |
| 29 static IThread::CatchFunc_t s_CatchFunc = NULL; | 31 static IThread::CatchFunc_t s_CatchFunc = NULL; |
| 30 static void* s_CatchCookie = NULL; | 32 static void* s_CatchCookie = NULL; |
| 31 | 33 |
| 32 static IMutex* ThreadGetLock() { | 34 static IMutex* ThreadGetLock() { |
| 33 static IMutex* mutex_ = IMutex::Allocate(); | 35 static IMutex* mutex_ = IMutex::Allocate(); |
| 34 return mutex_; | 36 return mutex_; |
| 35 } | 37 } |
| 36 | 38 |
| 37 static IThread::ThreadMap_t *ThreadGetMap() { | 39 static IThread::ThreadMap_t *ThreadGetMap() { |
| 38 static IThread::ThreadMap_t* map_ = new IThread::ThreadMap_t; | 40 static IThread::ThreadMap_t* map_ = new IThread::ThreadMap_t; |
| 39 return map_; | 41 return map_; |
| 40 } | 42 } |
| 41 | 43 |
| 44 volatile int signaled_ = 0; |
| 45 |
| 42 class Thread : public IThread { | 46 class Thread : public IThread { |
| 43 public: | 47 public: |
| 44 Thread(uint32_t id, struct NaClAppThread *natp) | 48 Thread(uint32_t id, struct NaClAppThread *natp) |
| 45 : ref_(1), id_(id), natp_(natp), state_(DEAD) {} | 49 : ref_(1), id_(id), natp_(natp), state_(DEAD) {} |
| 46 ~Thread() {} | 50 ~Thread() {} |
| 47 | 51 |
| 48 uint32_t GetId() { | 52 uint32_t GetId() { |
| 49 return id_; | 53 return id_; |
| 50 } | 54 } |
| 51 | 55 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 return false; | 100 return false; |
| 97 } | 101 } |
| 98 | 102 |
| 99 // This is not used and could be removed. | 103 // This is not used and could be removed. |
| 100 virtual void* GetContext() { return NULL; } | 104 virtual void* GetContext() { return NULL; } |
| 101 | 105 |
| 102 static enum NaClSignalResult SignalHandler(int signal, void *ucontext) { | 106 static enum NaClSignalResult SignalHandler(int signal, void *ucontext) { |
| 103 struct NaClSignalContext context; | 107 struct NaClSignalContext context; |
| 104 NaClSignalContextFromHandler(&context, ucontext); | 108 NaClSignalContextFromHandler(&context, ucontext); |
| 105 if (NaClSignalContextIsUntrusted(&context)) { | 109 if (NaClSignalContextIsUntrusted(&context)) { |
| 110 while (__sync_lock_test_and_set(&signaled_, 1)) { |
| 111 usleep(100); |
| 112 } |
| 106 uint32_t thread_id = IPlatform::GetCurrentThread(); | 113 uint32_t thread_id = IPlatform::GetCurrentThread(); |
| 107 Thread* thread = static_cast<Thread*>(Acquire(thread_id)); | 114 Thread* thread = static_cast<Thread*>(Acquire(thread_id)); |
| 108 State old_state = thread->state_; | 115 State old_state = thread->state_; |
| 109 thread->state_ = SIGNALED; | 116 thread->state_ = SIGNALED; |
| 110 thread->context_ = context; | 117 thread->context_ = context; |
| 111 | 118 |
| 112 if (s_CatchFunc != NULL) | 119 if (s_CatchFunc != NULL) |
| 113 s_CatchFunc(thread_id, signal, s_CatchCookie); | 120 s_CatchFunc(thread_id, signal, s_CatchCookie); |
| 114 | 121 |
| 115 NaClSignalContextToHandler(ucontext, &thread->context_); | 122 NaClSignalContextToHandler(ucontext, &thread->context_); |
| 116 thread->state_ = old_state; | 123 thread->state_ = old_state; |
| 117 Release(thread); | 124 Release(thread); |
| 125 __sync_lock_release(&signaled_); |
| 118 return NACL_SIGNAL_RETURN; | 126 return NACL_SIGNAL_RETURN; |
| 119 } else { | 127 } else { |
| 120 // Do not attempt to debug crashes in trusted code. | 128 // Do not attempt to debug crashes in trusted code. |
| 121 return NACL_SIGNAL_SEARCH; | 129 return NACL_SIGNAL_SEARCH; |
| 122 } | 130 } |
| 123 } | 131 } |
| 124 | 132 |
| 125 private: | 133 private: |
| 126 uint32_t ref_; | 134 uint32_t ref_; |
| 127 uint32_t id_; | 135 uint32_t id_; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 delete static_cast<IThread*>(thread); | 181 delete static_cast<IThread*>(thread); |
| 174 } | 182 } |
| 175 } | 183 } |
| 176 | 184 |
| 177 void IThread::SetExceptionCatch(IThread::CatchFunc_t func, void *cookie) { | 185 void IThread::SetExceptionCatch(IThread::CatchFunc_t func, void *cookie) { |
| 178 NaClSignalHandlerAdd(Thread::SignalHandler); | 186 NaClSignalHandlerAdd(Thread::SignalHandler); |
| 179 s_CatchFunc = func; | 187 s_CatchFunc = func; |
| 180 s_CatchCookie = cookie; | 188 s_CatchCookie = cookie; |
| 181 } | 189 } |
| 182 | 190 |
| 191 void IThread::SuspendAll(uint32_t signaled_id) { |
| 192 if (signaled_id == 0) { |
| 193 NaClLog(LOG_FATAL, "IThread::SuspendAll: not implemented\n"); |
| 194 } else { |
| 195 Thread* thread = static_cast<Thread*>(Acquire(signaled_id)); |
| 196 NaClUntrustedThreadsSuspendAll2(thread->natp_->nap, thread->natp_); |
| 197 Release(thread); |
| 198 } |
| 199 } |
| 183 | 200 |
| 184 } // End of port namespace | 201 void IThread::ResumeAll(uint32_t signaled_id) { |
| 202 if (signaled_id == 0) { |
| 203 NaClLog(LOG_FATAL, "IThread::ResumeAll: not implemented\n"); |
| 204 } else { |
| 205 Thread* thread = static_cast<Thread*>(Acquire(signaled_id)); |
| 206 NaClUntrustedThreadsResumeAll2(thread->natp_->nap, thread->natp_); |
| 207 Release(thread); |
| 208 } |
| 209 } |
| 185 | 210 |
| 211 } // namespace port |
| OLD | NEW |