2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Server Runtime threads implementation layer.
36 /* get the XSI-compliant version of strerror_r */
37 #define _XOPEN_SOURCE 600
41 #include <sys/types.h>
46 * PTHREAD_STACK_MIN should come from pthread.h as documented, but is
47 * actually pulled in by limits.h.
50 #include "native_client/service_runtime/nacl_config.h"
51 #include "native_client/service_runtime/nacl_threads.h"
52 #include "native_client/service_runtime/nacl_log.h"
54 #if NACL_KERN_STACK_SIZE < PTHREAD_STACK_MIN
55 # error "NaCl service runtime stack size is smaller than PTHREAD_STACK_MIN"
59 * Even if ctor fails, it should be okay -- and required -- to invoke
62 int NaClThreadCtor(struct NaClThread
*ntp
,
63 void (*start_fn
)(void *),
70 char err_string
[1024];
74 if (stack_size
< PTHREAD_STACK_MIN
) {
75 stack_size
= PTHREAD_STACK_MIN
;
77 if (0 != (code
= pthread_attr_init(&attr
))) {
79 "NaClThreadCtor: pthread_atr_init returned %d",
83 if (0 != (code
= pthread_attr_setstacksize(&attr
, stack_size
))) {
85 "NaClThreadCtor: pthread_attr_setstacksize returned %d (%s)",
87 (strerror_r(code
, err_string
, sizeof err_string
) == 0
93 (code
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
))) {
95 "nacl_thread: pthread_attr_setdetachstate returned %d (%s)",
97 (strerror_r(code
, err_string
, sizeof err_string
) == 0
102 if (0 != (code
= pthread_create(&ntp
->tid
,
104 (void *(*)(void *)) start_fn
,
107 "nacl_thread: pthread_create returned %d (%s)",
109 (strerror_r(code
, err_string
, sizeof err_string
) == 0
116 (void) pthread_attr_destroy(&attr
); /* often a noop */
121 void NaClThreadDtor(struct NaClThread
*ntp
)
124 * The threads that we create are not joinable, and we cannot tell
125 * when they are truly gone. Fortunately, the threads themselves
126 * and the underlying thread library are responsible for ensuring
127 * that resources such as the thread stack are properly released.
131 void NaClThreadExit(void)
133 pthread_exit((void *) 0);
136 void NaClThreadKill(struct NaClThread
*target
)
138 pthread_kill(target
->tid
, SIGKILL
);
141 int NaClTsdKeyCreate(struct NaClTsdKey
*tsdp
)
145 errcode
= pthread_key_create(&tsdp
->key
, (void (*)(void *)) NULL
);
146 /* returns zero on success, error code on failure */
149 "NaClTsdKeyCreate: could not create new key, error code %d",
155 int NaClTsdSetSpecific(struct NaClTsdKey
*tsdp
,
160 errcode
= pthread_setspecific(tsdp
->key
, ptr
);
161 /* returns zero on success, error code on failure */
164 "NaClTsdSetSpecific: could not set new value, error code %d",
170 void *NaClTsdGetSpecific(struct NaClTsdKey
*tsdp
)
172 return pthread_getspecific(tsdp
->key
);