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

Side by Side Diff: src/untrusted/pthread/nc_thread.c

Issue 623863002: Implement pthread_rwlock functions for NaCl newlib. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 5 years, 10 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 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 /* 7 /*
8 * Native Client threads library 8 * Native Client threads library
9 */ 9 */
10 10
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 /* Number of threads currently running in this NaCl module. */ 87 /* Number of threads currently running in this NaCl module. */
88 int __nc_running_threads_counter = 1; 88 int __nc_running_threads_counter = 1;
89 89
90 /* We have two queues of memory blocks - one for each type. */ 90 /* We have two queues of memory blocks - one for each type. */
91 STAILQ_HEAD(tailhead, entry) __nc_thread_memory_blocks[2]; 91 STAILQ_HEAD(tailhead, entry) __nc_thread_memory_blocks[2];
92 /* We need a counter for each queue to keep track of number of blocks. */ 92 /* We need a counter for each queue to keep track of number of blocks. */
93 int __nc_memory_block_counter[2]; 93 int __nc_memory_block_counter[2];
94 94
95 /* Internal functions */ 95 /* Internal functions */
96 96
97 static inline nc_thread_descriptor_t *nc_get_tdb(void) { 97 struct nc_thread_descriptor *__nc_get_tdb(void) {
98 /* 98 /*
99 * Fetch the thread-specific data pointer. This is usually just 99 * Fetch the thread-specific data pointer. This is usually just
100 * a wrapper around __libnacl_irt_tls.tls_get() but we don't use 100 * a wrapper around __libnacl_irt_tls.tls_get() but we don't use
101 * that here so that the IRT build can override the definition. 101 * that here so that the IRT build can override the definition.
102 */ 102 */
103 return (void *) ((char *) __nacl_read_tp_inline() 103 return (void *) ((char *) __nacl_read_tp_inline()
104 + __nacl_tp_tdb_offset(TDB_SIZE)); 104 + __nacl_tp_tdb_offset(TDB_SIZE));
105 } 105 }
106 106
107 static void nc_thread_starter(void) { 107 static void nc_thread_starter(void) {
108 nc_thread_descriptor_t *tdb = nc_get_tdb(); 108 nc_thread_descriptor_t *tdb = __nc_get_tdb();
109 __newlib_thread_init(); 109 __newlib_thread_init();
110 #if defined(NACL_IN_IRT) 110 #if defined(NACL_IN_IRT)
111 g_is_irt_internal_thread = 1; 111 g_is_irt_internal_thread = 1;
112 #endif 112 #endif
113 void *retval = tdb->start_func(tdb->state); 113 void *retval = tdb->start_func(tdb->state);
114 114
115 /* 115 /*
116 * Free handler list to prevent memory leak in case function returns 116 * Free handler list to prevent memory leak in case function returns
117 * without calling pthread_cleanup_pop(), although doing that is unspecified 117 * without calling pthread_cleanup_pop(), although doing that is unspecified
118 * behaviour. 118 * behaviour.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 nc_free_memory_block_mu(TLS_AND_TDB_MEMORY, block); 236 nc_free_memory_block_mu(TLS_AND_TDB_MEMORY, block);
237 } 237 }
238 } 238 }
239 239
240 /* Initialize a newly allocated TDB to some default values. */ 240 /* Initialize a newly allocated TDB to some default values. */
241 static void nc_tdb_init(nc_thread_descriptor_t *tdb, 241 static void nc_tdb_init(nc_thread_descriptor_t *tdb,
242 nc_basic_thread_data_t *basic_data) { 242 nc_basic_thread_data_t *basic_data) {
243 tdb->tls_base = tdb; 243 tdb->tls_base = tdb;
244 tdb->joinable = PTHREAD_CREATE_JOINABLE; 244 tdb->joinable = PTHREAD_CREATE_JOINABLE;
245 tdb->join_waiting = 0; 245 tdb->join_waiting = 0;
246 tdb->rdlock_count = 0;
246 tdb->stack_node = NULL; 247 tdb->stack_node = NULL;
247 tdb->tls_node = NULL; 248 tdb->tls_node = NULL;
248 tdb->start_func = NULL; 249 tdb->start_func = NULL;
249 tdb->state = NULL; 250 tdb->state = NULL;
250 tdb->irt_thread_data = NULL; 251 tdb->irt_thread_data = NULL;
251 tdb->basic_data = basic_data; 252 tdb->basic_data = basic_data;
252 253
253 basic_data->retval = NULL; 254 basic_data->retval = NULL;
254 basic_data->status = THREAD_RUNNING; 255 basic_data->status = THREAD_RUNNING;
255 if (pthread_cond_init(&basic_data->join_condvar, NULL) != 0) 256 if (pthread_cond_init(&basic_data->join_condvar, NULL) != 0)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 298
298 #else 299 #else
299 300
300 /* 301 /*
301 * Will be called from the library startup code, 302 * Will be called from the library startup code,
302 * which always happens on the application's main thread. 303 * which always happens on the application's main thread.
303 */ 304 */
304 void __pthread_initialize(void) { 305 void __pthread_initialize(void) {
305 __pthread_initialize_minimal(TDB_SIZE); 306 __pthread_initialize_minimal(TDB_SIZE);
306 307
307 struct nc_combined_tdb *tdb = (struct nc_combined_tdb *) nc_get_tdb(); 308 struct nc_combined_tdb *tdb = (struct nc_combined_tdb *) __nc_get_tdb();
308 nc_tdb_init(&tdb->tdb, &tdb->basic_data); 309 nc_tdb_init(&tdb->tdb, &tdb->basic_data);
309 __nc_initial_thread_id = &tdb->basic_data; 310 __nc_initial_thread_id = &tdb->basic_data;
310 311
311 __nc_initialize_globals(); 312 __nc_initialize_globals();
312 } 313 }
313 314
314 #endif 315 #endif
315 316
316 317
317 /* pthread functions */ 318 /* pthread functions */
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 nc_thread_cleanup_handler *handler = __nc_cleanup_handlers; 486 nc_thread_cleanup_handler *handler = __nc_cleanup_handlers;
486 __nc_cleanup_handlers = handler->previous; 487 __nc_cleanup_handlers = handler->previous;
487 if (execute) 488 if (execute)
488 handler->handler_function(handler->handler_arg); 489 handler->handler_function(handler->handler_arg);
489 free(handler); 490 free(handler);
490 } 491 }
491 } 492 }
492 493
493 void pthread_exit(void *retval) { 494 void pthread_exit(void *retval) {
494 /* Get all we need from the tdb before releasing it. */ 495 /* Get all we need from the tdb before releasing it. */
495 nc_thread_descriptor_t *tdb = nc_get_tdb(); 496 nc_thread_descriptor_t *tdb = __nc_get_tdb();
496 nc_thread_memory_block_t *stack_node = tdb->stack_node; 497 nc_thread_memory_block_t *stack_node = tdb->stack_node;
497 int32_t *is_used = &stack_node->is_used; 498 int32_t *is_used = &stack_node->is_used;
498 nc_basic_thread_data_t *basic_data = tdb->basic_data; 499 nc_basic_thread_data_t *basic_data = tdb->basic_data;
499 int joinable = tdb->joinable; 500 int joinable = tdb->joinable;
500 501
501 /* Call cleanup handlers. */ 502 /* Call cleanup handlers. */
502 while (NULL != __nc_cleanup_handlers) { 503 while (NULL != __nc_cleanup_handlers) {
503 pthread_cleanup_pop(1); 504 pthread_cleanup_pop(1);
504 } 505 }
505 506
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 } 624 }
624 625
625 int pthread_kill(pthread_t thread_id, 626 int pthread_kill(pthread_t thread_id,
626 int sig) { 627 int sig) {
627 /* This function is currently unimplemented. */ 628 /* This function is currently unimplemented. */
628 return ENOSYS; 629 return ENOSYS;
629 } 630 }
630 631
631 pthread_t pthread_self(void) { 632 pthread_t pthread_self(void) {
632 /* Get the tdb pointer from gs and use it to return the thread handle. */ 633 /* Get the tdb pointer from gs and use it to return the thread handle. */
633 nc_thread_descriptor_t *tdb = nc_get_tdb(); 634 nc_thread_descriptor_t *tdb = __nc_get_tdb();
634 return tdb->basic_data; 635 return tdb->basic_data;
635 } 636 }
636 637
637 int pthread_equal(pthread_t thread1, pthread_t thread2) { 638 int pthread_equal(pthread_t thread1, pthread_t thread2) {
638 return (thread1 == thread2); 639 return (thread1 == thread2);
639 } 640 }
640 641
641 int pthread_setschedprio(pthread_t thread_id, int prio) { 642 int pthread_setschedprio(pthread_t thread_id, int prio) {
642 if (thread_id != pthread_self()) { 643 if (thread_id != pthread_self()) {
643 /* 644 /*
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 822
822 /* 823 /*
823 * We include this directly in this file rather than compiling it 824 * We include this directly in this file rather than compiling it
824 * separately because there is some code (e.g. libstdc++) that uses weak 825 * separately because there is some code (e.g. libstdc++) that uses weak
825 * references to all pthread functions, but conditionalizes its calls only 826 * references to all pthread functions, but conditionalizes its calls only
826 * on one symbol. So if these functions are in another file in a library 827 * on one symbol. So if these functions are in another file in a library
827 * archive, they might not be linked in by static linking. 828 * archive, they might not be linked in by static linking.
828 */ 829 */
829 /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */ 830 /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
830 #include "native_client/src/untrusted/pthread/nc_tsd.c" 831 #include "native_client/src/untrusted/pthread/nc_tsd.c"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698