1b819cea2SGordon Ross /*
2b819cea2SGordon Ross  * This file and its contents are supplied under the terms of the
3b819cea2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4b819cea2SGordon Ross  * You may only use this file in accordance with the terms of version
5b819cea2SGordon Ross  * 1.0 of the CDDL.
6b819cea2SGordon Ross  *
7b819cea2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8b819cea2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9b819cea2SGordon Ross  * http://www.illumos.org/license/CDDL.
10b819cea2SGordon Ross  */
11b819cea2SGordon Ross 
12b819cea2SGordon Ross /*
13b819cea2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
14*589f9b62SVitaliy Gusev  * Copyright 2018 RackTop Systems.
15b819cea2SGordon Ross  */
16b819cea2SGordon Ross 
17b819cea2SGordon Ross #include <sys/cmn_err.h>
18b819cea2SGordon Ross #include <sys/thread.h>
19b819cea2SGordon Ross #include <sys/zone.h>
20f06dce2cSAndrew Stormont #include <sys/proc.h>
21*589f9b62SVitaliy Gusev #include <sys/atomic.h>
22b819cea2SGordon Ross 
23b819cea2SGordon Ross #define	_SYNCH_H	/* keep out <synch.h> */
24b819cea2SGordon Ross #include <thread.h>
25b819cea2SGordon Ross 
26b819cea2SGordon Ross /*
27b819cea2SGordon Ross  * Get the current kthread_t pointer.
28b819cea2SGordon Ross  */
29b819cea2SGordon Ross kthread_t *
_curthread(void)30b819cea2SGordon Ross _curthread(void)
31b819cea2SGordon Ross {
32b819cea2SGordon Ross 	thread_t tid;
33b819cea2SGordon Ross 
34b819cea2SGordon Ross 	tid = thr_self();
35b819cea2SGordon Ross 	return ((kthread_t *)(uintptr_t)tid);
36b819cea2SGordon Ross }
37b819cea2SGordon Ross 
38b819cea2SGordon Ross /*
39b819cea2SGordon Ross  * Create a thread.
40b819cea2SGordon Ross  *
41b819cea2SGordon Ross  * thread_create() blocks for memory if necessary.  It never fails.
42b819cea2SGordon Ross  */
43b819cea2SGordon Ross /* ARGSUSED */
44b819cea2SGordon Ross kthread_t *
thread_create(caddr_t stk,size_t stksize,void (* func)(),void * arg,size_t len,struct proc * pp,int state,pri_t pri)45b819cea2SGordon Ross thread_create(
46b819cea2SGordon Ross 	caddr_t	stk,
47b819cea2SGordon Ross 	size_t	stksize,
48b819cea2SGordon Ross 	void	(*func)(),
49b819cea2SGordon Ross 	void	*arg,
50b819cea2SGordon Ross 	size_t	len,
51b819cea2SGordon Ross 	struct proc *pp,
52b819cea2SGordon Ross 	int	state,
53b819cea2SGordon Ross 	pri_t	pri)
54b819cea2SGordon Ross {
55b819cea2SGordon Ross 	void * (*thr_func)(void *);
56b819cea2SGordon Ross 	thread_t newtid;
57b819cea2SGordon Ross 	int thr_flags = 0;
58b819cea2SGordon Ross 	int rc;
59b819cea2SGordon Ross 
60b819cea2SGordon Ross 	thr_flags = THR_BOUND;
61b819cea2SGordon Ross 
62b819cea2SGordon Ross 	switch (state) {
63b819cea2SGordon Ross 	case TS_RUN:
64b819cea2SGordon Ross 	case TS_ONPROC:
65b819cea2SGordon Ross 		break;
66b819cea2SGordon Ross 	case TS_STOPPED:
67b819cea2SGordon Ross 		thr_flags |= THR_SUSPENDED;
68b819cea2SGordon Ross 		break;
69b819cea2SGordon Ross 	default:
70b819cea2SGordon Ross 		cmn_err(CE_PANIC, "thread_create: invalid state");
71b819cea2SGordon Ross 		break;
72b819cea2SGordon Ross 	}
73b819cea2SGordon Ross 
740cad6fe6SToomas Soome 	thr_func = (void *(*)(void *))(uintptr_t)func;
75b819cea2SGordon Ross 	rc = thr_create(NULL, 0, thr_func, arg, thr_flags, &newtid);
76b819cea2SGordon Ross 	if (rc != 0)
77b819cea2SGordon Ross 		cmn_err(CE_PANIC, "thread_create failed, rc=%d", rc);
78b819cea2SGordon Ross 
79b819cea2SGordon Ross 	return ((void *)(uintptr_t)newtid);
80b819cea2SGordon Ross }
81b819cea2SGordon Ross 
82b819cea2SGordon Ross void
thread_exit(void)83b819cea2SGordon Ross thread_exit(void)
84b819cea2SGordon Ross {
85*589f9b62SVitaliy Gusev 	static thread_t reap_tid;
86*589f9b62SVitaliy Gusev 	thread_t prev;
87*589f9b62SVitaliy Gusev 
88*589f9b62SVitaliy Gusev 	/* reap previous thread exit */
89*589f9b62SVitaliy Gusev 	prev = atomic_swap_uint(&reap_tid, thr_self());
90*589f9b62SVitaliy Gusev 	if (prev != 0)
91*589f9b62SVitaliy Gusev 		(void) thr_join(prev, NULL, NULL); /* joinable thread */
92*589f9b62SVitaliy Gusev 
93b819cea2SGordon Ross 	thr_exit(NULL);
94b819cea2SGordon Ross }
95b819cea2SGordon Ross 
96b819cea2SGordon Ross void
thread_join(kt_did_t id)97b819cea2SGordon Ross thread_join(kt_did_t id)
98b819cea2SGordon Ross {
99b819cea2SGordon Ross 	thread_t thr_id;
100b819cea2SGordon Ross 
101b819cea2SGordon Ross 	thr_id = (thread_t)id;
102b819cea2SGordon Ross 	(void) thr_join(thr_id, NULL, NULL);
103b819cea2SGordon Ross }
104b819cea2SGordon Ross 
105b819cea2SGordon Ross void
tsignal(kthread_t * kt,int sig)106b819cea2SGordon Ross tsignal(kthread_t *kt, int sig)
107b819cea2SGordon Ross {
108b819cea2SGordon Ross 	thread_t tid = (thread_t)(uintptr_t)kt;
109b819cea2SGordon Ross 
110b819cea2SGordon Ross 	(void) thr_kill(tid, sig);
111b819cea2SGordon Ross }
112b819cea2SGordon Ross 
113b819cea2SGordon Ross 
114b819cea2SGordon Ross /*ARGSUSED*/
115b819cea2SGordon Ross kthread_t *
zthread_create(caddr_t stk,size_t stksize,void (* func)(),void * arg,size_t len,pri_t pri)116b819cea2SGordon Ross zthread_create(
117b819cea2SGordon Ross     caddr_t stk,
118b819cea2SGordon Ross     size_t stksize,
119b819cea2SGordon Ross     void (*func)(),
120b819cea2SGordon Ross     void *arg,
121b819cea2SGordon Ross     size_t len,
122b819cea2SGordon Ross     pri_t pri)
123b819cea2SGordon Ross {
124b819cea2SGordon Ross 	kthread_t *t;
125b819cea2SGordon Ross 
126b819cea2SGordon Ross 	t = thread_create(stk, stksize, func, arg, len, NULL, TS_RUN, pri);
127b819cea2SGordon Ross 
128b819cea2SGordon Ross 	return (t);
129b819cea2SGordon Ross }
130b819cea2SGordon Ross 
131b819cea2SGordon Ross void
zthread_exit(void)132b819cea2SGordon Ross zthread_exit(void)
133b819cea2SGordon Ross {
134b819cea2SGordon Ross 	thread_exit();
135b819cea2SGordon Ross 	/* NOTREACHED */
136b819cea2SGordon Ross }
137f06dce2cSAndrew Stormont 
138f06dce2cSAndrew Stormont void
tsd_create(uint_t * keyp,void (* destructor)(void *))139f06dce2cSAndrew Stormont tsd_create(uint_t *keyp, void (*destructor)(void *))
140f06dce2cSAndrew Stormont {
141f06dce2cSAndrew Stormont 	VERIFY0(thr_keycreate(keyp, destructor));
142f06dce2cSAndrew Stormont }
143f06dce2cSAndrew Stormont 
144f06dce2cSAndrew Stormont /*ARGSUSED*/
145f06dce2cSAndrew Stormont void
tsd_destroy(uint_t * keyp)146f06dce2cSAndrew Stormont tsd_destroy(uint_t *keyp)
147f06dce2cSAndrew Stormont {}
148f06dce2cSAndrew Stormont 
149f06dce2cSAndrew Stormont void *
tsd_get(uint_t key)150f06dce2cSAndrew Stormont tsd_get(uint_t key)
151f06dce2cSAndrew Stormont {
152f06dce2cSAndrew Stormont 	void *value;
153f06dce2cSAndrew Stormont 
154f06dce2cSAndrew Stormont 	return (thr_getspecific(key, &value) ? NULL : value);
155f06dce2cSAndrew Stormont }
156f06dce2cSAndrew Stormont 
157f06dce2cSAndrew Stormont int
tsd_set(uint_t key,void * value)158f06dce2cSAndrew Stormont tsd_set(uint_t key, void *value)
159f06dce2cSAndrew Stormont {
160f06dce2cSAndrew Stormont 	return (thr_setspecific(key, value));
161f06dce2cSAndrew Stormont }
162