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