gthr-vxworks.h revision 117395
1/* Threads compatibility routines for libgcc2 and libobjc for VxWorks. */ 2/* Compile this one with gcc. */ 3/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. 4 Contributed by Mike Stump <mrs@wrs.com>. 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 2, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License 19along with GCC; see the file COPYING. If not, write to the Free 20Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2102111-1307, USA. */ 22 23/* As a special exception, if you link this library with other files, 24 some of which are compiled with GCC, to produce an executable, 25 this library does not by itself cause the resulting executable 26 to be covered by the GNU General Public License. 27 This exception does not however invalidate any other reasons why 28 the executable file might be covered by the GNU General Public License. */ 29 30#ifndef GCC_GTHR_VXWORKS_H 31#define GCC_GTHR_VXWORKS_H 32 33#ifdef _LIBOBJC 34 35/* Thread local storage for a single thread */ 36static void *thread_local_storage = NULL; 37 38/* Backend initialization functions */ 39 40/* Initialize the threads subsystem. */ 41int 42__gthread_objc_init_thread_system (void) 43{ 44 /* No thread support available */ 45 return -1; 46} 47 48/* Close the threads subsystem. */ 49int 50__gthread_objc_close_thread_system (void) 51{ 52 /* No thread support available */ 53 return -1; 54} 55 56/* Backend thread functions */ 57 58/* Create a new thread of execution. */ 59objc_thread_t 60__gthread_objc_thread_detach (void (*func)(void *arg), void *arg) 61{ 62 /* No thread support available */ 63 return NULL; 64} 65 66/* Set the current thread's priority. */ 67int 68__gthread_objc_thread_set_priority (int priority) 69{ 70 /* No thread support available */ 71 return -1; 72} 73 74/* Return the current thread's priority. */ 75int 76__gthread_objc_thread_get_priority (void) 77{ 78 return OBJC_THREAD_INTERACTIVE_PRIORITY; 79} 80 81/* Yield our process time to another thread. */ 82void 83__gthread_objc_thread_yield (void) 84{ 85 return; 86} 87 88/* Terminate the current thread. */ 89int 90__gthread_objc_thread_exit (void) 91{ 92 /* No thread support available */ 93 /* Should we really exit the program */ 94 /* exit (&__objc_thread_exit_status); */ 95 return -1; 96} 97 98/* Returns an integer value which uniquely describes a thread. */ 99objc_thread_t 100__gthread_objc_thread_id (void) 101{ 102 /* No thread support, use 1. */ 103 return (objc_thread_t) 1; 104} 105 106/* Sets the thread's local storage pointer. */ 107int 108__gthread_objc_thread_set_data (void *value) 109{ 110 thread_local_storage = value; 111 return 0; 112} 113 114/* Returns the thread's local storage pointer. */ 115void * 116__gthread_objc_thread_get_data (void) 117{ 118 return thread_local_storage; 119} 120 121/* Backend mutex functions */ 122 123/* Allocate a mutex. */ 124int 125__gthread_objc_mutex_allocate (objc_mutex_t mutex) 126{ 127 return 0; 128} 129 130/* Deallocate a mutex. */ 131int 132__gthread_objc_mutex_deallocate (objc_mutex_t mutex) 133{ 134 return 0; 135} 136 137/* Grab a lock on a mutex. */ 138int 139__gthread_objc_mutex_lock (objc_mutex_t mutex) 140{ 141 /* There can only be one thread, so we always get the lock */ 142 return 0; 143} 144 145/* Try to grab a lock on a mutex. */ 146int 147__gthread_objc_mutex_trylock (objc_mutex_t mutex) 148{ 149 /* There can only be one thread, so we always get the lock */ 150 return 0; 151} 152 153/* Unlock the mutex */ 154int 155__gthread_objc_mutex_unlock (objc_mutex_t mutex) 156{ 157 return 0; 158} 159 160/* Backend condition mutex functions */ 161 162/* Allocate a condition. */ 163int 164__gthread_objc_condition_allocate (objc_condition_t condition) 165{ 166 return 0; 167} 168 169/* Deallocate a condition. */ 170int 171__gthread_objc_condition_deallocate (objc_condition_t condition) 172{ 173 return 0; 174} 175 176/* Wait on the condition */ 177int 178__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 179{ 180 return 0; 181} 182 183/* Wake up all threads waiting on this condition. */ 184int 185__gthread_objc_condition_broadcast (objc_condition_t condition) 186{ 187 return 0; 188} 189 190/* Wake up one thread waiting on this condition. */ 191int 192__gthread_objc_condition_signal (objc_condition_t condition) 193{ 194 return 0; 195} 196 197#else /* _LIBOBJC */ 198 199/* POSIX threads specific definitions. 200 Easy, since the interface is just one-to-one mapping. */ 201 202#define __GTHREADS 1 203 204#include <vxWorks.h> 205#include <semLib.h> 206/* typedef void *SEM_ID; */ 207 208typedef int __gthread_key_t; 209typedef char __gthread_once_t; 210typedef SEM_ID __gthread_mutex_t; 211 212#define __GTHREAD_MUTEX_INIT 0 213#define __GTHREAD_ONCE_INIT 0 214 215#ifndef REG_SAVED_REG 216static inline int 217__gthread_once (__gthread_once_t *once, void (*func) (void)) 218{ 219 (*func)(); 220 return 0; 221} 222 223extern __gthread_key_t eh_context_key; 224 225/* This is not the right way to do it, but the semantic of pthreads 226 don't map well enough onto VxWorks. */ 227 228static void 229__ehdtor (void *pTcb) 230{ 231 int tid = (int) pTcb; 232 void *p = (void *) taskVarGet (tid, &eh_context_key); 233 if (p != (void *) -1) 234 { 235 if (p) 236 free (p); 237 taskVarSet (tid, &eh_context_key, 0); 238 } 239} 240 241/* This only works for the code in libgcc2.c. */ 242 243static inline int 244__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) 245{ 246 *key = 0; 247 248 /* Do this first so that the task variables are visible during the 249 running of the delete hook. */ 250 251 taskVarInit (); 252 253 /* We don't have a way to track dtor here, so instead, we 254 register a generic routine that can cleanup any task. */ 255 256 taskDeleteHookAdd (__ehdtor); 257 258 return 0; 259} 260 261#define __gthread_setspecific(key, ptr) \ 262 (key = (int) ptr, 0) 263 264static inline int 265__gthread_key_dtor (__gthread_key_t key, void *ptr) 266{ 267 /* Just reset the key value to zero. */ 268 if (ptr) 269 return __gthread_setspecific (key, 0); 270 else 271 return 0; 272} 273 274#define __gthread_key_delete(key) \ 275 taskVarDelete (taskIdSelf (), &key) 276 277#define __gthread_getspecific(key) \ 278 ((key == 0) \ 279 ? ((taskVarAdd (taskIdSelf (), &key) != OK) \ 280 ? (__terminate (), (void *) 0) \ 281 : (void *) 0) \ 282 : (void *) key) 283#endif 284 285static inline int 286__gthread_mutex_lock (__gthread_mutex_t *mutex) 287{ 288 if (*mutex == 0) 289 *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE); 290 return semTake (*mutex, WAIT_FOREVER); 291} 292 293static inline int 294__gthread_mutex_trylock (__gthread_mutex_t *mutex) 295{ 296 if (*mutex == 0) 297 *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE); 298 return semTake (*mutex, NO_WAIT); 299} 300 301static inline int 302__gthread_mutex_unlock (__gthread_mutex_t *mutex) 303{ 304 /* We could return the */ 305 return semGive (*mutex); 306} 307 308#endif /* _LIBOBJC */ 309 310#endif /* ! GCC_GTHR_VXWORKS_H */ 311