Added the missing POSIX_NO_YIELD and POSIX_NO_PRIORITIES warning messages.

2000-03-17  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>

	* configure.in: Added the missing POSIX_NO_YIELD and
	POSIX_NO_PRIORITIES warning messages.

	* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
	real thread support. On solaris pthread_create can be linked to
	even in -lc, but it doesn't work then.

	* configure.in: Don't use priorities for threads, when the
	minimal/maximal priorities couldn't be determined at configure
	time.

	* configure.in, gthread.c: Always define GSystemThread in
	glibconfig.h to represent a system thread.

	* configure.in: Do not use native recursive threads, when
	possibe. We use some features, that they do not expose (namely the
	depth counter).

	* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
	now implemented in a different way, which should be way
	faster. Alsothere are now functions g_static_rec_mutex_unlock_full
	and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
	completly.

	* gthread.c (g_thread_self): Do not test the system_thread to be
	non-zero to speed things up.

	* gthread.c (g_mutex_init): Therefore set the system_thread of the
	main thread here.

	* tests/thread-test.c: Rerun all tests once again, but this time
	we fool the system into thinking, that the available thread system
	is not native, but userprovided.

	* gthread/gthread-posix.c: Don't use priorities for threads,
	when the minimal/maximal priorities couldn't be determined at
	configure time.

	* gthread/gthread-posix.c: Don't check for errors, when
	setting the scope of a tread to system, as some posix
	implementations can't do that and we don't want the thing to
	fail because of that.
This commit is contained in:
Sebastian Wilhelmi
2000-03-17 14:49:59 +00:00
committed by Sebastian Wilhelmi
parent 3540769b17
commit 5e7134375e
17 changed files with 613 additions and 273 deletions

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -1,3 +1,39 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Added the missing POSIX_NO_YIELD and
POSIX_NO_PRIORITIES warning messages.
* configure.in: Use AC_TRY_RUN instead of AC_TRY_LINK, to test for
real thread support. On solaris pthread_create can be linked to
even in -lc, but it doesn't work then.
* configure.in: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* configure.in, gthread.c: Always define GSystemThread in
glibconfig.h to represent a system thread.
* configure.in: Do not use native recursive threads, when
possibe. We use some features, that they do not expose (namely the
depth counter).
* glib.h, gthread.c: Redefined GStaticRecMutex. The functions are
now implemented in a different way, which should be way
faster. Alsothere are now functions g_static_rec_mutex_unlock_full
and g_static_rec_mutex_lock_full to leave/enter a recursive mutex
completly.
* gthread.c (g_thread_self): Do not test the system_thread to be
non-zero to speed things up.
* gthread.c (g_mutex_init): Therefore set the system_thread of the
main thread here.
* tests/thread-test.c: Rerun all tests once again, but this time
we fool the system into thinking, that the available thread system
is not native, but userprovided.
2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-03-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We * gqueue.c (g_queue_push_tail_link, g_queue_push_head_link): We

View File

