Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <errno.h> | |
| 6 #include <pthread.h> | |
| 7 | |
| 8 #include "base/macros.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "components/nacl/loader/nonsfi/irt_interfaces.h" | |
| 11 | |
| 12 namespace nacl { | |
| 13 namespace nonsfi { | |
| 14 namespace { | |
| 15 | |
| 16 // We heuristically chose 1M for the stack size per thread. | |
| 17 const int kStackSize = 1024 * 1024; | |
| 18 | |
| 19 // For RAII of pthread_attr_t. | |
| 20 class ScopedPthreadAttrPtr { | |
| 21 public: | |
| 22 ScopedPthreadAttrPtr(pthread_attr_t* attr) : attr_(attr) { | |
| 23 } | |
| 24 ~ScopedPthreadAttrPtr() { | |
| 25 pthread_attr_destroy(attr_); | |
| 26 } | |
| 27 | |
| 28 private: | |
| 29 pthread_attr_t* attr_; | |
| 30 }; | |
| 31 | |
| 32 struct ThreadContext { | |
| 33 void (*start_func)(); | |
| 34 void* thread_ptr; | |
| 35 }; | |
| 36 | |
| 37 // A thread local pointer to support nacl_irt_tls. | |
| 38 // This should be initialized at the beginning of ThreadMain, which is a thin | |
| 39 // wrapper of a user function called on a newly created thread, and may be | |
| 40 // reset via IrtTlsInit(). The pointer can be obtained via IrtTlsGet(). | |
| 41 __thread void* g_thread_ptr; | |
| 42 | |
| 43 void* ThreadMain(void *arg) { | |
| 44 ::scoped_ptr<ThreadContext> context(static_cast<ThreadContext*>(arg)); | |
| 45 g_thread_ptr = context->thread_ptr; | |
| 46 | |
| 47 // Release the memory of context before running start_func. | |
| 48 void (*start_func)() = context->start_func; | |
| 49 context.reset(); | |
| 50 | |
| 51 start_func(); | |
| 52 return NULL; | |
|
Mark Seaborn
2014/01/15 19:06:39
Can you call abort() instead? The user's function
hidehiko
2014/01/16 03:17:44
Done.
| |
| 53 } | |
| 54 | |
| 55 int IrtThreadCreate(void (*start_func)(), void* stack, void* thread_ptr) { | |
| 56 pthread_attr_t attr; | |
| 57 int error = pthread_attr_init(&attr); | |
| 58 if (error != 0) | |
| 59 return error; | |
| 60 ScopedPthreadAttrPtr scoped_attr_ptr(&attr); | |
| 61 | |
| 62 // Note: Currently we ignore the argument stack. | |
| 63 error = pthread_attr_setstacksize(&attr, kStackSize); | |
| 64 if (error != 0) | |
| 65 return error; | |
| 66 | |
| 67 error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
| 68 if (error != 0) | |
| 69 return error; | |
| 70 | |
| 71 ::scoped_ptr<ThreadContext> context(new ThreadContext); | |
| 72 context->start_func = start_func; | |
| 73 context->thread_ptr = thread_ptr; | |
| 74 | |
| 75 pthread_t tid; | |
| 76 error = pthread_create(&tid, &attr, ThreadMain, context.get()); | |
| 77 if (error != 0) | |
| 78 return error; | |
| 79 | |
| 80 // The ownership of the context is taken by the created thread. So, here we | |
| 81 // just manually release it. | |
| 82 ignore_result(context.release()); | |
| 83 return 0; | |
| 84 } | |
| 85 | |
| 86 void IrtThreadExit(int32_t* stack_flag) { | |
| 87 // As we actually don't use stack given to thread_create, it means that the | |
| 88 // memory can be released whenever. | |
| 89 if (stack_flag) | |
| 90 *stack_flag = 0; | |
| 91 pthread_exit(NULL); | |
| 92 } | |
| 93 | |
| 94 int IrtThreadNice(const int nice) { | |
| 95 // TODO(https://code.google.com/p/nativeclient/issues/detail?id=3734): | |
| 96 // Implement this method. | |
| 97 return ENOSYS; | |
|
Mark Seaborn
2014/01/15 19:06:39
Since 'nice' is just a hint, it would be better to
hidehiko
2014/01/16 03:17:44
Done.
| |
| 98 } | |
| 99 | |
| 100 int IrtTlsInit(void* thread_ptr) { | |
| 101 g_thread_ptr = thread_ptr; | |
| 102 return 0; | |
| 103 } | |
| 104 | |
| 105 void* IrtTlsGet() { | |
| 106 return g_thread_ptr; | |
| 107 } | |
| 108 | |
| 109 } // namespace | |
| 110 | |
| 111 const nacl_irt_thread kIrtThread = { | |
| 112 IrtThreadCreate, | |
| 113 IrtThreadExit, | |
| 114 IrtThreadNice, | |
| 115 }; | |
| 116 | |
| 117 const nacl_irt_tls kIrtTls = { | |
| 118 IrtTlsInit, | |
| 119 IrtTlsGet, | |
| 120 }; | |
| 121 | |
| 122 } // namespace nonsfi | |
| 123 } // namespace nacl | |
| OLD | NEW |