Chromium Code Reviews| Index: components/nacl/loader/nonsfi/irt_thread.cc |
| diff --git a/components/nacl/loader/nonsfi/irt_thread.cc b/components/nacl/loader/nonsfi/irt_thread.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d0a181425c548fba1493e4ab648c337c7f403c6f |
| --- /dev/null |
| +++ b/components/nacl/loader/nonsfi/irt_thread.cc |
| @@ -0,0 +1,123 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <errno.h> |
| +#include <pthread.h> |
| + |
| +#include "base/macros.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "components/nacl/loader/nonsfi/irt_interfaces.h" |
| + |
| +namespace nacl { |
| +namespace nonsfi { |
| +namespace { |
| + |
| +// We heuristically chose 1M for the stack size per thread. |
| +const int kStackSize = 1024 * 1024; |
| + |
| +// For RAII of pthread_attr_t. |
| +class ScopedPthreadAttrPtr { |
| + public: |
| + ScopedPthreadAttrPtr(pthread_attr_t* attr) : attr_(attr) { |
| + } |
| + ~ScopedPthreadAttrPtr() { |
| + pthread_attr_destroy(attr_); |
| + } |
| + |
| + private: |
| + pthread_attr_t* attr_; |
| +}; |
| + |
| +struct ThreadContext { |
| + void (*start_func)(); |
| + void* thread_ptr; |
| +}; |
| + |
| +// A thread local pointer to support nacl_irt_tls. |
| +// This should be initialized at the beginning of ThreadMain, which is a thin |
| +// wrapper of a user function called on a newly created thread, and may be |
| +// reset via IrtTlsInit(). The pointer can be obtained via IrtTlsGet(). |
| +__thread void* g_thread_ptr; |
| + |
| +void* ThreadMain(void *arg) { |
| + ::scoped_ptr<ThreadContext> context(static_cast<ThreadContext*>(arg)); |
| + g_thread_ptr = context->thread_ptr; |
| + |
| + // Release the memory of context before running start_func. |
| + void (*start_func)() = context->start_func; |
| + context.reset(); |
| + |
| + start_func(); |
| + 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.
|
| +} |
| + |
| +int IrtThreadCreate(void (*start_func)(), void* stack, void* thread_ptr) { |
| + pthread_attr_t attr; |
| + int error = pthread_attr_init(&attr); |
| + if (error != 0) |
| + return error; |
| + ScopedPthreadAttrPtr scoped_attr_ptr(&attr); |
| + |
| + // Note: Currently we ignore the argument stack. |
| + error = pthread_attr_setstacksize(&attr, kStackSize); |
| + if (error != 0) |
| + return error; |
| + |
| + error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| + if (error != 0) |
| + return error; |
| + |
| + ::scoped_ptr<ThreadContext> context(new ThreadContext); |
| + context->start_func = start_func; |
| + context->thread_ptr = thread_ptr; |
| + |
| + pthread_t tid; |
| + error = pthread_create(&tid, &attr, ThreadMain, context.get()); |
| + if (error != 0) |
| + return error; |
| + |
| + // The ownership of the context is taken by the created thread. So, here we |
| + // just manually release it. |
| + ignore_result(context.release()); |
| + return 0; |
| +} |
| + |
| +void IrtThreadExit(int32_t* stack_flag) { |
| + // As we actually don't use stack given to thread_create, it means that the |
| + // memory can be released whenever. |
| + if (stack_flag) |
| + *stack_flag = 0; |
| + pthread_exit(NULL); |
| +} |
| + |
| +int IrtThreadNice(const int nice) { |
| + // TODO(https://code.google.com/p/nativeclient/issues/detail?id=3734): |
| + // Implement this method. |
| + 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.
|
| +} |
| + |
| +int IrtTlsInit(void* thread_ptr) { |
| + g_thread_ptr = thread_ptr; |
| + return 0; |
| +} |
| + |
| +void* IrtTlsGet() { |
| + return g_thread_ptr; |
| +} |
| + |
| +} // namespace |
| + |
| +const nacl_irt_thread kIrtThread = { |
| + IrtThreadCreate, |
| + IrtThreadExit, |
| + IrtThreadNice, |
| +}; |
| + |
| +const nacl_irt_tls kIrtTls = { |
| + IrtTlsInit, |
| + IrtTlsGet, |
| +}; |
| + |
| +} // namespace nonsfi |
| +} // namespace nacl |