190075Sobrien/* Threads compatibility routines for libgcc2 and libobjc for VxWorks.  */
250397Sobrien/* Compile this one with gcc.  */
390075Sobrien/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
450397Sobrien   Contributed by Mike Stump <mrs@wrs.com>.
550397Sobrien
690075SobrienThis file is part of GCC.
750397Sobrien
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1250397Sobrien
1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690075Sobrienfor more details.
1750397Sobrien
1850397SobrienYou should have received a copy of the GNU General Public License
1990075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169689Skan02110-1301, USA.  */
2250397Sobrien
2350397Sobrien/* As a special exception, if you link this library with other files,
2450397Sobrien   some of which are compiled with GCC, to produce an executable,
2550397Sobrien   this library does not by itself cause the resulting executable
2650397Sobrien   to be covered by the GNU General Public License.
2750397Sobrien   This exception does not however invalidate any other reasons why
2850397Sobrien   the executable file might be covered by the GNU General Public License.  */
2950397Sobrien
3090075Sobrien#ifndef GCC_GTHR_VXWORKS_H
3190075Sobrien#define GCC_GTHR_VXWORKS_H
3250397Sobrien
3390075Sobrien#ifdef _LIBOBJC
3490075Sobrien
35132718Skan/* libobjc requires the optional pthreads component.  */
36132718Skan#include "gthr-posix.h"
3790075Sobrien
38132718Skan#else
3990075Sobrien
40132718Skan#define __GTHREADS 1
41132718Skan#define __gthread_active_p() 1
4290075Sobrien
43132718Skan/* Mutexes are easy, except that they need to be initialized at runtime.  */
4490075Sobrien
45132718Skan#include <semLib.h>
4690075Sobrien
47132718Skantypedef SEM_ID __gthread_mutex_t;
48169689Skan/* All VxWorks mutexes are recursive.  */
49169689Skantypedef SEM_ID __gthread_recursive_mutex_t;
50132718Skan#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
51169689Skan#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
5290075Sobrien
53132718Skanstatic inline void
54132718Skan__gthread_mutex_init_function (__gthread_mutex_t *mutex)
5590075Sobrien{
56132718Skan  *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
5790075Sobrien}
5890075Sobrien
59132718Skanstatic inline int
60132718Skan__gthread_mutex_lock (__gthread_mutex_t *mutex)
6190075Sobrien{
62132718Skan  return semTake (*mutex, WAIT_FOREVER);
6390075Sobrien}
6490075Sobrien
65132718Skanstatic inline int
66132718Skan__gthread_mutex_trylock (__gthread_mutex_t *mutex)
6790075Sobrien{
68132718Skan  return semTake (*mutex, NO_WAIT);
6990075Sobrien}
7090075Sobrien
7150397Sobrienstatic inline int
72132718Skan__gthread_mutex_unlock (__gthread_mutex_t *mutex)
7350397Sobrien{
74132718Skan  return semGive (*mutex);
7550397Sobrien}
7650397Sobrien
77169689Skanstatic inline void
78169689Skan__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
79169689Skan{
80169689Skan  __gthread_mutex_init_function (mutex);
81169689Skan}
82169689Skan
83169689Skanstatic inline int
84169689Skan__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
85169689Skan{
86169689Skan  return __gthread_mutex_lock (mutex);
87169689Skan}
88169689Skan
89169689Skanstatic inline int
90169689Skan__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
91169689Skan{
92169689Skan  return __gthread_mutex_trylock (mutex);
93169689Skan}
94169689Skan
95169689Skanstatic inline int
96169689Skan__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
97169689Skan{
98169689Skan  return __gthread_mutex_unlock (mutex);
99169689Skan}
100169689Skan
101132718Skan/* pthread_once is complicated enough that it's implemented
102132718Skan   out-of-line.  See config/vxlib.c.  */
10350397Sobrien
104132718Skantypedef struct
10550397Sobrien{
106132718Skan  volatile unsigned char busy;
107132718Skan  volatile unsigned char done;
10850397Sobrien}
109132718Skan__gthread_once_t;
11050397Sobrien
111132718Skan#define __GTHREAD_ONCE_INIT { 0, 0 }
11250397Sobrien
113132718Skanextern int __gthread_once (__gthread_once_t *once, void (*func)(void));
11450397Sobrien
115132718Skan/* Thread-specific data requires a great deal of effort, since VxWorks
116132718Skan   is not really set up for it.  See config/vxlib.c for the gory
117132718Skan   details.  All the TSD routines are sufficiently complex that they
118132718Skan   need to be implemented out of line.  */
11952284Sobrien
120132718Skantypedef unsigned int __gthread_key_t;
12152284Sobrien
122132718Skanextern int __gthread_key_create (__gthread_key_t *keyp, void (*dtor)(void *));
123132718Skanextern int __gthread_key_delete (__gthread_key_t key);
12450397Sobrien
125132718Skanextern void *__gthread_getspecific (__gthread_key_t key);
126132718Skanextern int __gthread_setspecific (__gthread_key_t key, void *ptr);
12750397Sobrien
128132718Skan#endif /* not _LIBOBJC */
12950397Sobrien
130132718Skan#endif /* gthr-vxworks.h */
131