1 /* $OpenBSD: rthread_sched.c,v 1.7 2006/01/06 09:49:16 otto Exp $ */ 2 /* 3 * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /* 19 * scheduling routines 20 */ 21 22 #include <sys/param.h> 23 #include <sys/mman.h> 24 #include <sys/wait.h> 25 26 #include <machine/spinlock.h> 27 28 #include <stdlib.h> 29 #include <unistd.h> 30 #include <signal.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <errno.h> 34 35 #include <pthread.h> 36 #include <pthread_np.h> 37 38 #include "rthread.h" 39 40 int 41 pthread_getschedparam(pthread_t thread, int *policy, 42 struct sched_param *param) 43 { 44 *policy = thread->sched_policy; 45 if (param) 46 *param = thread->sched_param; 47 48 return (0); 49 } 50 51 int 52 pthread_setschedparam(pthread_t thread, int policy, 53 const struct sched_param *param) 54 { 55 thread->sched_policy = policy; 56 if (param) 57 thread->sched_param = *param; 58 59 return (0); 60 } 61 62 int 63 pthread_attr_getschedparam(const pthread_attr_t *attrp, struct sched_param *param) 64 { 65 *param = (*attrp)->sched_param; 66 67 return (0); 68 } 69 70 int 71 pthread_attr_setschedparam(pthread_attr_t *attrp, const struct sched_param *param) 72 { 73 (*attrp)->sched_param = *param; 74 75 return (0); 76 } 77 78 int 79 pthread_attr_getschedpolicy(const pthread_attr_t *attrp, int *policy) 80 { 81 *policy = (*attrp)->sched_policy; 82 83 return (0); 84 } 85 86 int 87 pthread_attr_setschedpolicy(pthread_attr_t *attrp, int policy) 88 { 89 (*attrp)->sched_policy = policy; 90 91 return (0); 92 } 93 94 int 95 pthread_attr_getinheritsched(const pthread_attr_t *attrp, int *inherit) 96 { 97 *inherit = (*attrp)->sched_inherit; 98 99 return (0); 100 } 101 102 int 103 pthread_attr_setinheritsched(pthread_attr_t *attrp, int inherit) 104 { 105 (*attrp)->sched_inherit = inherit; 106 107 return (0); 108 } 109 110 int 111 pthread_getprio(pthread_t thread) 112 { 113 return (thread->sched_param.sched_priority); 114 } 115 116 int 117 pthread_setprio(pthread_t thread, int priority) 118 { 119 thread->sched_param.sched_priority = priority; 120 121 return (0); 122 } 123 124 void 125 pthread_yield(void) 126 { 127 sched_yield(); 128 } 129 130 int 131 pthread_suspend_np(pthread_t thread) 132 { 133 int errn = 0; 134 135 if (thread->tid == getthrid()) 136 return (EDEADLK); 137 /* 138 * XXX Avoid a bug in current signal handling by refusing to 139 * suspend the main thread. 140 */ 141 if (thread->tid != _initial_thread.tid) 142 if (kill(thread->tid, SIGSTOP) == -1) 143 errn = errno; 144 return (errn); 145 } 146 147 void 148 pthread_suspend_all_np(void) 149 { 150 pthread_t t; 151 pid_t me = getthrid(); 152 153 _spinlock(&_thread_lock); 154 LIST_FOREACH(t, &_thread_list, threads) 155 if (t->tid != me) 156 pthread_suspend_np(t); 157 _spinunlock(&_thread_lock); 158 } 159 160 int 161 pthread_resume_np(pthread_t thread) 162 { 163 int errn = 0; 164 165 /* XXX check if really suspended? */ 166 if (kill(thread->tid, SIGCONT) == -1) 167 errn = errno; 168 return (errn); 169 } 170 171 void 172 pthread_resume_all_np(void) 173 { 174 pthread_t t; 175 pid_t me = getthrid(); 176 177 _spinlock(&_thread_lock); 178 LIST_FOREACH(t, &_thread_list, threads) 179 if (t->tid != me) 180 pthread_resume_np(t); 181 _spinunlock(&_thread_lock); 182 } 183 184