1*568eb77eSriastradh /* $NetBSD: pthread_specific.c,v 1.28 2022/04/10 10:38:33 riastradh Exp $ */
2c62a74e6Sthorpej
3c62a74e6Sthorpej /*-
4b8833ff5Sad * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
5c62a74e6Sthorpej * All rights reserved.
6c62a74e6Sthorpej *
7c62a74e6Sthorpej * This code is derived from software contributed to The NetBSD Foundation
8c62a74e6Sthorpej * by Nathan J. Williams.
9c62a74e6Sthorpej *
10c62a74e6Sthorpej * Redistribution and use in source and binary forms, with or without
11c62a74e6Sthorpej * modification, are permitted provided that the following conditions
12c62a74e6Sthorpej * are met:
13c62a74e6Sthorpej * 1. Redistributions of source code must retain the above copyright
14c62a74e6Sthorpej * notice, this list of conditions and the following disclaimer.
15c62a74e6Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
16c62a74e6Sthorpej * notice, this list of conditions and the following disclaimer in the
17c62a74e6Sthorpej * documentation and/or other materials provided with the distribution.
18c62a74e6Sthorpej *
19c62a74e6Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20c62a74e6Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21c62a74e6Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22c62a74e6Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23c62a74e6Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24c62a74e6Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25c62a74e6Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26c62a74e6Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27c62a74e6Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28c62a74e6Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29c62a74e6Sthorpej * POSSIBILITY OF SUCH DAMAGE.
30c62a74e6Sthorpej */
31c62a74e6Sthorpej
32f043c0fbSlukem #include <sys/cdefs.h>
33*568eb77eSriastradh __RCSID("$NetBSD: pthread_specific.c,v 1.28 2022/04/10 10:38:33 riastradh Exp $");
347adb4107Sriastradh
357adb4107Sriastradh /* Need to use libc-private names for atomic operations. */
367adb4107Sriastradh #include "../../common/lib/libc/atomic/atomic_op_namespace.h"
37f043c0fbSlukem
38c62a74e6Sthorpej /* Functions and structures dealing with thread-specific data */
39c62a74e6Sthorpej
40c62a74e6Sthorpej #include "pthread.h"
41c62a74e6Sthorpej #include "pthread_int.h"
4271d484f9Schristos #include "reentrant.h"
43c62a74e6Sthorpej
44bba80928Smanu #include <string.h>
454084ca7fSad #include <sys/lwpctl.h>
464084ca7fSad
47bba80928Smanu #include "../libc/include/extern.h" /* for _sys_setcontext() */
48bba80928Smanu
49bba80928Smanu int pthread_setcontext(const ucontext_t *);
50bba80928Smanu
__strong_alias(__libc_thr_setspecific,pthread_setspecific)51c62a74e6Sthorpej __strong_alias(__libc_thr_setspecific,pthread_setspecific)
52c62a74e6Sthorpej __strong_alias(__libc_thr_getspecific,pthread_getspecific)
534084ca7fSad __strong_alias(__libc_thr_curcpu,pthread_curcpu_np)
54c62a74e6Sthorpej
55bba80928Smanu __strong_alias(setcontext,pthread_setcontext)
56bba80928Smanu
57c62a74e6Sthorpej int
58c62a74e6Sthorpej pthread_setspecific(pthread_key_t key, const void *value)
59c62a74e6Sthorpej {
60c62a74e6Sthorpej pthread_t self;
61c62a74e6Sthorpej
6271d484f9Schristos if (__predict_false(__uselibcstub))
6371d484f9Schristos return __libc_thr_setspecific_stub(key, value);
6471d484f9Schristos
65c62a74e6Sthorpej self = pthread__self();
66c62a74e6Sthorpej /*
67c62a74e6Sthorpej * We can't win here on constness. Having been given a
68c62a74e6Sthorpej * "const void *", we can only assign it to other const void *,
69c62a74e6Sthorpej * and return it from functions that are const void *, without
70c62a74e6Sthorpej * generating a warning.
71c62a74e6Sthorpej */
7255f47ec3Schristos return pthread__add_specific(self, key, value);
73c62a74e6Sthorpej }
74c62a74e6Sthorpej
75c62a74e6Sthorpej void *
pthread_getspecific(pthread_key_t key)76c62a74e6Sthorpej pthread_getspecific(pthread_key_t key)
77c62a74e6Sthorpej {
7871d484f9Schristos if (__predict_false(__uselibcstub))
7971d484f9Schristos return __libc_thr_getspecific_stub(key);
804084ca7fSad
8155f47ec3Schristos return pthread__self()->pt_specific[key].pts_value;
82c62a74e6Sthorpej }
834084ca7fSad
844084ca7fSad unsigned int
pthread_curcpu_np(void)854084ca7fSad pthread_curcpu_np(void)
864084ca7fSad {
8771d484f9Schristos if (__predict_false(__uselibcstub))
8871d484f9Schristos return __libc_thr_curcpu_stub();
8971d484f9Schristos
9071d484f9Schristos {
9193af5b69Syamt const int curcpu = pthread__self()->pt_lwpctl->lc_curcpu;
9248a1e4cfSyamt
9393af5b69Syamt pthread__assert(curcpu != LWPCTL_CPU_NONE);
9493af5b69Syamt pthread__assert(curcpu != LWPCTL_CPU_EXITED);
9593af5b69Syamt pthread__assert(curcpu >= 0);
9693af5b69Syamt return curcpu;
974084ca7fSad }
9871d484f9Schristos }
99bba80928Smanu
100bba80928Smanu /*
101bba80928Smanu * Override setcontext so that pthread private pointer is preserved
102bba80928Smanu */
103bba80928Smanu int
pthread_setcontext(const ucontext_t * ucp)104bba80928Smanu pthread_setcontext(const ucontext_t *ucp)
105bba80928Smanu {
106426a7619Smatt #ifdef _UC_TLSBASE
107bba80928Smanu ucontext_t uc;
108426a7619Smatt /*
109426a7619Smatt * Only copy and clear _UC_TLSBASE if it is set.
110426a7619Smatt */
111426a7619Smatt if (ucp->uc_flags & _UC_TLSBASE) {
112426a7619Smatt uc = *ucp;
113bba80928Smanu uc.uc_flags &= ~_UC_TLSBASE;
114426a7619Smatt ucp = &uc;
115426a7619Smatt }
116426a7619Smatt #endif /* _UC_TLSBASE */
117426a7619Smatt return _sys_setcontext(ucp);
118bba80928Smanu }
119