@@ -648,7 +648,7 @@ dnl *************************
THREAD_NO_IMPLEMENTATION="You do not have any known thread system on your THREAD_NO_IMPLEMENTATION="You do not have any known thread system on your
computer. GLib will not have a default thread implementation." computer. GLib will not have a default thread implementation."
FLAG_DOES_NOT_WORK="I can't find the MACRO, that enables thread safety on your FLAG_DOES_NOT_WORK="I can't find the MACRO to enable thread safety on your
platform (normaly it's "_REENTRANT"). I'll not use any flag on platform (normaly it's "_REENTRANT"). I'll not use any flag on
compilation now, but then your programs might not work. compilation now, but then your programs might not work.
Please provide information on how it is done on your system." Please provide information on how it is done on your system."
@@ -668,6 +668,17 @@ FUNC_NO_GETPWUID_R="the 'g_get_(user_name|real_name|home_dir|tmp_dir)'
FUNC_NO_LOCALTIME_R="the 'g_date_set_time' function will not be MT-safe FUNC_NO_LOCALTIME_R="the 'g_date_set_time' function will not be MT-safe
because there is no 'localtime_r' on your system." because there is no 'localtime_r' on your system."
POSIX_NO_YIELD="I can not find a yield functions for your platform. A rather
crude surrogate will be used. If you happen to know a
yield function for your system, please inform the GLib
developers."
POSIX_NO_PRIORITIES="I can not find the minimal and maximal priorities for
threads on your system. Thus threads can only have the default
priority. If you happen to know these main/max
priorities, please inform the GLib developers."
dnl determination of thread implementation dnl determination of thread implementation
dnl *************************************** dnl ***************************************
@@ -682,7 +693,7 @@ fi
if test "x$want_threads" = xyes || test "x$want_threads" = xposix \ if test "x$want_threads" = xyes || test "x$want_threads" = xposix \
|| test "x$want_threads" = xdce; then || test "x$want_threads" = xdce; then
# -D_POSIX4A_DRAFT10_SOURCE is for DG/UX # -D_POSIX4A_DRAFT10_SOURCE is for DG/UX
# -U_OSF_SOURCE if for Digital UNIX 4.0d # -U_OSF_SOURCE is for Digital UNIX 4.0d
GTHREAD_COMPILE_IMPL_DEFINES="-D_POSIX4A_DRAFT10_SOURCE -U_OSF_SOURCE" GTHREAD_COMPILE_IMPL_DEFINES="-D_POSIX4A_DRAFT10_SOURCE -U_OSF_SOURCE"
glib_save_CPPFLAGS="$CPPFLAGS" glib_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES" CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES"
@@ -731,12 +742,22 @@ case $have_threads in
add_thread_lib="-l$thread_lib" add_thread_lib="-l$thread_lib"
IN=" in -l$thread_lib" IN=" in -l$thread_lib"
fi fi
if test x"$have_threads" = xposix; then
defattr=NULL
else
defattr=pthread_attr_default
fi
LIBS="$glib_save_LIBS $add_thread_lib" LIBS="$glib_save_LIBS $add_thread_lib"
AC_MSG_CHECKING(for pthread_join$IN) AC_MSG_CHECKING(for pthread_join$IN)
AC_TRY_LINK([#include <pthread.h>], AC_TRY_RUN([#include <pthread.h>
[pthread_t t; pthread_join(t,NULL)], void* func(void* data) {}
main()
{ pthread_t t;
exit(pthread_create (&t, $defattr, func,
NULL));
}],
[AC_MSG_RESULT(yes) [AC_MSG_RESULT(yes)
G_THREAD_LIBS="$add_thread_lib" G_THREAD_LIBS="$add_thread_lib"
break], break],
@@ -874,6 +895,8 @@ if test x"$enable_threads" = xyes; then
fi fi
LIBS="$LIBS $G_THREAD_LIBS" LIBS="$LIBS $G_THREAD_LIBS"
if test x"$have_threads" = xposix; then if test x"$have_threads" = xposix; then
glib_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES"
GLIB_SIZEOF([#include <pthread.h>], GLIB_SIZEOF([#include <pthread.h>],
pthread_t, pthread_t,
system_thread) system_thread)
@@ -917,13 +940,13 @@ if test x"$enable_threads" = xyes; then
if test x"$posix_priority_min" = xnone; then if test x"$posix_priority_min" = xnone; then
AC_MSG_RESULT(none found) AC_MSG_RESULT(none found)
AC_MSG_WARN($POSIX_NO_PRIORITIES) AC_MSG_WARN($POSIX_NO_PRIORITIES)
posix_priority_min=1 posix_priority_min=-1
posix_priority_max=1 posix_priority_max=-1
else else
AC_MSG_RESULT($posix_priority_min/$posix_priority_max) AC_MSG_RESULT($posix_priority_min/$posix_priority_max)
AC_DEFINE_UNQUOTED(POSIX_MIN_PRIORITY,$posix_priority_min)
AC_DEFINE_UNQUOTED(POSIX_MAX_PRIORITY,$posix_priority_max)
fi fi
AC_DEFINE_UNQUOTED(POSIX_MIN_PRIORITY,$posix_priority_min)
AC_DEFINE_UNQUOTED(POSIX_MAX_PRIORITY,$posix_priority_max)
posix_yield_func=none posix_yield_func=none
AC_MSG_CHECKING(for posix yield function) AC_MSG_CHECKING(for posix yield function)
for yield_func in pthread_yield_np pthread_yield sched_yield \ for yield_func in pthread_yield_np pthread_yield sched_yield \
@@ -942,10 +965,11 @@ if test x"$enable_threads" = xyes; then
posix_yield_func="$posix_yield_func()" posix_yield_func="$posix_yield_func()"
fi fi
AC_DEFINE_UNQUOTED(POSIX_YIELD_FUNC,$posix_yield_func) AC_DEFINE_UNQUOTED(POSIX_YIELD_FUNC,$posix_yield_func)
else CPPFLAGS="$glib_save_CPPFLAGS"
# for now, the only other implementation is solaris else # solaris threads
# -> there 4 bytes are enough GLIB_SIZEOF([#include <thread.h>],
AC_DEFINE_UNQUOTED(GLIB_SIZEOF_SYSTEM_THREAD, 4) thread_t,
system_thread)
fi fi
LIBS="$glib_save_LIBS" LIBS="$glib_save_LIBS"
@@ -958,6 +982,10 @@ if test x"$enable_threads" = xyes; then
if test "$ac_cv_func_localtime_r" != "yes"; then if test "$ac_cv_func_localtime_r" != "yes"; then
AC_MSG_WARN($FUNC_NO_LOCALTIME_R) AC_MSG_WARN($FUNC_NO_LOCALTIME_R)
fi fi
else
# If no thread implementation exists, we will provide enough
# space for a pointer
GLIB_SIZEOF(, void*, system_thread)
fi fi
AC_DEFINE_UNQUOTED(G_THREAD_SOURCE,"gthread-$have_threads.c") AC_DEFINE_UNQUOTED(G_THREAD_SOURCE,"gthread-$have_threads.c")
@@ -974,6 +1002,10 @@ dnl
dnl if mutex_has_default = yes, we also got dnl if mutex_has_default = yes, we also got
dnl mutex_default_type, mutex_default_init and mutex_header_file dnl mutex_default_type, mutex_default_init and mutex_header_file
GLIB_IF_VAR_EQ(mutex_has_default, yes, GLIB_IF_VAR_EQ(mutex_has_default, yes,
glib_save_CPPFLAGS="$CPPFLAGS"
glib_save_LIBS="$LIBS"
LIBS="$LIBS $G_THREAD_LIBS"
CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES"
GLIB_SIZEOF([#include <$mutex_header_file>], GLIB_SIZEOF([#include <$mutex_header_file>],
$mutex_default_type, $mutex_default_type,
gmutex, gmutex,
@@ -986,14 +1018,8 @@ GLIB_IF_VAR_EQ(mutex_has_default, yes,
if test x"$glib_cv_byte_contents_gmutex" = xno; then if test x"$glib_cv_byte_contents_gmutex" = xno; then
mutex_has_default=no mutex_has_default=no
fi fi
if test x"$have_threads" = xposix; then CPPFLAGS="$glib_save_CPPFLAGS"
GLIB_BYTE_CONTENTS([#define __USE_GNU LIBS="$glib_save_LIBS"
#include <$mutex_header_file>],
$mutex_default_type,
grecmutex,
$glib_cv_sizeof_gmutex,
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
fi
, ,
) )
@@ -1184,32 +1210,21 @@ typedef struct _GMutex* GStaticMutex;
#define g_static_mutex_get_mutex(mutex) (g_static_mutex_get_mutex_impl (mutex)) #define g_static_mutex_get_mutex(mutex) (g_static_mutex_get_mutex_impl (mutex))
_______EOF _______EOF
fi fi
if test x$g_recmutex_contents != xno -a \
x$g_recmutex_contents != x; then cat >>$outfile <<_______EOF
# the definition of GStaticRecMutex is not done via /* This represents a system thread as used by the implementation. An
# typedef GStaticMutex GStaticRecMutex to avoid silent * alien implementaion, as loaded by g_thread_init can only count on
# compilation, when a GStaticRecMutex is used where a * "sizeof (gpointer)" bytes to store their info. We however need more
# GStaticMutex should have been used and vice versa, * for some of our native implementations. */
# because that might fail on other platforms. typedef union _GSystemThread GSystemThread;
cat >>$outfile <<_______EOF union _GSystemThread
typedef struct _GStaticRecMutex GStaticRecMutex;
struct _GStaticRecMutex
{ {
struct _GMutex *runtime_mutex; char data[$g_system_thread_sizeof];
union { double dummy_double;
char pad[$g_mutex_sizeof]; void *dummy_pointer;
double dummy_double; long dummy_long;
void *dummy_pointer;
long dummy_long;
} aligned_pad_u;
}; };
#define G_STATIC_REC_MUTEX_INIT { NULL, { { $g_recmutex_contents} } }
#define g_static_rec_mutex_lock(mutex) g_static_mutex_lock (mutex)
#define g_static_rec_mutex_trylock(mutex) g_static_mutex_trylock (mutex)
#define g_static_rec_mutex_unlock(mutex) g_static_mutex_unlock (mutex)
#define g_static_rec_mutex_get_mutex(mutex) (mutex)
_______EOF _______EOF
fi
echo >>$outfile echo >>$outfile
g_bit_sizes="16 32" g_bit_sizes="16 32"
@@ -1456,8 +1471,8 @@ g_threads_impl_def=$g_threads_impl
g_mutex_has_default="$mutex_has_default" g_mutex_has_default="$mutex_has_default"
g_mutex_sizeof="$glib_cv_sizeof_gmutex" g_mutex_sizeof="$glib_cv_sizeof_gmutex"
g_system_thread_sizeof="$glib_cv_sizeof_system_thread"
g_mutex_contents="$glib_cv_byte_contents_gmutex" g_mutex_contents="$glib_cv_byte_contents_gmutex"
g_recmutex_contents="$glib_cv_byte_contents_grecmutex"
case $host in case $host in
*-*-beos*) *-*-beos*)

25
glib.h
View File

@@ -1,3 +1,4 @@
/* GLIB - Library of useful routines for C programming /* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* *
@@ -3062,24 +3063,22 @@ void g_static_private_set_for_thread (GStaticPrivate *private_key,
GThread *thread, GThread *thread,
gpointer data, gpointer data,
GDestroyNotify notify); GDestroyNotify notify);
#ifndef G_STATIC_REC_MUTEX_INIT
/* if GStaticRecMutex is not just a differently initialized GStaticMutex,
* the following is done:
* This can't be done in glibconfig.h, as GStaticPrivate and gboolean
* are not yet known there
*/
typedef struct _GStaticRecMutex GStaticRecMutex; typedef struct _GStaticRecMutex GStaticRecMutex;
struct _GStaticRecMutex struct _GStaticRecMutex
{ {
GStaticMutex mutex; GStaticMutex mutex;
GStaticPrivate counter; unsigned int depth;
GSystemThread owner;
}; };
#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT, G_STATIC_PRIVATE_INIT }
void g_static_rec_mutex_lock (GStaticRecMutex* mutex); #define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
gboolean g_static_rec_mutex_trylock (GStaticRecMutex* mutex); void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
void g_static_rec_mutex_unlock (GStaticRecMutex* mutex); gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
#define g_static_rec_mutex_get_mutex(mutex) ((mutex)->mutex) void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
#endif /* G_STATIC_REC_MUTEX_INIT */ void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
guint depth);
guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
typedef struct _GStaticRWLock GStaticRWLock; typedef struct _GStaticRWLock GStaticRWLock;
struct _GStaticRWLock struct _GStaticRWLock

View File

@@ -1,3 +1,4 @@
/* GLIB - Library of useful routines for C programming /* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* *
@@ -3062,24 +3063,22 @@ void g_static_private_set_for_thread (GStaticPrivate *private_key,
GThread *thread, GThread *thread,
gpointer data, gpointer data,
GDestroyNotify notify); GDestroyNotify notify);
#ifndef G_STATIC_REC_MUTEX_INIT
/* if GStaticRecMutex is not just a differently initialized GStaticMutex,
* the following is done:
* This can't be done in glibconfig.h, as GStaticPrivate and gboolean
* are not yet known there
*/
typedef struct _GStaticRecMutex GStaticRecMutex; typedef struct _GStaticRecMutex GStaticRecMutex;
struct _GStaticRecMutex struct _GStaticRecMutex
{ {
GStaticMutex mutex; GStaticMutex mutex;
GStaticPrivate counter; unsigned int depth;
GSystemThread owner;
}; };
#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT, G_STATIC_PRIVATE_INIT }
void g_static_rec_mutex_lock (GStaticRecMutex* mutex); #define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
gboolean g_static_rec_mutex_trylock (GStaticRecMutex* mutex); void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
void g_static_rec_mutex_unlock (GStaticRecMutex* mutex); gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
#define g_static_rec_mutex_get_mutex(mutex) ((mutex)->mutex) void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
#endif /* G_STATIC_REC_MUTEX_INIT */ void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
guint depth);
guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
typedef struct _GStaticRWLock GStaticRWLock; typedef struct _GStaticRWLock GStaticRWLock;
struct _GStaticRWLock struct _GStaticRWLock

View File

@@ -39,62 +39,29 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
typedef union _SystemThread SystemThread; #if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P
# define g_system_thread_equal(thread1, thread2) \
/* This represents a system thread as used by the implementation. An (thread1.dummy_pointer == thread2.dummy_pointer)
* alien implementaion, as loaded by g_thread_init can only count on # define g_system_thread_assign(dest, src) \
* "sizeof (gpointer)" bytes to store their info. We however need more (dest.dummy_pointer = src.dummy_pointer)
* for some of our native implementations. */ #else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */
union _SystemThread # define g_system_thread_equal(thread1, thread2) \
{ (memcmp (&thread1, &thread2, GLIB_SIZEOF_SYSTEM_THREAD) == 0)
guchar data[GLIB_SIZEOF_SYSTEM_THREAD]; # define g_system_thread_assign(dest, src) \
gdouble double_dummy; /* These are used for the right alignment */ (memcpy (&dest, &src, GLIB_SIZEOF_SYSTEM_THREAD))
gpointer pointer_dummy; #endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
#ifdef G_HAVE_GINT64
guint64 long_dummy;
#else
guint32 long_dummy;
#endif
};
typedef struct _GRealThread GRealThread; typedef struct _GRealThread GRealThread;
struct _GRealThread struct _GRealThread
{ {
GThread thread; GThread thread;
GThreadFunc func; GThreadFunc func;
gpointer arg; gpointer arg;
gpointer private_data; gpointer private_data;
SystemThread system_thread; GSystemThread system_thread;
}; };
#if (GLIB_SIZEOF_SYSTEM_THREAD <= 8 && defined(G_HAVE_GINT64)) \
|| (GLIB_SIZEOF_SYSTEM_THREAD <= 4)
/* We can use fast setting and checks */
# define set_system_thread_to_zero(t) (t->system_thread.long_dummy=0)
# define system_thread_is_not_zero(t) (t->system_thread.long_dummy)
#else
/* We have to do it the hard way and hope the compiler will optimize a bit */
static inline void
set_system_thread_to_zero(GRealThread* thread)
{
int i;
for (i = 0; i < GLIB_SIZEOF_SYSTEM_THREAD; i++)
thread->system_thread.data[i] = 0;
}
static inline gboolean
system_thread_is_not_zero(GRealThread* thread)
{
int i;
for (i = 0; i < GLIB_SIZEOF_SYSTEM_THREAD; i++)
if (thread->system_thread.data[i]) return FALSE;
return TRUE;
}
#endif
typedef struct _GStaticPrivateNode GStaticPrivateNode; typedef struct _GStaticPrivateNode GStaticPrivateNode;
struct _GStaticPrivateNode struct _GStaticPrivateNode
{ {
gpointer data; gpointer data;
@@ -106,6 +73,7 @@ static void g_thread_fail (void);
/* Global variables */ /* Global variables */
static GSystemThread zero_thread; /* This is initialized to all zero */
gboolean g_thread_use_default_impl = TRUE; gboolean g_thread_use_default_impl = TRUE;
gboolean g_threads_got_initialized = FALSE; gboolean g_threads_got_initialized = FALSE;
@@ -149,24 +117,19 @@ static GPrivate *g_thread_specific_private = NULL;
void void
g_mutex_init (void) g_mutex_init (void)
{ {
gpointer private_old; GRealThread* main_thread;
/* We let the main thread (the one that calls g_thread_init) inherit /* We let the main thread (the one that calls g_thread_init) inherit
* the data, that it set before calling g_thread_init * the data, that it set before calling g_thread_init
*/ */
private_old = g_thread_specific_private; main_thread = (GRealThread*) g_thread_self ();
g_thread_specific_private = g_private_new (g_thread_cleanup); g_thread_specific_private = g_private_new (g_thread_cleanup);
G_THREAD_UF (private_set, (g_thread_specific_private, main_thread));
/* we can not use g_private_set here, as g_threads_got_initialized is not G_THREAD_UF (thread_self, (&main_thread->system_thread));
* yet set TRUE, whereas the private_set function is already set.
*/
g_thread_functions_for_glib_use.private_set (g_thread_specific_private,
private_old);
g_mutex_protect_static_mutex_allocation = g_mutex_new(); g_mutex_protect_static_mutex_allocation = g_mutex_new();
g_thread_specific_mutex = g_mutex_new(); g_thread_specific_mutex = g_mutex_new();
} }
GMutex * GMutex *
@@ -187,47 +150,87 @@ g_static_mutex_get_mutex_impl (GMutex** mutex)
return *mutex; return *mutex;
} }
#ifndef g_static_rec_mutex_lock
/* That means, that g_static_rec_mutex_lock is not defined to be
* g_static_mutex_lock, we have to provide an implementation ourselves.
*/
void void
g_static_rec_mutex_lock (GStaticRecMutex* mutex) g_static_rec_mutex_lock (GStaticRecMutex* mutex)
{ {
guint counter = GPOINTER_TO_UINT (g_static_private_get (&mutex->counter)); GSystemThread self;
if (counter == 0)
g_return_if_fail (mutex);
G_THREAD_UF (thread_self, (&self));
if (g_system_thread_equal (self, mutex->owner))
{ {
g_static_mutex_lock (&mutex->mutex); mutex->depth++;
return;
} }
counter++; g_static_mutex_lock (&mutex->mutex);
g_static_private_set (&mutex->counter, GUINT_TO_POINTER (counter), NULL); g_system_thread_assign (mutex->owner, self);
mutex->depth = 1;
} }
gboolean gboolean
g_static_rec_mutex_trylock (GStaticRecMutex* mutex) g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
{ {
guint counter = GPOINTER_TO_UINT (g_static_private_get (&mutex->counter)); GSystemThread self;
if (counter == 0)
g_return_val_if_fail (mutex, FALSE);
G_THREAD_UF (thread_self, (&self));
if (g_system_thread_equal (self, mutex->owner))
{ {
if (!g_static_mutex_trylock (&mutex->mutex)) return FALSE; mutex->depth++;
return TRUE;
} }
counter++;
g_static_private_set (&mutex->counter, GUINT_TO_POINTER (counter), NULL); if (!g_static_mutex_trylock (&mutex->mutex))
return FALSE;
g_system_thread_assign (mutex->owner, self);
mutex->depth = 1;
return TRUE; return TRUE;
} }
void void
g_static_rec_mutex_unlock (GStaticRecMutex* mutex) g_static_rec_mutex_unlock (GStaticRecMutex* mutex)
{ {
guint counter = GPOINTER_TO_UINT (g_static_private_get (&mutex->counter)); g_return_if_fail (mutex);
if (counter == 1)
if (mutex->depth > 1)
{ {
g_static_mutex_unlock (&mutex->mutex); mutex->depth--;
return;
} }
counter--; g_system_thread_assign (mutex->owner, zero_thread);
g_static_private_set (&mutex->counter, GUINT_TO_POINTER (counter), NULL); g_static_mutex_unlock (&mutex->mutex);
} }
#endif /* g_static_rec_mutex_lock */
void
g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
guint depth)
{
g_return_if_fail (mutex);
g_static_mutex_lock (&mutex->mutex);
G_THREAD_UF (thread_self, (&mutex->owner));
mutex->depth = depth;
}
guint
g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
{
gint depth = mutex->depth;
g_return_val_if_fail (mutex, 0);
g_system_thread_assign (mutex->owner, zero_thread);
mutex->depth = 0;
g_static_mutex_unlock (&mutex->mutex);
return depth;
}
gpointer gpointer
g_static_private_get (GStaticPrivate *private_key) g_static_private_get (GStaticPrivate *private_key)
@@ -341,7 +344,7 @@ g_thread_cleanup (gpointer data)
if (!thread->thread.joinable) if (!thread->thread.joinable)
{ {
/* Just to make sure, this isn't used any more */ /* Just to make sure, this isn't used any more */
set_system_thread_to_zero(thread); g_system_thread_assign (thread->system_thread, zero_thread);
g_free (thread); g_free (thread);
} }
} }
@@ -380,7 +383,7 @@ g_thread_create (GThreadFunc thread_func,
gboolean bound, gboolean bound,
GThreadPriority priority) GThreadPriority priority)
{ {
GRealThread* result = g_new0 (GRealThread,1); GRealThread* result = g_new (GRealThread, 1);
g_return_val_if_fail (thread_func, NULL); g_return_val_if_fail (thread_func, NULL);
@@ -389,6 +392,7 @@ g_thread_create (GThreadFunc thread_func,
result->thread.priority = priority; result->thread.priority = priority;
result->func = thread_func; result->func = thread_func;
result->arg = arg; result->arg = arg;
result->private_data = NULL;
G_LOCK (g_thread_create); G_LOCK (g_thread_create);
G_THREAD_UF (thread_create, (g_thread_create_proxy, result, stack_size, G_THREAD_UF (thread_create, (g_thread_create_proxy, result, stack_size,
joinable, bound, priority, joinable, bound, priority,
@@ -405,13 +409,13 @@ g_thread_join (GThread* thread)
g_return_if_fail (thread); g_return_if_fail (thread);
g_return_if_fail (thread->joinable); g_return_if_fail (thread->joinable);
g_return_if_fail (system_thread_is_not_zero (real)); g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
G_THREAD_UF (thread_join, (&real->system_thread)); G_THREAD_UF (thread_join, (&real->system_thread));
/* Just to make sure, this isn't used any more */ /* Just to make sure, this isn't used any more */
thread->joinable = 0; thread->joinable = 0;
set_system_thread_to_zero (real); g_system_thread_assign (real->system_thread, zero_thread);
/* the thread structure for non-joinable threads is freed upon /* the thread structure for non-joinable threads is freed upon
thread end. We free the memory here. This will leave loose end, thread end. We free the memory here. This will leave loose end,
@@ -427,7 +431,7 @@ g_thread_set_priority (GThread* thread,
GRealThread* real = (GRealThread*) thread; GRealThread* real = (GRealThread*) thread;
g_return_if_fail (thread); g_return_if_fail (thread);
g_return_if_fail (system_thread_is_not_zero (real)); g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
thread->priority = priority; thread->priority = priority;
G_THREAD_CF (thread_set_priority, (void)0, (&real->system_thread, priority)); G_THREAD_CF (thread_set_priority, (void)0, (&real->system_thread, priority));
@@ -442,22 +446,20 @@ g_thread_self()
{ {
/* If no thread data is available, provide and set one. This /* If no thread data is available, provide and set one. This
can happen for the main thread and for threads, that are not can happen for the main thread and for threads, that are not
created by glib. */ created by GLib. */
thread = g_new (GRealThread,1); thread = g_new (GRealThread, 1);
thread->thread.joinable = FALSE; /* This is a save guess */ thread->thread.joinable = FALSE; /* This is a save guess */
thread->thread.bound = TRUE; /* This isn't important at all */ thread->thread.bound = TRUE; /* This isn't important at all */
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
just a guess */ just a guess */
thread->func = NULL; thread->func = NULL;
thread->arg = NULL; thread->arg = NULL;
set_system_thread_to_zero (thread);
thread->private_data = NULL; thread->private_data = NULL;
g_private_set (g_thread_specific_private, thread);
}
if (g_thread_supported () && !system_thread_is_not_zero(thread)) if (g_thread_supported ())
{ G_THREAD_UF (thread_self, (&thread->system_thread));
g_thread_functions_for_glib_use.thread_self(&thread->system_thread);
g_private_set (g_thread_specific_private, thread);
} }
return (GThread*)thread; return (GThread*)thread;

176
gthread.c
View File

@@ -39,62 +39,29 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
typedef union _SystemThread SystemThread; #if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P
# define g_system_thread_equal(thread1, thread2) \
/* This represents a system thread as used by the implementation. An (thread1.dummy_pointer == thread2.dummy_pointer)
* alien implementaion, as loaded by g_thread_init can only count on # define g_system_thread_assign(dest, src) \
* "sizeof (gpointer)" bytes to store their info. We however need more (dest.dummy_pointer = src.dummy_pointer)
* for some of our native implementations. */ #else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */
union _SystemThread # define g_system_thread_equal(thread1, thread2) \
{ (memcmp (&thread1, &thread2, GLIB_SIZEOF_SYSTEM_THREAD) == 0)
guchar data[GLIB_SIZEOF_SYSTEM_THREAD]; # define g_system_thread_assign(dest, src) \
gdouble double_dummy; /* These are used for the right alignment */ (memcpy (&dest, &src, GLIB_SIZEOF_SYSTEM_THREAD))
gpointer pointer_dummy; #endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
#ifdef G_HAVE_GINT64
guint64 long_dummy;
#else
guint32 long_dummy;
#endif
};
typedef struct _GRealThread GRealThread; typedef struct _GRealThread GRealThread;
struct _GRealThread struct _GRealThread
{ {
GThread thread; GThread thread;
GThreadFunc func; GThreadFunc func;
gpointer arg; gpointer arg;
gpointer private_data; gpointer private_data;
SystemThread system_thread; GSystemThread system_thread;
}; };
#if (GLIB_SIZEOF_SYSTEM_THREAD <= 8 && defined(G_HAVE_GINT64)) \
|| (GLIB_SIZEOF_SYSTEM_THREAD <= 4)
/* We can use fast setting and checks */
# define set_system_thread_to_zero(t) (t->system_thread.long_dummy=0)
# define system_thread_is_not_zero(t) (t->system_thread.long_dummy)
#else
/* We have to do it the hard way and hope the compiler will optimize a bit */
static inline void
set_system_thread_to_zero(GRealThread* thread)
{
int i;
for (i = 0; i < GLIB_SIZEOF_SYSTEM_THREAD; i++)
thread->system_thread.data[i] = 0;
}
static inline gboolean
system_thread_is_not_zero(GRealThread* thread)
{
int i;
for (i = 0; i < GLIB_SIZEOF_SYSTEM_THREAD; i++)
if (thread->system_thread.data[i]) return FALSE;
return TRUE;
}
#endif
typedef struct _GStaticPrivateNode GStaticPrivateNode; typedef struct _GStaticPrivateNode GStaticPrivateNode;
struct _GStaticPrivateNode struct _GStaticPrivateNode
{ {
gpointer data; gpointer data;
@@ -106,6 +73,7 @@ static void g_thread_fail (void);
/* Global variables */ /* Global variables */
static GSystemThread zero_thread; /* This is initialized to all zero */
gboolean g_thread_use_default_impl = TRUE; gboolean g_thread_use_default_impl = TRUE;
gboolean g_threads_got_initialized = FALSE; gboolean g_threads_got_initialized = FALSE;
@@ -149,24 +117,19 @@ static GPrivate *g_thread_specific_private = NULL;
void void
g_mutex_init (void) g_mutex_init (void)
{ {
gpointer private_old; GRealThread* main_thread;
/* We let the main thread (the one that calls g_thread_init) inherit /* We let the main thread (the one that calls g_thread_init) inherit
* the data, that it set before calling g_thread_init * the data, that it set before calling g_thread_init
*/ */
private_old = g_thread_specific_private; main_thread = (GRealThread*) g_thread_self ();
g_thread_specific_private = g_private_new (g_thread_cleanup); g_thread_specific_private = g_private_new (g_thread_cleanup);
G_THREAD_UF (private_set, (g_thread_specific_private, main_thread));
/* we can not use g_private_set here, as g_threads_got_initialized is not G_THREAD_UF (thread_self, (&main_thread->system_thread));
* yet set TRUE, whereas the private_set function is already set.
*/
g_thread_functions_for_glib_use.private_set (g_thread_specific_private,
private_old);
g_mutex_protect_static_mutex_allocation = g_mutex_new(); g_mutex_protect_static_mutex_allocation = g_mutex_new();
g_thread_specific_mutex = g_mutex_new(); g_thread_specific_mutex = g_mutex_new();
} }
GMutex * GMutex *
@@ -187,47 +150,87 @@ g_static_mutex_get_mutex_impl (GMutex** mutex)
return *mutex; return *mutex;
} }
#ifndef g_static_rec_mutex_lock
/* That means, that g_static_rec_mutex_lock is not defined to be
* g_static_mutex_lock, we have to provide an implementation ourselves.
*/
void void
g_static_rec_mutex_lock (GStaticRecMutex* mutex) g_static_rec_mutex_lock (GStaticRecMutex* mutex)
{ {
guint counter = GPOINTER_TO_UINT (g_static_private_get (&mutex->counter)); GSystemThread self;
if (counter == 0)
g_return_if_fail (mutex);
G_THREAD_UF (thread_self, (&self));
if (g_system_thread_equal (self, mutex->owner))
{ {
g_static_mutex_lock (&mutex->mutex); mutex->depth++;
return;
} }
counter++; g_static_mutex_lock (&mutex->mutex);
g_static_private_set (&mutex->counter, GUINT_TO_POINTER (counter), NULL); g_system_thread_assign (mutex->owner, self);
mutex->depth = 1;
} }
gboolean gboolean
g_static_rec_mutex_trylock (GStaticRecMutex* mutex) g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
{ {
guint counter = GPOINTER_TO_UINT (g_static_private_get (&mutex->counter)); GSystemThread self;
if (counter == 0)
g_return_val_if_fail (mutex, FALSE);
G_THREAD_UF (thread_self, (&self));
if (g_system_thread_equal (self, mutex->owner))
{ {
if (!g_static_mutex_trylock (&mutex->mutex)) return FALSE; mutex->depth++;
return TRUE;
} }
counter++;
g_static_private_set (&mutex->counter, GUINT_TO_POINTER (counter), NULL); if (!g_static_mutex_trylock (&mutex->mutex))
return FALSE;
g_system_thread_assign (mutex->owner, self);
mutex->depth = 1;
return TRUE; return TRUE;
} }
void void
g_static_rec_mutex_unlock (GStaticRecMutex* mutex) g_static_rec_mutex_unlock (GStaticRecMutex* mutex)
{ {
guint counter = GPOINTER_TO_UINT (g_static_private_get (&mutex->counter)); g_return_if_fail (mutex);
if (counter == 1)
if (mutex->depth > 1)
{ {
g_static_mutex_unlock (&mutex->mutex); mutex->depth--;
return;
} }
counter--; g_system_thread_assign (mutex->owner, zero_thread);
g_static_private_set (&mutex->counter, GUINT_TO_POINTER (counter), NULL); g_static_mutex_unlock (&mutex->mutex);
} }
#endif /* g_static_rec_mutex_lock */
void
g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
guint depth)
{
g_return_if_fail (mutex);
g_static_mutex_lock (&mutex->mutex);
G_THREAD_UF (thread_self, (&mutex->owner));
mutex->depth = depth;
}
guint
g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
{
gint depth = mutex->depth;
g_return_val_if_fail (mutex, 0);
g_system_thread_assign (mutex->owner, zero_thread);
mutex->depth = 0;
g_static_mutex_unlock (&mutex->mutex);
return depth;
}
gpointer gpointer
g_static_private_get (GStaticPrivate *private_key) g_static_private_get (GStaticPrivate *private_key)
@@ -341,7 +344,7 @@ g_thread_cleanup (gpointer data)
if (!thread->thread.joinable) if (!thread->thread.joinable)
{ {
/* Just to make sure, this isn't used any more */ /* Just to make sure, this isn't used any more */
set_system_thread_to_zero(thread); g_system_thread_assign (thread->system_thread, zero_thread);
g_free (thread); g_free (thread);
} }
} }
@@ -380,7 +383,7 @@ g_thread_create (GThreadFunc thread_func,
gboolean bound, gboolean bound,
GThreadPriority priority) GThreadPriority priority)
{ {
GRealThread* result = g_new0 (GRealThread,1); GRealThread* result = g_new (GRealThread, 1);
g_return_val_if_fail (thread_func, NULL); g_return_val_if_fail (thread_func, NULL);
@@ -389,6 +392,7 @@ g_thread_create (GThreadFunc thread_func,
result->thread.priority = priority; result->thread.priority = priority;
result->func = thread_func; result->func = thread_func;
result->arg = arg; result->arg = arg;
result->private_data = NULL;
G_LOCK (g_thread_create); G_LOCK (g_thread_create);
G_THREAD_UF (thread_create, (g_thread_create_proxy, result, stack_size, G_THREAD_UF (thread_create, (g_thread_create_proxy, result, stack_size,
joinable, bound, priority, joinable, bound, priority,
@@ -405,13 +409,13 @@ g_thread_join (GThread* thread)
g_return_if_fail (thread); g_return_if_fail (thread);
g_return_if_fail (thread->joinable); g_return_if_fail (thread->joinable);
g_return_if_fail (system_thread_is_not_zero (real)); g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
G_THREAD_UF (thread_join, (&real->system_thread)); G_THREAD_UF (thread_join, (&real->system_thread));
/* Just to make sure, this isn't used any more */ /* Just to make sure, this isn't used any more */
thread->joinable = 0; thread->joinable = 0;
set_system_thread_to_zero (real); g_system_thread_assign (real->system_thread, zero_thread);
/* the thread structure for non-joinable threads is freed upon /* the thread structure for non-joinable threads is freed upon
thread end. We free the memory here. This will leave loose end, thread end. We free the memory here. This will leave loose end,
@@ -427,7 +431,7 @@ g_thread_set_priority (GThread* thread,
GRealThread* real = (GRealThread*) thread; GRealThread* real = (GRealThread*) thread;
g_return_if_fail (thread); g_return_if_fail (thread);
g_return_if_fail (system_thread_is_not_zero (real)); g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
thread->priority = priority; thread->priority = priority;
G_THREAD_CF (thread_set_priority, (void)0, (&real->system_thread, priority)); G_THREAD_CF (thread_set_priority, (void)0, (&real->system_thread, priority));
@@ -442,22 +446,20 @@ g_thread_self()
{ {
/* If no thread data is available, provide and set one. This /* If no thread data is available, provide and set one. This
can happen for the main thread and for threads, that are not can happen for the main thread and for threads, that are not
created by glib. */ created by GLib. */
thread = g_new (GRealThread,1); thread = g_new (GRealThread, 1);
thread->thread.joinable = FALSE; /* This is a save guess */ thread->thread.joinable = FALSE; /* This is a save guess */
thread->thread.bound = TRUE; /* This isn't important at all */ thread->thread.bound = TRUE; /* This isn't important at all */
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
just a guess */ just a guess */
thread->func = NULL; thread->func = NULL;
thread->arg = NULL; thread->arg = NULL;
set_system_thread_to_zero (thread);
thread->private_data = NULL; thread->private_data = NULL;
g_private_set (g_thread_specific_private, thread);
}
if (g_thread_supported () && !system_thread_is_not_zero(thread)) if (g_thread_supported ())
{ G_THREAD_UF (thread_self, (&thread->system_thread));
g_thread_functions_for_glib_use.thread_self(&thread->system_thread);
g_private_set (g_thread_specific_private, thread);
} }
return (GThread*)thread; return (GThread*)thread;

View File

@@ -1,3 +1,13 @@
2000-03-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread-posix.c: Don't use priorities for threads, when the
minimal/maximal priorities couldn't be determined at configure
time.
* gthread-posix.c: Don't check for errors, when setting the scope
of a tread to system, as some posix implementations can't do that
and we don't want the thing to fail because of that.
2000-02-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 2000-02-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread-posix.c, gthread-solaris.c: check for sysconf * gthread-posix.c, gthread-solaris.c: check for sysconf

View File

@@ -41,21 +41,21 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#define posix_print_error( name, num ) \ #define posix_print_error( name, num ) \
g_error( "file %s: line %d (%s): error %s during %s", \ g_error( "file %s: line %d (%s): error %s during %s", \
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
g_strerror((num)), #name ) g_strerror((num)), #name )
#if defined(G_THREADS_IMPL_POSIX) #if defined(G_THREADS_IMPL_POSIX)
# define posix_check_for_error( what ) G_STMT_START{ \ # define posix_check_for_error( what ) G_STMT_START{ \
int error = (what); \ int error = (what); \
if( error ) { posix_print_error( what, error ); } \ if( error ) { posix_print_error( what, error ); } \
}G_STMT_END }G_STMT_END
# define mutexattr_default NULL # define mutexattr_default NULL
# define condattr_default NULL # define condattr_default NULL
#elif defined(G_THREADS_IMPL_DCE) #elif defined(G_THREADS_IMPL_DCE)
# define posix_check_for_error( what ) G_STMT_START{ \ # define posix_check_for_error( what ) G_STMT_START{ \
if( (what) == -1 ) { posix_print_error( what, errno ); } \ if( (what) == -1 ) { posix_print_error( what, errno ); \
}G_STMT_END }G_STMT_END
# define pthread_key_create(a, b) pthread_keycreate (a, b) # define pthread_key_create(a, b) pthread_keycreate (a, b)
# define pthread_attr_init(a) pthread_attr_create (a) # define pthread_attr_init(a) pthread_attr_create (a)
@@ -67,14 +67,20 @@
# error This should not happen. Contact the GLib team. # error This should not happen. Contact the GLib team.
#endif #endif
#if defined(POSIX_MIN_PRIORITY) && defined(POSIX_MAX_PRIORITY)
# define HAVE_PRIORITIES 1
#endif
gulong g_thread_min_stack_size = 0; gulong g_thread_min_stack_size = 0;
#define HAVE_G_THREAD_IMPL_INIT #define HAVE_G_THREAD_IMPL_INIT
static void static void
g_thread_impl_init() g_thread_impl_init()
{ {
#ifdef HAVE_PRIORITIES
g_thread_min_priority = POSIX_MIN_PRIORITY; g_thread_min_priority = POSIX_MIN_PRIORITY;
g_thread_max_priority = POSIX_MAX_PRIORITY; g_thread_max_priority = POSIX_MAX_PRIORITY;
#endif /* HAVE_PRIORITIES */
#ifdef _SC_THREAD_STACK_MIN #ifdef _SC_THREAD_STACK_MIN
g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0); g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0);
#endif /* _SC_THREAD_STACK_MIN */ #endif /* _SC_THREAD_STACK_MIN */
@@ -244,8 +250,9 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
#ifdef PTHREAD_SCOPE_SYSTEM #ifdef PTHREAD_SCOPE_SYSTEM
if (bound) if (bound)
posix_check_for_error (pthread_attr_setscope (&attr, /* No error check here, because some systems can't do it and we
PTHREAD_SCOPE_SYSTEM)); * simply don't want threads to fail because of that. */
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
#endif /* PTHREAD_SCOPE_SYSTEM */ #endif /* PTHREAD_SCOPE_SYSTEM */
#ifdef G_THREADS_IMPL_POSIX #ifdef G_THREADS_IMPL_POSIX
@@ -253,17 +260,19 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED)); joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
#endif /* G_THREADS_IMPL_POSIX */ #endif /* G_THREADS_IMPL_POSIX */
#ifdef G_THREADS_IMPL_POSIX #ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX
{ {
struct sched_param sched; struct sched_param sched;
posix_check_for_error (pthread_attr_getschedparam (&attr, &sched)); posix_check_for_error (pthread_attr_getschedparam (&attr, &sched));
sched.sched_priority = g_thread_map_priority (priority); sched.sched_priority = g_thread_map_priority (priority);
posix_check_for_error (pthread_attr_setschedparam (&attr, &sched)); posix_check_for_error (pthread_attr_setschedparam (&attr, &sched));
} }
#else /* G_THREADS_IMPL_DCE */ # else /* G_THREADS_IMPL_DCE */
posix_check_for_error posix_check_for_error
(pthread_attr_setprio (&attr, g_thread_map_priority (priority))); (pthread_attr_setprio (&attr, g_thread_map_priority (priority)));
#endif /* G_THREADS_IMPL_DCE */ # endif /* G_THREADS_IMPL_DCE */
#endif /* HAVE_PRIORITIES */
posix_check_for_error (pthread_create (thread, &attr, posix_check_for_error (pthread_create (thread, &attr,
(void* (*)(void*))thread_func, (void* (*)(void*))thread_func,
@@ -300,7 +309,8 @@ g_thread_exit_posix_impl (void)
static void static void
g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority) g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
{ {
#ifdef G_THREADS_IMPL_POSIX #ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX
struct sched_param sched; struct sched_param sched;
int policy; int policy;
posix_check_for_error (pthread_getschedparam (*(pthread_t*)thread, posix_check_for_error (pthread_getschedparam (*(pthread_t*)thread,
@@ -308,10 +318,11 @@ g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
sched.sched_priority = g_thread_map_priority (priority); sched.sched_priority = g_thread_map_priority (priority);
posix_check_for_error (pthread_setschedparam (*(pthread_t*)thread, posix_check_for_error (pthread_setschedparam (*(pthread_t*)thread,
policy, &sched)); policy, &sched));
#else /* G_THREADS_IMPL_DCE */ # else /* G_THREADS_IMPL_DCE */
posix_check_for_error (pthread_setprio (*(pthread_t*)thread, posix_check_for_error (pthread_setprio (*(pthread_t*)thread,
g_thread_map_priority (priority))); g_thread_map_priority (priority)));
#endif # endif
#endif /* HAVE_PRIORITIES */
} }
static void static void

View File

@@ -39,14 +39,14 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#define solaris_print_error( name, num ) \ #define solaris_print_error( name, num ) \
g_error( "file %s: line %d (%s): error %s during %s", \ g_error( "file %s: line %d (%s): error %s during %s", \
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
g_strerror((num)), #name ) g_strerror((num)), #name )
#define solaris_check_for_error( what ) G_STMT_START{ \ #define solaris_check_for_error( what ) G_STMT_START{ \
int error = (what); \ int error = (what); \
if( error ) { solaris_print_error( what, error ); } \ if( error ) { solaris_print_error( what, error ); } \
}G_STMT_END }G_STMT_END
gulong g_thread_min_stack_size = 0; gulong g_thread_min_stack_size = 0;

View File

@@ -221,6 +221,15 @@ test_g_static_rw_lock ()
} }
/* run all the tests */ /* run all the tests */
void
run_all_tests()
{
test_g_mutex ();
test_g_static_rec_mutex ();
test_g_static_private ();
test_g_static_rw_lock ();
}
int int
main (int argc, main (int argc,
char *argv[]) char *argv[])
@@ -229,10 +238,15 @@ main (int argc,
implementation is available */ implementation is available */
#if defined(G_THREADS_ENABLED) && ! defined(G_THREADS_IMPL_NONE) #if defined(G_THREADS_ENABLED) && ! defined(G_THREADS_IMPL_NONE)
g_thread_init (NULL); g_thread_init (NULL);
test_g_mutex (); run_all_tests ();
test_g_static_rec_mutex ();
test_g_static_private (); /* Now we rerun all tests, but this time we fool the system into
test_g_static_rw_lock (); * thinking, that the available thread system is not native, but
* userprovided. */
g_thread_use_default_impl = FALSE;
run_all_tests ();
#endif #endif
return 0; return 0;
} }