1 /* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. 4 * Copyright 2006, Jérôme Duval. All rights reserved. 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include <pthread.h> 10 #include "pthread_private.h" 11 12 #include <limits.h> 13 #include <stdlib.h> 14 15 #include <Debug.h> 16 17 #include <syscalls.h> 18 #include <thread_defs.h> 19 20 21 int __pthread_attr_get_np(pthread_t thread, pthread_attr_t *_attr); 22 int __pthread_getattr_np(pthread_t thread, pthread_attr_t *_attr); 23 24 25 int 26 pthread_attr_init(pthread_attr_t *_attr) 27 { 28 pthread_attr *attr; 29 30 if (_attr == NULL) 31 return B_BAD_VALUE; 32 33 attr = (pthread_attr *)malloc(sizeof(pthread_attr)); 34 if (attr == NULL) 35 return B_NO_MEMORY; 36 37 attr->detach_state = PTHREAD_CREATE_JOINABLE; 38 attr->sched_priority = B_NORMAL_PRIORITY; 39 attr->stack_size = USER_STACK_SIZE; 40 attr->guard_size = USER_STACK_GUARD_SIZE; 41 attr->stack_address = NULL; 42 43 *_attr = attr; 44 return B_OK; 45 } 46 47 48 int 49 pthread_attr_destroy(pthread_attr_t *_attr) 50 { 51 pthread_attr *attr; 52 53 if (_attr == NULL || (attr = *_attr) == NULL) 54 return B_BAD_VALUE; 55 56 *_attr = NULL; 57 free(attr); 58 59 return B_OK; 60 } 61 62 63 int 64 pthread_attr_getdetachstate(const pthread_attr_t *_attr, int *state) 65 { 66 pthread_attr *attr; 67 68 if (_attr == NULL || (attr = *_attr) == NULL || state == NULL) 69 return B_BAD_VALUE; 70 71 *state = attr->detach_state; 72 73 return B_OK; 74 } 75 76 77 int 78 pthread_attr_setdetachstate(pthread_attr_t *_attr, int state) 79 { 80 pthread_attr *attr; 81 82 if (_attr == NULL || (attr = *_attr) == NULL) 83 return B_BAD_VALUE; 84 85 if (state != PTHREAD_CREATE_JOINABLE && state != PTHREAD_CREATE_DETACHED) 86 return B_BAD_VALUE; 87 88 attr->detach_state = state; 89 90 return B_OK; 91 } 92 93 94 int 95 pthread_attr_getstacksize(const pthread_attr_t *_attr, size_t *stacksize) 96 { 97 pthread_attr *attr; 98 99 if (_attr == NULL || (attr = *_attr) == NULL || stacksize == NULL) 100 return B_BAD_VALUE; 101 102 *stacksize = attr->stack_size; 103 104 return 0; 105 } 106 107 108 int 109 pthread_attr_setstacksize(pthread_attr_t *_attr, size_t stacksize) 110 { 111 pthread_attr *attr; 112 113 if (_attr == NULL || (attr = *_attr) == NULL) 114 return B_BAD_VALUE; 115 116 STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE 117 && PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE); 118 if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE) 119 return B_BAD_VALUE; 120 121 attr->stack_size = stacksize; 122 123 return 0; 124 } 125 126 127 int 128 pthread_attr_getscope(const pthread_attr_t *attr, int *contentionScope) 129 { 130 if (attr == NULL || contentionScope == NULL) 131 return EINVAL; 132 133 *contentionScope = PTHREAD_SCOPE_SYSTEM; 134 return 0; 135 } 136 137 138 int 139 pthread_attr_setscope(pthread_attr_t *attr, int contentionScope) 140 { 141 if (attr == NULL) 142 return EINVAL; 143 144 if (contentionScope != PTHREAD_SCOPE_SYSTEM) 145 return ENOTSUP; 146 147 return 0; 148 } 149 150 151 int 152 pthread_attr_setschedparam(pthread_attr_t *attr, 153 const struct sched_param *param) 154 { 155 if (attr == NULL || param == NULL) 156 return EINVAL; 157 158 (*attr)->sched_priority = param->sched_priority; 159 160 return 0; 161 } 162 163 164 int 165 pthread_attr_getschedparam(const pthread_attr_t *attr, 166 struct sched_param *param) 167 { 168 if (attr == NULL || param == NULL) 169 return EINVAL; 170 171 param->sched_priority = (*attr)->sched_priority; 172 173 return 0; 174 } 175 176 177 int 178 pthread_attr_getguardsize(const pthread_attr_t *_attr, size_t *guardsize) 179 { 180 pthread_attr *attr; 181 182 if (_attr == NULL || (attr = *_attr) == NULL || guardsize == NULL) 183 return B_BAD_VALUE; 184 185 *guardsize = attr->guard_size; 186 187 return 0; 188 } 189 190 191 int 192 pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize) 193 { 194 pthread_attr *attr; 195 196 if (_attr == NULL || (attr = *_attr) == NULL) 197 return B_BAD_VALUE; 198 199 attr->guard_size = guardsize; 200 201 return 0; 202 } 203 204 205 int 206 pthread_attr_getstack(const pthread_attr_t *_attr, void **stackaddr, 207 size_t *stacksize) 208 { 209 pthread_attr *attr; 210 211 if (_attr == NULL || (attr = *_attr) == NULL || stackaddr == NULL 212 || stacksize == NULL) { 213 return B_BAD_VALUE; 214 } 215 216 *stacksize = attr->stack_size; 217 *stackaddr = attr->stack_address; 218 219 return 0; 220 } 221 222 223 int 224 pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr, 225 size_t stacksize) 226 { 227 pthread_attr *attr; 228 229 if (_attr == NULL || (attr = *_attr) == NULL) 230 return B_BAD_VALUE; 231 232 STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE 233 && PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE); 234 if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE) 235 return B_BAD_VALUE; 236 237 attr->stack_size = stacksize; 238 attr->stack_address = stackaddr; 239 240 return 0; 241 } 242 243 244 int 245 __pthread_attr_get_np(pthread_t thread, pthread_attr_t *_attr) 246 { 247 pthread_attr *attr; 248 status_t status; 249 thread_info info; 250 251 if (_attr == NULL || (attr = *_attr) == NULL) 252 return B_BAD_VALUE; 253 254 status = _kern_get_thread_info(thread->id, &info); 255 if (status == B_BAD_THREAD_ID) 256 return ESRCH; 257 258 if ((thread->flags & THREAD_DETACHED) != 0) 259 attr->detach_state = PTHREAD_CREATE_DETACHED; 260 else 261 attr->detach_state = PTHREAD_CREATE_JOINABLE; 262 attr->sched_priority = info.priority; 263 attr->stack_address = info.stack_base; 264 attr->stack_size = (size_t)info.stack_end - (size_t)info.stack_base; 265 // not in thread_info 266 attr->guard_size = 0; 267 268 return 0; 269 } 270 271 272 int 273 __pthread_getattr_np(pthread_t thread, pthread_attr_t *_attr) 274 { 275 int err = pthread_attr_init(_attr); 276 if (err == 0) 277 err = __pthread_attr_get_np(thread, _attr); 278 return err; 279 } 280 281 282 B_DEFINE_WEAK_ALIAS(__pthread_getattr_np, pthread_getattr_np); 283 B_DEFINE_WEAK_ALIAS(__pthread_attr_get_np, pthread_attr_get_np); 284 285