This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [basic-improvements] Remove __gthread_key_dtor
Zack,
> Okay, but what I don't get is why this translates to a requirement
> that every registered TSD destructor hook call back into gthr.h.
> In fact, I don't see what TSD has to do with mutexes at all.
>
re mutexes: Sony only has mutexes and not a real thread system at all.
So, we get to "invent" things via locking and mutexes.
Now, I may have a problem with my implementation based on rth's email,
but here's the dtor function as it currently exists:
static inline int
__gthread_key_dtor (__gthread_key_t key, void *ptr)
{
/* Just reset the key value to zero. */
if (ptr)
return __gthread_setspecific (key, 0);
else
return 0;
}
I'll attach and old version of the file since it's currently undergoing
development. The mutex init function is incorrect, but that's mostly
because I couldn't find a good listing on the proper options to have :)
(There are only 253 mutexes available and we're trying to figure out
exactly how many can be used by gcc to decide whether or not we can just
lock a mutex or have to use a single mutex and spin on it... - advice
here would be wonderful.
-eric
--
Yeah, I used to play basketball...
/* Threads compatibility routines for libgcc2 for the Emotion Engine. */
/* Compile this one with gcc. */
/* Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Sony Computer Entertainment Inc. and
Eric Christopher <echristo@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef GCC_GTHR_EEKERNEL_H
#define GCC_GTHR_EEKERNEL_H
/* EE kernel threads specific definitions. */
#define __GTHREADS 1
typedef int __gthread_key_t;
typedef int __gthread_once_t;
typedef int __gthread_mutex_t;
typedef struct SemaParam
{
int currentCount;
int maxCount;
int initCount;
int numWaitThreads;
unsigned int attr;
unsigned int option;
}SemaParam;
#define __GTHREAD_ONCE_INIT 0
#define __GTHREAD_MUTEX_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define THR_ID_NUM 256
#define KEY_NUM 8
static void *key_value[THR_ID_NUM][KEY_NUM] = { { 0 }, { 0 } };
static int key_use[KEY_NUM] = { 0 };
/* Mutex for locking key bitmap. */
static __gthread_mutex_t key_mutex;
#ifdef __cplusplus
extern "C"
{
#endif
extern int GetThreadId(void);
extern int WaitSema(int);
extern int PollSema(int);
extern int SignalSema(int);
extern int CreateSema(struct SemaParam *);
#ifdef __cplusplus
}
#endif
extern int __sce_eh_sema_id;
static inline int
__gthread_active_p ()
{
return 1;
}
static inline int
__gthread_once (__gthread_once_t *once, void (*func) ())
{
return 0;
}
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *mutex)
{
SemaParam defaultSema;
defaultSema.currentCount = 0;
defaultSema.initCount = 0;
defaultSema.attr = 0;
*mutex = CreateSema (&defaultSema);
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
if (WaitSema(*mutex) == -1)
return -1;
else
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
{
if (PollSema(*mutex) == -1)
return -1;
return 0;
}
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
if (SignalSema(*mutex) == -1)
return -1;
return 0;
}
static inline int
__gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *))
{
int i;
__gthread_mutex_lock (&key_mutex);
for (i = 0; i < KEY_NUM; i++)
{
if (!key_use[i] && dtor != 0)
{
key_use[i] = 1;
__gthread_mutex_unlock (&key_mutex);
*keyp = i;
return 0;
}
}
__gthread_mutex_unlock (&key_mutex);
return -1;
}
static inline int
__gthread_key_delete (__gthread_key_t key)
{
int id;
__gthread_mutex_lock (&key_mutex);
/* Make sure we don't have a bogus key number. */
if (key > KEY_NUM)
{
__gthread_mutex_unlock (&key_mutex);
return -1;
}
if (key_use[key] != 0)
key_use[key] = 0;
/* Set the value of the key to 0 in all threads,
so that if a key is later used it's value is NULL. */
for (id = 0; id < THR_ID_NUM; id++)
key_value[id][key] = 0;
__gthread_mutex_unlock (&key_mutex);
return 0;
}
static inline void *
__gthread_getspecific (__gthread_key_t key)
{
if (key > KEY_NUM || !key_use[key])
return 0;
return key_value[GetThreadId ()][key];
}
static inline int
__gthread_setspecific (__gthread_key_t key, const void *ptr)
{
if (key > KEY_NUM || !key_use[key])
return -1;
key_value[GetThreadId ()][key] = (void *)ptr;
return 0;
}
static inline int
__gthread_key_dtor (__gthread_key_t key, void *ptr)
{
/* Just reset the key value to zero. */
if (ptr)
return __gthread_setspecific (key, 0);
else
return 0;
}
#endif /* not GCC_GTHR_EEKERNEL_H */