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

Unified Diff: src/nonsfi/linux/linux_pthread_private.c

Issue 1222753005: Non-SFI mode: Use clone() instead of pthread_create() (Closed) Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
Patch Set: Fixed compilation errors 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/nonsfi/linux/linux_pthread_private.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/nonsfi/linux/linux_pthread_private.c
diff --git a/src/nonsfi/linux/linux_pthread_private.c b/src/nonsfi/linux/linux_pthread_private.c
index 0cf3cd03d0c10076cf393720abfdd0bdbf0ab83b..0b7911239033cb55895c431369b645c511941425 100644
--- a/src/nonsfi/linux/linux_pthread_private.c
+++ b/src/nonsfi/linux/linux_pthread_private.c
@@ -4,8 +4,10 @@
* found in the LICENSE file.
*/
+#include <assert.h>
#include <errno.h>
+#include "native_client/src/nonsfi/linux/linux_pthread_private.h"
#include "native_client/src/nonsfi/linux/linux_syscall_defines.h"
#include "native_client/src/nonsfi/linux/linux_syscall_structs.h"
#include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h"
@@ -79,6 +81,116 @@ static int nacl_irt_thread_nice(const int nice) {
return 0;
}
+static struct nc_combined_tdb *get_irt_tdb(void *thread_ptr) {
+ struct nc_combined_tdb *tdb = (void *) ((uintptr_t) thread_ptr +
+ __nacl_tp_tdb_offset(sizeof(*tdb)));
+ return tdb;
+}
+
+/* Initialize a newly allocated TDB to some default values. */
+static void nc_tdb_init(nc_thread_descriptor_t *tdb,
Mark Seaborn 2015/07/08 04:11:21 Rather than duplicating this from pthread/nc_threa
Luis Héctor Chávez 2015/07/08 16:42:13 Done.
+ nc_basic_thread_data_t *basic_data) {
+ tdb->tls_base = tdb;
+ tdb->joinable = PTHREAD_CREATE_JOINABLE;
+ tdb->join_waiting = 0;
+ tdb->rdlock_count = 0;
+ tdb->stack_node = NULL;
+ tdb->tls_node = NULL;
+ tdb->start_func = NULL;
+ tdb->state = NULL;
+ tdb->irt_thread_data = NULL;
+ tdb->basic_data = basic_data;
+
+ basic_data->retval = NULL;
+ basic_data->status = THREAD_RUNNING;
+ if (pthread_cond_init(&basic_data->join_condvar, NULL) != 0)
+ __builtin_trap();
+ basic_data->tdb = tdb;
+}
+
+/*
+ * This is used by the IRT for user threads. We initialize all fields
+ * so that we get predictable behaviour in case some IRT code does an
+ * unsupported pthread operation on a user thread.
+ */
+void __nc_initialize_unjoinable_thread(struct nc_combined_tdb *tdb) {
+ nc_tdb_init(&tdb->tdb, &tdb->basic_data);
+ tdb->tdb.joinable = 0;
+}
+
+/*
+ * This is the real first entry point for new threads.
+ */
+static void irt_start_thread() {
Mark Seaborn 2015/07/08 04:11:21 Can you add a comment saying that this is based on
Luis Héctor Chávez 2015/07/08 16:42:13 Done.
+ struct nc_combined_tdb *tdb = get_irt_tdb(__nacl_read_tp());
+
+ /*
+ * Fetch the user's start routine.
+ */
+ void *(*user_start)(void *) = tdb->tdb.start_func;
+
+ /*
+ * Now do per-thread initialization for the IRT-private C library state.
+ */
+ __newlib_thread_init();
+
+ /*
+ * Finally, run the user code.
+ */
+ (*user_start)(tdb->tdb.state);
+
+ /*
+ * That should never return. Crash hard if it does.
+ */
+ __builtin_trap();
+}
+
+int nacl_user_thread_create(void *(*start_func)(void *), void *stack,
+ void *thread_ptr) {
+ struct nc_combined_tdb *tdb;
+
+ /*
+ * Before we start the thread, allocate the IRT-private TLS area for it.
+ */
+ size_t combined_size = __nacl_tls_combined_size(sizeof(*tdb));
+ void *combined_area = malloc(combined_size);
+ if (combined_area == NULL)
+ return EAGAIN;
+
+ /*
Mark Seaborn 2015/07/08 04:11:21 Nit: fix indentation
Luis Héctor Chávez 2015/07/08 16:42:13 Done.
+ * Note that __nacl_tls_initialize_memory() is not reversible,
+ * because it takes a pointer that need not be aligned and can
+ * return a pointer that is aligned. In order to
+ * free(combined_area) later, we must save the value of
+ * combined_area.
+ */
+ void *irt_tp = __nacl_tls_initialize_memory(combined_area, sizeof(*tdb));
Mark Seaborn 2015/07/08 04:11:21 Nit: fix indentation
Luis Héctor Chávez 2015/07/08 16:42:13 Done.
+ tdb = get_irt_tdb(irt_tp);
+ __nc_initialize_unjoinable_thread(tdb);
+ tdb->tdb.irt_thread_data = combined_area;
+ tdb->tdb.start_func = start_func;
+ tdb->tdb.state = thread_ptr;
+
+ return nacl_irt_thread_create(irt_start_thread, stack, irt_tp);
+}
+
+void nacl_user_thread_exit(int32_t *stack_flag) {
+ struct nc_combined_tdb *tdb = get_irt_tdb(__nacl_read_tp());
+
+ __nc_tsd_exit();
+
+ /*
+ * Sanity check: Check that this function was not called on a thread
+ * created by the IRT's internal pthread_create(). For such
+ * threads, irt_thread_data == NULL.
+ */
+ assert(tdb->tdb.irt_thread_data != NULL);
+
+ free(tdb->tdb.irt_thread_data);
+
+ nacl_irt_thread_exit(stack_flag);
+}
+
void __nc_initialize_interfaces(void) {
const struct nacl_irt_thread init = {
nacl_irt_thread_create,
« no previous file with comments | « src/nonsfi/linux/linux_pthread_private.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698