1 /*	$NetBSD: subr_lwp_specificdata.c,v 1.3 2013/10/25 16:17:35 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 2006 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #define _LWP_API_PRIVATE
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: subr_lwp_specificdata.c,v 1.3 2013/10/25 16:17:35 martin Exp $");
33 
34 #include <sys/param.h>
35 #include <sys/lwp.h>
36 #include <sys/specificdata.h>
37 
38 static specificdata_domain_t lwp_specificdata_domain;
39 
40 void
lwpinit_specificdata(void)41 lwpinit_specificdata(void)
42 {
43 
44 	lwp_specificdata_domain = specificdata_domain_create();
45 	KASSERT(lwp_specificdata_domain != NULL);
46 }
47 
48 /*
49  * lwp_specific_key_create --
50  *	Create a key for subsystem lwp-specific data.
51  */
52 int
lwp_specific_key_create(specificdata_key_t * keyp,specificdata_dtor_t dtor)53 lwp_specific_key_create(specificdata_key_t *keyp, specificdata_dtor_t dtor)
54 {
55 
56 	return (specificdata_key_create(lwp_specificdata_domain, keyp, dtor));
57 }
58 
59 /*
60  * lwp_specific_key_delete --
61  *	Delete a key for subsystem lwp-specific data.
62  */
63 void
lwp_specific_key_delete(specificdata_key_t key)64 lwp_specific_key_delete(specificdata_key_t key)
65 {
66 
67 	specificdata_key_delete(lwp_specificdata_domain, key);
68 }
69 
70 /*
71  * lwp_initspecific --
72  *	Initialize an LWP's specificdata container.
73  */
74 void
lwp_initspecific(struct lwp * l)75 lwp_initspecific(struct lwp *l)
76 {
77 	int error __diagused;
78 
79 	error = specificdata_init(lwp_specificdata_domain, &l->l_specdataref);
80 	KASSERT(error == 0);
81 }
82 
83 /*
84  * lwp_finispecific --
85  *	Finalize an LWP's specificdata container.
86  */
87 void
lwp_finispecific(struct lwp * l)88 lwp_finispecific(struct lwp *l)
89 {
90 
91 	specificdata_fini(lwp_specificdata_domain, &l->l_specdataref);
92 }
93 
94 /*
95  * lwp_getspecific --
96  *	Return lwp-specific data corresponding to the specified key.
97  *
98  *	Note: LWP specific data is NOT INTERLOCKED.  An LWP should access
99  *	only its OWN SPECIFIC DATA.  If it is necessary to access another
100  *	LWP's specifc data, care must be taken to ensure that doing so
101  *	would not cause internal data structure inconsistency (i.e. caller
102  *	can guarantee that the target LWP is not inside an lwp_getspecific()
103  *	or lwp_setspecific() call).
104  */
105 void *
lwp_getspecific(specificdata_key_t key)106 lwp_getspecific(specificdata_key_t key)
107 {
108 
109 	return (specificdata_getspecific_unlocked(lwp_specificdata_domain,
110 						  &curlwp->l_specdataref, key));
111 }
112 
113 void *
_lwp_getspecific_by_lwp(struct lwp * l,specificdata_key_t key)114 _lwp_getspecific_by_lwp(struct lwp *l, specificdata_key_t key)
115 {
116 
117 	return (specificdata_getspecific_unlocked(lwp_specificdata_domain,
118 						  &l->l_specdataref, key));
119 }
120 
121 /*
122  * lwp_setspecific --
123  *	Set lwp-specific data corresponding to the specified key.
124  */
125 void
lwp_setspecific(specificdata_key_t key,void * data)126 lwp_setspecific(specificdata_key_t key, void *data)
127 {
128 
129 	specificdata_setspecific(lwp_specificdata_domain,
130 				 &curlwp->l_specdataref, key, data);
131 }
132