Added new default thread implementation on top of the mozilla nspr

1998-12-11  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>

	* gthread/gthread-nspr.c, configure.in: Added new default thread
	implementation on top of the mozilla nspr library.

	* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
	Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
	into GMutex and GPrivate resp. to make error reporting and use of
	gmem possible in most (not all, though) gthread functions. Also
	initialized the modules via new init functions.

	* configure.in: Fixed syntax bug in definition of type
	GStaticMutex.

	* gthread/testgthread.c: Updated to work with nspr, but see note
	there for remaining problems.
This commit is contained in:
Sebastian Wilhelmi 1998-12-11 14:38:11 +00:00 committed by Sebastian Wilhelmi
parent 502084745c
commit 7589569f13
18 changed files with 540 additions and 325 deletions

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -1,3 +1,20 @@
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread/gthread-nspr.c, configure.in: Added new default thread
implementation on top of the mozilla nspr library.
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
into GMutex and GPrivate resp. to make error reporting and use of
gmem possible in most (not all, though) gthread functions. Also
initialized the modules via new init functions.
* configure.in: Fixed syntax bug in definition of type
GStaticMutex.
* gthread/testgthread.c: Updated to work with nspr, but see note
there for remaining problems.
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de> 1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is * gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -513,7 +513,7 @@ dnl ***********************
dnl *** g_thread checks *** dnl *** g_thread checks ***
dnl *********************** dnl ***********************
AC_ARG_WITH(threads, [ --with-threads=[none/posix/solaris] specify a thread implementation to use.],,) AC_ARG_WITH(threads, [ --with-threads=[none/posix/solaris/nspr] specify a thread implementation to use.],,)
dnl error and warning message dnl error and warning message
dnl ************************* dnl *************************
@ -548,6 +548,7 @@ if test x"$with_threads" = x; then
if test x"$with_threads" = x; then if test x"$with_threads" = x; then
AC_CHECK_LIB(pthread,pthread_cond_init,with_threads=posix) AC_CHECK_LIB(pthread,pthread_cond_init,with_threads=posix)
AC_CHECK_LIB(pthreads,pthread_attr_init,with_threads=posix) AC_CHECK_LIB(pthreads,pthread_attr_init,with_threads=posix)
AC_CHECK_LIB(nspr21,PRP_NewNakedCondVar,with_threads=nspr)
fi fi
fi fi
@ -586,6 +587,10 @@ case $with_threads in
[solaris_mutex_init_broken=no]) [solaris_mutex_init_broken=no])
AC_MSG_RESULT($solaris_mutex_init_broken) AC_MSG_RESULT($solaris_mutex_init_broken)
;; ;;
nspr)
AC_CHECK_LIB(nspr21,PRP_NewNakedCondVar,
G_THREAD_LIBS="-lnspr21")
;;
none) none)
;; ;;
*) *)
@ -793,7 +798,7 @@ outfile_EOF
else else
cat >>$outfile <<outfile_EOF cat >>$outfile <<outfile_EOF
typedef GMutex* GStaticMutex; typedef struct _GMutex* GStaticMutex;
#define G_STATIC_MUTEX_INIT NULL #define G_STATIC_MUTEX_INIT NULL
#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)
outfile_EOF outfile_EOF
@ -1031,6 +1036,9 @@ case $with_threads in
fi fi
g_mutex_header_file='thread.h' g_mutex_header_file='thread.h'
;; ;;
nspr)
g_mutex_has_default=no
;;
*) *)
g_mutex_has_default=no g_mutex_has_default=no
;; ;;

View File

@ -53,13 +53,11 @@
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS) #if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
#define ENTER_MEM_CHUNK_ROUTINE() \ #define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \ g_static_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) + 1, \ g_static_get (allocating_for_mem_chunk) + 1)
NULL)
#define ENTER_MEM_CHUNK_ROUTINE() \ #define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \ g_static_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) - 1, \ g_static_get (allocating_for_mem_chunk) - 1)
NULL)
#else #else
#define ENTER_MEM_CHUNK_ROUTINE() #define ENTER_MEM_CHUNK_ROUTINE()
#define LEAVE_MEM_CHUNK_ROUTINE() #define LEAVE_MEM_CHUNK_ROUTINE()
@ -127,17 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
gchar *addr); gchar *addr);
static G_LOCK_DEFINE(mem_chunks); /* here we can't use StaticMutexes, as they depend upon a working
* g_malloc, the same holds true for StaticPrivate */
static GMutex* mem_chunks_lock = NULL;
static GRealMemChunk *mem_chunks = NULL; static GRealMemChunk *mem_chunks = NULL;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
static G_LOCK_DEFINE(mem_profile); static GMutex* mem_profile_lock;
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 }; static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
static gulong allocated_mem = 0; static gulong allocated_mem = 0;
static gulong freed_mem = 0; static gulong freed_mem = 0;
static GStaticPrivate allocating_for_mem_chunk = G_STATIC_PRIVATE_INIT; static GPrivate* allocating_for_mem_chunk = NULL;
#define IS_IN_MEM_CHUNK_ROUTINE() \ #define IS_IN_MEM_CHUNK_ROUTINE() \
GPOINTER_TO_UINT (g_static_private_get (allocating_for_mem_chunk)) GPOINTER_TO_UINT (g_static_get (allocating_for_mem_chunk))
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
@ -188,7 +188,7 @@ g_malloc (gulong size)
*t = size; *t = size;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile); g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) { if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif # endif
@ -200,7 +200,7 @@ g_malloc (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
} }
# endif # endif
g_unlock(mem_profile); g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -253,7 +253,7 @@ g_malloc0 (gulong size)
*t = size; *t = size;
# ifdef ENABLE_MEM_PROFILE # ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile); g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) { if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif # endif
@ -265,7 +265,7 @@ g_malloc0 (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
} }
# endif # endif
g_unlock(mem_profile); g_mutex_unlock (mem_profile_lock);
# endif /* ENABLE_MEM_PROFILE */ # endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -304,9 +304,9 @@ g_realloc (gpointer mem,
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK) #if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG); t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile); g_mutex_lock (mem_profile);
freed_mem += *t; freed_mem += *t;
g_unlock (mem_profile); g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
mem = t; mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -341,7 +341,7 @@ g_realloc (gpointer mem,
*t = size; *t = size;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile); g_mutex_lock (mem_profile_lock);
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) { if(!IS_IN_MEM_CHUNK_ROUTINE()) {
#endif #endif
@ -353,7 +353,7 @@ g_realloc (gpointer mem,
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
} }
#endif #endif
g_unlock(mem_profile); g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -375,9 +375,9 @@ g_free (gpointer mem)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG); t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
size = *t; size = *t;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile); g_mutex_lock (mem_profile);
freed_mem += size; freed_mem += size;
g_unlock (mem_profile); g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
mem = t; mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -408,12 +408,12 @@ g_mem_profile (void)
gulong local_allocated_mem; gulong local_allocated_mem;
gulong local_freed_mem; gulong local_freed_mem;
g_lock (mem_profile); g_mutex_lock (mem_profile);
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
local_allocations[i] = allocations[i]; local_allocations[i] = allocations[i];
local_allocated_mem = allocated_mem; local_allocated_mem = allocated_mem;
local_freed_mem = freed_mem; local_freed_mem = freed_mem;
g_unlock (mem_profile); g_mutex_unlock (mem_profile);
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
if (local_allocations[i] > 0) if (local_allocations[i] > 0)
@ -494,13 +494,13 @@ g_mem_chunk_new (gchar *name,
mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size); mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
*/ */
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk->next = mem_chunks; mem_chunk->next = mem_chunks;
mem_chunk->prev = NULL; mem_chunk->prev = NULL;
if (mem_chunks) if (mem_chunks)
mem_chunks->prev = mem_chunk; mem_chunks->prev = mem_chunk;
mem_chunks = mem_chunk; mem_chunks = mem_chunk;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
LEAVE_MEM_CHUNK_ROUTINE(); LEAVE_MEM_CHUNK_ROUTINE();
@ -533,10 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
if (rmem_chunk->prev) if (rmem_chunk->prev)
rmem_chunk->prev->next = rmem_chunk->next; rmem_chunk->prev->next = rmem_chunk->next;
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
if (rmem_chunk == mem_chunks) if (rmem_chunk == mem_chunks)
mem_chunks = mem_chunks->next; mem_chunks = mem_chunks->next;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
if (rmem_chunk->type == G_ALLOC_AND_FREE) if (rmem_chunk->type == G_ALLOC_AND_FREE)
g_tree_destroy (rmem_chunk->mem_tree); g_tree_destroy (rmem_chunk->mem_tree);
@ -864,20 +864,20 @@ g_mem_chunk_info (void)
gint count; gint count;
count = 0; count = 0;
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks; mem_chunk = mem_chunks;
while (mem_chunk) while (mem_chunk)
{ {
count += 1; count += 1;
mem_chunk = mem_chunk->next; mem_chunk = mem_chunk->next;
} }
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count); g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count);
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks; mem_chunk = mem_chunks;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
while (mem_chunk) while (mem_chunk)
{ {
@ -891,9 +891,9 @@ g_blow_chunks (void)
{ {
GRealMemChunk *mem_chunk; GRealMemChunk *mem_chunk;
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks; mem_chunk = mem_chunks;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
while (mem_chunk) while (mem_chunk)
{ {
g_mem_chunk_clean ((GMemChunk*) mem_chunk); g_mem_chunk_clean ((GMemChunk*) mem_chunk);
@ -985,3 +985,13 @@ g_allocator_free (GAllocator *allocator)
g_free (allocator); g_free (allocator);
} }
void
g_mem_init (void)
{
mem_chunks_lock = g_mutex_new();
#ifdef ENABLE_MEM_PROFILE
mem_profile_lock = g_mutex_new();
allocating_for_mem_chunk = g_private_new(NULL);
#endif
}

View File

@ -72,7 +72,7 @@ struct _GLogHandler
/* --- variables --- */ /* --- variables --- */
static G_LOCK_DEFINE(g_messages_global); static GMutex* g_messages_lock = NULL;
const gchar *g_log_domain_glib = "GLib"; const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL; static GLogDomain *g_log_domains = NULL;
@ -83,7 +83,7 @@ static GErrorFunc glib_error_func = NULL;
static GWarningFunc glib_warning_func = NULL; static GWarningFunc glib_warning_func = NULL;
static GPrintFunc glib_message_func = NULL; static GPrintFunc glib_message_func = NULL;
static GStaticPrivate g_log_depth = G_STATIC_PRIVATE_INIT; static GPrivate* g_log_depth = NULL;
/* --- functions --- */ /* --- functions --- */
@ -92,18 +92,18 @@ g_log_find_domain (const gchar *log_domain)
{ {
register GLogDomain *domain; register GLogDomain *domain;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
domain = g_log_domains; domain = g_log_domains;
while (domain) while (domain)
{ {
if (strcmp (domain->log_domain, log_domain) == 0) if (strcmp (domain->log_domain, log_domain) == 0)
{ {
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return domain; return domain;
} }
domain = domain->next; domain = domain->next;
} }
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return NULL; return NULL;
} }
@ -117,10 +117,10 @@ g_log_domain_new (const gchar *log_domain)
domain->fatal_mask = G_LOG_FATAL_MASK; domain->fatal_mask = G_LOG_FATAL_MASK;
domain->handlers = NULL; domain->handlers = NULL;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
domain->next = g_log_domains; domain->next = g_log_domains;
g_log_domains = domain; g_log_domains = domain;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return domain; return domain;
} }
@ -135,7 +135,7 @@ g_log_domain_check_free (GLogDomain *domain)
last = NULL; last = NULL;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
work = g_log_domains; work = g_log_domains;
while (work) while (work)
{ {
@ -151,7 +151,7 @@ g_log_domain_check_free (GLogDomain *domain)
} }
work = work->next; work = work->next;
} }
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
} }
} }
@ -190,10 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask)
/* remove bogus flag */ /* remove bogus flag */
fatal_mask &= ~G_LOG_FLAG_FATAL; fatal_mask &= ~G_LOG_FLAG_FATAL;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_mask = g_log_always_fatal; old_mask = g_log_always_fatal;
g_log_always_fatal = fatal_mask; g_log_always_fatal = fatal_mask;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_mask; return old_mask;
} }
@ -245,9 +245,9 @@ g_log_set_handler (const gchar *log_domain,
domain = g_log_domain_new (log_domain); domain = g_log_domain_new (log_domain);
handler = g_new (GLogHandler, 1); handler = g_new (GLogHandler, 1);
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
handler->id = ++handler_id; handler->id = ++handler_id;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
handler->log_level = log_levels; handler->log_level = log_levels;
handler->log_func = log_func; handler->log_func = log_func;
handler->data = user_data; handler->data = user_data;
@ -335,7 +335,7 @@ g_logv (const gchar *log_domain,
test_level = 1 << i; test_level = 1 << i;
if (log_level & test_level) if (log_level & test_level)
{ {
guint depth = GPOINTER_TO_UINT (g_static_private_get (&g_log_depth)); guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
GLogDomain *domain; GLogDomain *domain;
GLogFunc log_func; GLogFunc log_func;
gpointer data = NULL; gpointer data = NULL;
@ -346,13 +346,13 @@ g_logv (const gchar *log_domain,
test_level |= G_LOG_FLAG_RECURSION; test_level |= G_LOG_FLAG_RECURSION;
depth++; depth++;
g_static_private_set (&g_log_depth, GUINT_TO_POINTER (depth), NULL); g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
g_log_always_fatal) & test_level) != 0) g_log_always_fatal) & test_level) != 0)
test_level |= G_LOG_FLAG_FATAL; test_level |= G_LOG_FLAG_FATAL;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
log_func = g_log_domain_get_handler (domain, test_level, &data); log_func = g_log_domain_get_handler (domain, test_level, &data);
log_func (log_domain, test_level, buffer, data); log_func (log_domain, test_level, buffer, data);
@ -363,7 +363,7 @@ g_logv (const gchar *log_domain,
abort (); abort ();
depth--; depth--;
g_static_private_set (&g_log_depth, GUINT_TO_POINTER (depth), NULL); g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
} }
} }
} }
@ -414,11 +414,11 @@ g_log_default_handler (const gchar *log_domain,
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2; fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
#endif #endif
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
local_glib_error_func = glib_error_func; local_glib_error_func = glib_error_func;
local_glib_warning_func = glib_warning_func; local_glib_warning_func = glib_warning_func;
local_glib_message_func = glib_message_func; local_glib_message_func = glib_message_func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
switch (log_level) switch (log_level)
{ {
@ -593,10 +593,10 @@ g_set_print_handler (GPrintFunc func)
{ {
GPrintFunc old_print_func; GPrintFunc old_print_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_print_func = glib_print_func; old_print_func = glib_print_func;
glib_print_func = func; glib_print_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_print_func; return old_print_func;
} }
@ -615,9 +615,9 @@ g_print (const gchar *format,
string = g_strdup_vprintf (format, args); string = g_strdup_vprintf (format, args);
va_end (args); va_end (args);
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
local_glib_print_func = glib_print_func; local_glib_print_func = glib_print_func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
if (local_glib_print_func) if (local_glib_print_func)
local_glib_print_func (string); local_glib_print_func (string);
@ -634,10 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
{ {
GPrintFunc old_printerr_func; GPrintFunc old_printerr_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_printerr_func = glib_printerr_func; old_printerr_func = glib_printerr_func;
glib_printerr_func = func; glib_printerr_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_printerr_func; return old_printerr_func;
} }
@ -656,9 +656,9 @@ g_printerr (const gchar *format,
string = g_strdup_vprintf (format, args); string = g_strdup_vprintf (format, args);
va_end (args); va_end (args);
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
local_glib_printerr_func = glib_printerr_func; local_glib_printerr_func = glib_printerr_func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
if (local_glib_printerr_func) if (local_glib_printerr_func)
local_glib_printerr_func (string); local_glib_printerr_func (string);
@ -676,10 +676,10 @@ g_set_error_handler (GErrorFunc func)
{ {
GErrorFunc old_error_func; GErrorFunc old_error_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_error_func = glib_error_func; old_error_func = glib_error_func;
glib_error_func = func; glib_error_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_error_func; return old_error_func;
} }
@ -690,10 +690,10 @@ g_set_warning_handler (GWarningFunc func)
{ {
GWarningFunc old_warning_func; GWarningFunc old_warning_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_warning_func = glib_warning_func; old_warning_func = glib_warning_func;
glib_warning_func = func; glib_warning_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_warning_func; return old_warning_func;
} }
@ -704,10 +704,17 @@ g_set_message_handler (GPrintFunc func)
{ {
GPrintFunc old_message_func; GPrintFunc old_message_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_message_func = glib_message_func; old_message_func = glib_message_func;
glib_message_func = func; glib_message_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_message_func; return old_message_func;
} }
void
g_messages_init (void)
{
g_messages_lock = g_mutex_new();
g_log_depth = g_private_new(NULL);
}

74
gmem.c
View File

@ -53,13 +53,11 @@
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS) #if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
#define ENTER_MEM_CHUNK_ROUTINE() \ #define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \ g_static_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) + 1, \ g_static_get (allocating_for_mem_chunk) + 1)
NULL)
#define ENTER_MEM_CHUNK_ROUTINE() \ #define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \ g_static_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) - 1, \ g_static_get (allocating_for_mem_chunk) - 1)
NULL)
#else #else
#define ENTER_MEM_CHUNK_ROUTINE() #define ENTER_MEM_CHUNK_ROUTINE()
#define LEAVE_MEM_CHUNK_ROUTINE() #define LEAVE_MEM_CHUNK_ROUTINE()
@ -127,17 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
gchar *addr); gchar *addr);
static G_LOCK_DEFINE(mem_chunks); /* here we can't use StaticMutexes, as they depend upon a working
* g_malloc, the same holds true for StaticPrivate */
static GMutex* mem_chunks_lock = NULL;
static GRealMemChunk *mem_chunks = NULL; static GRealMemChunk *mem_chunks = NULL;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
static G_LOCK_DEFINE(mem_profile); static GMutex* mem_profile_lock;
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 }; static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
static gulong allocated_mem = 0; static gulong allocated_mem = 0;
static gulong freed_mem = 0; static gulong freed_mem = 0;
static GStaticPrivate allocating_for_mem_chunk = G_STATIC_PRIVATE_INIT; static GPrivate* allocating_for_mem_chunk = NULL;
#define IS_IN_MEM_CHUNK_ROUTINE() \ #define IS_IN_MEM_CHUNK_ROUTINE() \
GPOINTER_TO_UINT (g_static_private_get (allocating_for_mem_chunk)) GPOINTER_TO_UINT (g_static_get (allocating_for_mem_chunk))
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
@ -188,7 +188,7 @@ g_malloc (gulong size)
*t = size; *t = size;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile); g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) { if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif # endif
@ -200,7 +200,7 @@ g_malloc (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
} }
# endif # endif
g_unlock(mem_profile); g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -253,7 +253,7 @@ g_malloc0 (gulong size)
*t = size; *t = size;
# ifdef ENABLE_MEM_PROFILE # ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile); g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) { if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif # endif
@ -265,7 +265,7 @@ g_malloc0 (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
} }
# endif # endif
g_unlock(mem_profile); g_mutex_unlock (mem_profile_lock);
# endif /* ENABLE_MEM_PROFILE */ # endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -304,9 +304,9 @@ g_realloc (gpointer mem,
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK) #if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG); t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile); g_mutex_lock (mem_profile);
freed_mem += *t; freed_mem += *t;
g_unlock (mem_profile); g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
mem = t; mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -341,7 +341,7 @@ g_realloc (gpointer mem,
*t = size; *t = size;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile); g_mutex_lock (mem_profile_lock);
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) { if(!IS_IN_MEM_CHUNK_ROUTINE()) {
#endif #endif
@ -353,7 +353,7 @@ g_realloc (gpointer mem,
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
} }
#endif #endif
g_unlock(mem_profile); g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -375,9 +375,9 @@ g_free (gpointer mem)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG); t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
size = *t; size = *t;
#ifdef ENABLE_MEM_PROFILE #ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile); g_mutex_lock (mem_profile);
freed_mem += size; freed_mem += size;
g_unlock (mem_profile); g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE */
mem = t; mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -408,12 +408,12 @@ g_mem_profile (void)
gulong local_allocated_mem; gulong local_allocated_mem;
gulong local_freed_mem; gulong local_freed_mem;
g_lock (mem_profile); g_mutex_lock (mem_profile);
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
local_allocations[i] = allocations[i]; local_allocations[i] = allocations[i];
local_allocated_mem = allocated_mem; local_allocated_mem = allocated_mem;
local_freed_mem = freed_mem; local_freed_mem = freed_mem;
g_unlock (mem_profile); g_mutex_unlock (mem_profile);
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
if (local_allocations[i] > 0) if (local_allocations[i] > 0)
@ -494,13 +494,13 @@ g_mem_chunk_new (gchar *name,
mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size); mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
*/ */
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk->next = mem_chunks; mem_chunk->next = mem_chunks;
mem_chunk->prev = NULL; mem_chunk->prev = NULL;
if (mem_chunks) if (mem_chunks)
mem_chunks->prev = mem_chunk; mem_chunks->prev = mem_chunk;
mem_chunks = mem_chunk; mem_chunks = mem_chunk;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
LEAVE_MEM_CHUNK_ROUTINE(); LEAVE_MEM_CHUNK_ROUTINE();
@ -533,10 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
if (rmem_chunk->prev) if (rmem_chunk->prev)
rmem_chunk->prev->next = rmem_chunk->next; rmem_chunk->prev->next = rmem_chunk->next;
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
if (rmem_chunk == mem_chunks) if (rmem_chunk == mem_chunks)
mem_chunks = mem_chunks->next; mem_chunks = mem_chunks->next;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
if (rmem_chunk->type == G_ALLOC_AND_FREE) if (rmem_chunk->type == G_ALLOC_AND_FREE)
g_tree_destroy (rmem_chunk->mem_tree); g_tree_destroy (rmem_chunk->mem_tree);
@ -864,20 +864,20 @@ g_mem_chunk_info (void)
gint count; gint count;
count = 0; count = 0;
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks; mem_chunk = mem_chunks;
while (mem_chunk) while (mem_chunk)
{ {
count += 1; count += 1;
mem_chunk = mem_chunk->next; mem_chunk = mem_chunk->next;
} }
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count); g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count);
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks; mem_chunk = mem_chunks;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
while (mem_chunk) while (mem_chunk)
{ {
@ -891,9 +891,9 @@ g_blow_chunks (void)
{ {
GRealMemChunk *mem_chunk; GRealMemChunk *mem_chunk;
g_lock (mem_chunks); g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks; mem_chunk = mem_chunks;
g_unlock (mem_chunks); g_mutex_unlock (mem_chunks_lock);
while (mem_chunk) while (mem_chunk)
{ {
g_mem_chunk_clean ((GMemChunk*) mem_chunk); g_mem_chunk_clean ((GMemChunk*) mem_chunk);
@ -985,3 +985,13 @@ g_allocator_free (GAllocator *allocator)
g_free (allocator); g_free (allocator);
} }
void
g_mem_init (void)
{
mem_chunks_lock = g_mutex_new();
#ifdef ENABLE_MEM_PROFILE
mem_profile_lock = g_mutex_new();
allocating_for_mem_chunk = g_private_new(NULL);
#endif
}

View File

@ -72,7 +72,7 @@ struct _GLogHandler
/* --- variables --- */ /* --- variables --- */
static G_LOCK_DEFINE(g_messages_global); static GMutex* g_messages_lock = NULL;
const gchar *g_log_domain_glib = "GLib"; const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL; static GLogDomain *g_log_domains = NULL;
@ -83,7 +83,7 @@ static GErrorFunc glib_error_func = NULL;
static GWarningFunc glib_warning_func = NULL; static GWarningFunc glib_warning_func = NULL;
static GPrintFunc glib_message_func = NULL; static GPrintFunc glib_message_func = NULL;
static GStaticPrivate g_log_depth = G_STATIC_PRIVATE_INIT; static GPrivate* g_log_depth = NULL;
/* --- functions --- */ /* --- functions --- */
@ -92,18 +92,18 @@ g_log_find_domain (const gchar *log_domain)
{ {
register GLogDomain *domain; register GLogDomain *domain;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
domain = g_log_domains; domain = g_log_domains;
while (domain) while (domain)
{ {
if (strcmp (domain->log_domain, log_domain) == 0) if (strcmp (domain->log_domain, log_domain) == 0)
{ {
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return domain; return domain;
} }
domain = domain->next; domain = domain->next;
} }
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return NULL; return NULL;
} }
@ -117,10 +117,10 @@ g_log_domain_new (const gchar *log_domain)
domain->fatal_mask = G_LOG_FATAL_MASK; domain->fatal_mask = G_LOG_FATAL_MASK;
domain->handlers = NULL; domain->handlers = NULL;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
domain->next = g_log_domains; domain->next = g_log_domains;
g_log_domains = domain; g_log_domains = domain;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return domain; return domain;
} }
@ -135,7 +135,7 @@ g_log_domain_check_free (GLogDomain *domain)
last = NULL; last = NULL;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
work = g_log_domains; work = g_log_domains;
while (work) while (work)
{ {
@ -151,7 +151,7 @@ g_log_domain_check_free (GLogDomain *domain)
} }
work = work->next; work = work->next;
} }
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
} }
} }
@ -190,10 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask)
/* remove bogus flag */ /* remove bogus flag */
fatal_mask &= ~G_LOG_FLAG_FATAL; fatal_mask &= ~G_LOG_FLAG_FATAL;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_mask = g_log_always_fatal; old_mask = g_log_always_fatal;
g_log_always_fatal = fatal_mask; g_log_always_fatal = fatal_mask;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_mask; return old_mask;
} }
@ -245,9 +245,9 @@ g_log_set_handler (const gchar *log_domain,
domain = g_log_domain_new (log_domain); domain = g_log_domain_new (log_domain);
handler = g_new (GLogHandler, 1); handler = g_new (GLogHandler, 1);
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
handler->id = ++handler_id; handler->id = ++handler_id;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
handler->log_level = log_levels; handler->log_level = log_levels;
handler->log_func = log_func; handler->log_func = log_func;
handler->data = user_data; handler->data = user_data;
@ -335,7 +335,7 @@ g_logv (const gchar *log_domain,
test_level = 1 << i; test_level = 1 << i;
if (log_level & test_level) if (log_level & test_level)
{ {
guint depth = GPOINTER_TO_UINT (g_static_private_get (&g_log_depth)); guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
GLogDomain *domain; GLogDomain *domain;
GLogFunc log_func; GLogFunc log_func;
gpointer data = NULL; gpointer data = NULL;
@ -346,13 +346,13 @@ g_logv (const gchar *log_domain,
test_level |= G_LOG_FLAG_RECURSION; test_level |= G_LOG_FLAG_RECURSION;
depth++; depth++;
g_static_private_set (&g_log_depth, GUINT_TO_POINTER (depth), NULL); g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
g_log_always_fatal) & test_level) != 0) g_log_always_fatal) & test_level) != 0)
test_level |= G_LOG_FLAG_FATAL; test_level |= G_LOG_FLAG_FATAL;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
log_func = g_log_domain_get_handler (domain, test_level, &data); log_func = g_log_domain_get_handler (domain, test_level, &data);
log_func (log_domain, test_level, buffer, data); log_func (log_domain, test_level, buffer, data);
@ -363,7 +363,7 @@ g_logv (const gchar *log_domain,
abort (); abort ();
depth--; depth--;
g_static_private_set (&g_log_depth, GUINT_TO_POINTER (depth), NULL); g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
} }
} }
} }
@ -414,11 +414,11 @@ g_log_default_handler (const gchar *log_domain,
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2; fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
#endif #endif
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
local_glib_error_func = glib_error_func; local_glib_error_func = glib_error_func;
local_glib_warning_func = glib_warning_func; local_glib_warning_func = glib_warning_func;
local_glib_message_func = glib_message_func; local_glib_message_func = glib_message_func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
switch (log_level) switch (log_level)
{ {
@ -593,10 +593,10 @@ g_set_print_handler (GPrintFunc func)
{ {
GPrintFunc old_print_func; GPrintFunc old_print_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_print_func = glib_print_func; old_print_func = glib_print_func;
glib_print_func = func; glib_print_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_print_func; return old_print_func;
} }
@ -615,9 +615,9 @@ g_print (const gchar *format,
string = g_strdup_vprintf (format, args); string = g_strdup_vprintf (format, args);
va_end (args); va_end (args);
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
local_glib_print_func = glib_print_func; local_glib_print_func = glib_print_func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
if (local_glib_print_func) if (local_glib_print_func)
local_glib_print_func (string); local_glib_print_func (string);
@ -634,10 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
{ {
GPrintFunc old_printerr_func; GPrintFunc old_printerr_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_printerr_func = glib_printerr_func; old_printerr_func = glib_printerr_func;
glib_printerr_func = func; glib_printerr_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_printerr_func; return old_printerr_func;
} }
@ -656,9 +656,9 @@ g_printerr (const gchar *format,
string = g_strdup_vprintf (format, args); string = g_strdup_vprintf (format, args);
va_end (args); va_end (args);
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
local_glib_printerr_func = glib_printerr_func; local_glib_printerr_func = glib_printerr_func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
if (local_glib_printerr_func) if (local_glib_printerr_func)
local_glib_printerr_func (string); local_glib_printerr_func (string);
@ -676,10 +676,10 @@ g_set_error_handler (GErrorFunc func)
{ {
GErrorFunc old_error_func; GErrorFunc old_error_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_error_func = glib_error_func; old_error_func = glib_error_func;
glib_error_func = func; glib_error_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_error_func; return old_error_func;
} }
@ -690,10 +690,10 @@ g_set_warning_handler (GWarningFunc func)
{ {
GWarningFunc old_warning_func; GWarningFunc old_warning_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_warning_func = glib_warning_func; old_warning_func = glib_warning_func;
glib_warning_func = func; glib_warning_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_warning_func; return old_warning_func;
} }
@ -704,10 +704,17 @@ g_set_message_handler (GPrintFunc func)
{ {
GPrintFunc old_message_func; GPrintFunc old_message_func;
g_lock (g_messages_global); g_mutex_lock (g_messages_lock);
old_message_func = glib_message_func; old_message_func = glib_message_func;
glib_message_func = func; glib_message_func = func;
g_unlock (g_messages_global); g_mutex_unlock (g_messages_lock);
return old_message_func; return old_message_func;
} }
void
g_messages_init (void)
{
g_messages_lock = g_mutex_new();
g_log_depth = g_private_new(NULL);
}

View File

@ -75,7 +75,11 @@ g_mutex_init (void)
the data, that it set before calling g_thread_init */ the data, that it set before calling g_thread_init */
gpointer private_old = g_thread_specific_private; gpointer private_old = g_thread_specific_private;
g_thread_specific_private = g_private_new (g_static_private_free_data); g_thread_specific_private = g_private_new (g_static_private_free_data);
g_private_set (g_thread_specific_private, private_old);
/* we can not use g_private_set here, as g_thread_supported is not
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();

View File

@ -11,7 +11,7 @@
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details. * Library General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU Library General Public
@ -39,46 +39,46 @@
if( error ) { posix_print_error( what, error ); } \ if( error ) { posix_print_error( what, error ); } \
}G_STMT_END }G_STMT_END
static GMutex* static GMutex *
g_mutex_new_posix_impl (void) g_mutex_new_posix_impl (void)
{ {
/* we can not use g_new and friends, as they might use mutexes by GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
themself */ posix_check_for_error (pthread_mutex_init ((pthread_mutex_t *) result, NULL));
GMutex* result = malloc(sizeof(pthread_mutex_t));
posix_check_for_error( pthread_mutex_init( (pthread_mutex_t*)result,
NULL ) );
return result; return result;
} }
static void static void
g_mutex_free_posix_impl (GMutex* mutex) g_mutex_free_posix_impl (GMutex * mutex)
{ {
posix_check_for_error( pthread_mutex_destroy((pthread_mutex_t*)mutex) ); posix_check_for_error (pthread_mutex_destroy ((pthread_mutex_t *) mutex));
free (mutex); free (mutex);
} }
/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
functions from gmem.c and gmessages.c; */
/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as /* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as
signature and semantic are right, but without error check then!!!!, signature and semantic are right, but without error check then!!!!,
we might want to change this therfore. */ we might want to change this therefore. */
static gboolean static gboolean
g_mutex_trylock_posix_impl (GMutex* mutex) g_mutex_trylock_posix_impl (GMutex * mutex)
{ {
int result; int result;
result = pthread_mutex_trylock((pthread_mutex_t*)mutex);
if( result == EBUSY ) result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
{ if (result != EBUSY)
return FALSE; return FALSE;
}
posix_check_for_error( result ); posix_check_for_error (result);
return TRUE; return TRUE;
} }
static GCond* static GCond *
g_cond_new_posix_impl (void) g_cond_new_posix_impl (void)
{ {
GCond* result = (GCond*) g_new0 (pthread_cond_t, 1); GCond *result = (GCond *) g_new (pthread_cond_t, 1);
posix_check_for_error( pthread_cond_init( (pthread_cond_t*)result, NULL ) ); posix_check_for_error (pthread_cond_init ((pthread_cond_t *) result, NULL));
return result; return result;
} }
@ -90,10 +90,10 @@ g_cond_new_posix_impl (void)
#define G_MICROSEC 1000000 #define G_MICROSEC 1000000
#define G_NANOSEC 1000000000 #define G_NANOSEC 1000000000
static gboolean static gboolean
g_cond_timed_wait_posix_impl (GCond* cond, g_cond_timed_wait_posix_impl (GCond * cond,
GMutex* entered_mutex, GMutex * entered_mutex,
GTimeVal* abs_time) GTimeVal * abs_time)
{ {
int result; int result;
struct timespec end_time; struct timespec end_time;
@ -101,78 +101,76 @@ g_cond_timed_wait_posix_impl (GCond* cond,
g_return_val_if_fail (cond != NULL, FALSE); g_return_val_if_fail (cond != NULL, FALSE);
g_return_val_if_fail (entered_mutex != NULL, FALSE); g_return_val_if_fail (entered_mutex != NULL, FALSE);
if (!abs_time) if (!abs_time)
{ {
g_cond_wait(cond, entered_mutex); g_cond_wait (cond, entered_mutex);
return TRUE; return TRUE;
} }
end_time.tv_sec = abs_time->tv_sec; end_time.tv_sec = abs_time->tv_sec;
end_time.tv_nsec = abs_time->tv_usec * (G_NANOSEC / G_MICROSEC); end_time.tv_nsec = abs_time->tv_usec * (G_NANOSEC / G_MICROSEC);
g_assert (end_time.tv_nsec < G_NANOSEC); g_assert (end_time.tv_nsec < G_NANOSEC);
result = pthread_cond_timedwait ((pthread_cond_t*)cond, result = pthread_cond_timedwait ((pthread_cond_t *) cond,
(pthread_mutex_t*)entered_mutex, (pthread_mutex_t *) entered_mutex,
&end_time); &end_time);
timed_out = ( result == ETIMEDOUT ); timed_out = (result == ETIMEDOUT);
if (!timed_out) if (!timed_out)
posix_check_for_error (result); posix_check_for_error (result);
return !timed_out; return !timed_out;
} }
static void static void
g_cond_free_posix_impl(GCond* cond) g_cond_free_posix_impl (GCond * cond)
{ {
posix_check_for_error (pthread_cond_destroy((pthread_cond_t*)cond)); posix_check_for_error (pthread_cond_destroy ((pthread_cond_t *) cond));
g_free (cond); g_free (cond);
} }
static GPrivate* static GPrivate *
g_private_new_posix_impl(GDestroyNotify destructor) g_private_new_posix_impl (GDestroyNotify destructor)
{ {
/* we can not use g_new and friends, as they might use mutexes by GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
themself */ posix_check_for_error (pthread_key_create ((pthread_key_t *) result,
GPrivate* result = malloc( sizeof(pthread_key_t) ); destructor));
/* FIXME: we shouldn't use g_log here actually */
posix_check_for_error( pthread_key_create( (pthread_key_t*)result,
destructor) );
return result; return result;
} }
void /* NOTE: the functions g_private_get and g_private_set may not use
g_private_set_posix_impl(GPrivate* private, gpointer value) functions from gmem.c and gmessages.c */
{
g_return_if_fail (private != NULL);
/* FIXME: we shouldn't use g_log here actually */ static void
posix_check_for_error( pthread_setspecific(*(pthread_key_t*)private, g_private_set_posix_impl (GPrivate * private, gpointer value)
value) ); {
if (!private)
return;
pthread_setspecific (*(pthread_key_t *) private, value);
} }
gpointer static gpointer
g_private_get_posix_impl(GPrivate* private) g_private_get_posix_impl (GPrivate * private)
{ {
g_return_val_if_fail (private != NULL, NULL); if (!private)
return NULL;
/* FIXME: we shouldn't use g_log here actually */ return pthread_getspecific (*(pthread_key_t *) private);
return pthread_getspecific(*(pthread_key_t*)private );
} }
static GThreadFunctions static GThreadFunctions g_thread_functions_for_glib_use_default =
g_thread_functions_for_glib_use_default = { {
g_mutex_new_posix_impl, g_mutex_new_posix_impl,
(void(*)(GMutex*))pthread_mutex_lock, (void (*)(GMutex *)) pthread_mutex_lock,
g_mutex_trylock_posix_impl, g_mutex_trylock_posix_impl,
(void(*)(GMutex*))pthread_mutex_unlock, (void (*)(GMutex *)) pthread_mutex_unlock,
g_mutex_free_posix_impl, g_mutex_free_posix_impl,
g_cond_new_posix_impl, g_cond_new_posix_impl,
(void(*)(GCond*))pthread_cond_signal, (void (*)(GCond *)) pthread_cond_signal,
(void(*)(GCond*))pthread_cond_broadcast, (void (*)(GCond *)) pthread_cond_broadcast,
(void(*)(GCond*,GMutex*))pthread_cond_wait, (void (*)(GCond *, GMutex *)) pthread_cond_wait,
g_cond_timed_wait_posix_impl, g_cond_timed_wait_posix_impl,
g_cond_free_posix_impl, g_cond_free_posix_impl,
g_private_new_posix_impl, g_private_new_posix_impl,
g_private_get_posix_impl, g_private_get_posix_impl,
g_private_set_posix_impl g_private_set_posix_impl
}; };

View File

@ -11,7 +11,7 @@
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details. * Library General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU Library General Public
@ -29,30 +29,20 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
/* we can't use g_log in the g_thread functions, because g_log depends #define solaris_print_error( name, num ) \
on these functions to work properly, we even should not use g_error( "file %s: line %d (%s): error %s during %s", \
g_strerror (might be a FIXME) */ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
g_strerror((num)), #name )
#define solaris_error_args( name, num ) \ #define solaris_check_for_error( what ) G_STMT_START{ \
"Gthread: Fatal error in file %s: line %d (%s): error %s during %s\n", \ int error = (what); \
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \ if( error ) { solaris_print_error( what, error ); } \
g_strerror((num)), #name
#define solaris_check_for_error( what ) G_STMT_START{ \
int error = (what); \
if( error ) { \
fprintf(stderr, solaris_error_args( what, error ) ); \
exit(1); \
} \
}G_STMT_END }G_STMT_END
static GMutex * static GMutex *
g_mutex_new_solaris_impl (void) g_mutex_new_solaris_impl (void)
{ {
/* we can not use g_new and friends, as they might use mutexes by GMutex *result = (GMutex *) g_new (mutex_t, 1);
themself */
GMutex *result = malloc (sizeof (mutex_t));
solaris_check_for_error (result?NULL:ENOMEM);
solaris_check_for_error (mutex_init ((mutex_t *) result, USYNC_PROCESS, 0)); solaris_check_for_error (mutex_init ((mutex_t *) result, USYNC_PROCESS, 0));
return result; return result;
} }
@ -64,6 +54,9 @@ g_mutex_free_solaris_impl (GMutex * mutex)
free (mutex); free (mutex);
} }
/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
functions from gmem.c and gmessages.c; */
/* mutex_lock, mutex_unlock can be taken directly, as /* mutex_lock, mutex_unlock can be taken directly, as
signature and semantic are right, but without error check then!!!!, signature and semantic are right, but without error check then!!!!,
we might want to change this therefore. */ we might want to change this therefore. */
@ -82,7 +75,7 @@ g_mutex_trylock_solaris_impl (GMutex * mutex)
static GCond * static GCond *
g_cond_new_solaris_impl () g_cond_new_solaris_impl ()
{ {
GCond *result = (GCond *) g_new0 (cond_t, 1); GCond *result = (GCond *) g_new (cond_t, 1);
solaris_check_for_error (cond_init ((cond_t *) result, USYNC_THREAD, 0)); solaris_check_for_error (cond_init ((cond_t *) result, USYNC_THREAD, 0));
return result; return result;
} }
@ -96,7 +89,8 @@ g_cond_new_solaris_impl ()
#define G_NANOSEC 1000000000 #define G_NANOSEC 1000000000
static gboolean static gboolean
g_cond_timed_wait_solaris_impl (GCond * cond, GMutex * entered_mutex, g_cond_timed_wait_solaris_impl (GCond * cond,
GMutex * entered_mutex,
GTimeVal * abs_time) GTimeVal * abs_time)
{ {
int result; int result;
@ -105,7 +99,7 @@ g_cond_timed_wait_solaris_impl (GCond * cond, GMutex * entered_mutex,
g_return_val_if_fail (cond != NULL, FALSE); g_return_val_if_fail (cond != NULL, FALSE);
g_return_val_if_fail (entered_mutex != NULL, FALSE); g_return_val_if_fail (entered_mutex != NULL, FALSE);
if (!abs_time) if (!abs_time)
{ {
g_cond_wait (cond, entered_mutex); g_cond_wait (cond, entered_mutex);
@ -133,39 +127,38 @@ g_cond_free_solaris_impl (GCond * cond)
static GPrivate * static GPrivate *
g_private_new_solaris_impl (GDestroyNotify destructor) g_private_new_solaris_impl (GDestroyNotify destructor)
{ {
/* we can not use g_new and friends, as they might use private data GPrivate *result = (GPrivate *) g_new (thread_key_t,1);
by themself */
GPrivate *result = malloc (sizeof (thread_key_t));
solaris_check_for_error (malloc ? NULL : ENOMEM);
solaris_check_for_error (thr_keycreate ((thread_key_t *) result, solaris_check_for_error (thr_keycreate ((thread_key_t *) result,
destructor)); destructor));
return result; return result;
} }
void /* NOTE: the functions g_private_get and g_private_set may not use
functions from gmem.c and gmessages.c */
static void
g_private_set_solaris_impl (GPrivate * private, gpointer value) g_private_set_solaris_impl (GPrivate * private, gpointer value)
{ {
solaris_check_for_error (private ? NULL : EINVAL); if (!private)
return;
solaris_check_for_error (thr_setspecific (*(thread_key_t *) private, value)); thr_setspecific (*(thread_key_t *) private, value);
} }
gpointer static gpointer
g_private_get_solaris_impl (GPrivate * private) g_private_get_solaris_impl (GPrivate * private)
{ {
gpointer result; gpointer result;
solaris_check_for_error (private ? NULL : EINVAL); if (!private)
return NULL;
thr_getspecific (*(thread_key_t *) private, &result);
solaris_check_for_error (thr_getspecific (*(thread_key_t *) private,
&result));
return result; return result;
} }
static GThreadFunctions static GThreadFunctions g_thread_functions_for_glib_use_default =
g_thread_functions_for_glib_use_default =
{ {
g_mutex_new_solaris_impl, g_mutex_new_solaris_impl,
(void (*)(GMutex *)) mutex_lock, (void (*)(GMutex *)) mutex_lock,

View File

@ -36,10 +36,14 @@ static gboolean thread_system_already_initialized = FALSE;
#include G_THREAD_SOURCE #include G_THREAD_SOURCE
void g_mutex_init (void); void g_mutex_init (void);
void g_mem_init (void);
void g_messages_init (void);
void void
g_thread_init(GThreadFunctions* init) g_thread_init(GThreadFunctions* init)
{ {
gboolean supported;
if (thread_system_already_initialized) if (thread_system_already_initialized)
g_error ("the glib thread system may only be initialized once."); g_error ("the glib thread system may only be initialized once.");
@ -52,7 +56,11 @@ g_thread_init(GThreadFunctions* init)
g_thread_functions_for_glib_use = *init; g_thread_functions_for_glib_use = *init;
g_thread_supported = /* It is important, that g_thread_supported is not set before the
thread initialization functions of the different modules are
called */
supported =
init->mutex_new && init->mutex_new &&
init->mutex_lock && init->mutex_lock &&
init->mutex_trylock && init->mutex_trylock &&
@ -71,7 +79,7 @@ g_thread_init(GThreadFunctions* init)
/* if somebody is calling g_thread_init (), it means that he wants to /* if somebody is calling g_thread_init (), it means that he wants to
have thread support, so check this */ have thread support, so check this */
if (!g_thread_supported) if (!supported)
{ {
if (g_thread_use_default_impl) if (g_thread_use_default_impl)
g_error ("Threads are not supported on this platform."); g_error ("Threads are not supported on this platform.");
@ -83,4 +91,11 @@ g_thread_init(GThreadFunctions* init)
glib modules. BTW: order does matter, g_mutex_init MUST be first */ glib modules. BTW: order does matter, g_mutex_init MUST be first */
g_mutex_init (); g_mutex_init ();
g_mem_init ();
g_messages_init ();
/* now we can set g_thread_supported and thus enable all the thread
functions */
g_thread_supported = TRUE;
} }

View File

@ -8,166 +8,193 @@
#define TEST_PRIVATE_ROUNDS 5 #define TEST_PRIVATE_ROUNDS 5
void void
test_mutexes() test_mutexes ()
{ {
GMutex* mutex; GMutex *mutex = NULL;
GCond* cond; GCond *cond = NULL;
GStaticMutex static_mutex = G_STATIC_MUTEX_INIT; GStaticMutex static_mutex = G_STATIC_MUTEX_INIT;
G_LOCK_DEFINE(test_me); G_LOCK_DEFINE (test_me);
if( g_thread_supported ) if (g_thread_supported)
{ {
mutex = g_mutex_new(); mutex = g_mutex_new ();
cond = g_cond_new(); cond = g_cond_new ();
} }
g_mutex_lock(mutex); g_mutex_lock (mutex);
g_mutex_unlock(mutex); g_mutex_unlock (mutex);
g_static_mutex_lock(static_mutex); g_static_mutex_lock (static_mutex);
g_static_mutex_unlock(static_mutex); g_static_mutex_unlock (static_mutex);
g_cond_signal(cond); g_cond_signal (cond);
g_cond_broadcast(cond); g_cond_broadcast (cond);
g_lock(test_me); g_lock (test_me);
g_unlock(test_me); g_unlock (test_me);
if( g_thread_supported ) if (g_thread_supported)
{ {
g_cond_free(cond); g_cond_free (cond);
g_mutex_free(mutex); g_mutex_free (mutex);
} }
} }
#if defined(DEFAULTMUTEX) /* we are using solaris threads */ #if defined(NSPR) /* we are using nspr threads */
gulong /* this option must be specified by hand during compile of
new_thread(GHookFunc func, gpointer data) testgthread. also note, that you have to link with whatever library
nspr is building upon, it might otherwise (as on solaris) lead to
run time failure, as the mutex functions are defined in libc, but
as noops, that will make some nspr assertions fail. */
#include <prthread.h>
gpointer
new_thread (GHookFunc func, gpointer data)
{ {
thread_t thread; PRThread *thread = PR_CreateThread (PR_SYSTEM_THREAD, func, data,
thr_create( NULL, 0, (void* (*)(void*))func, data, THR_BOUND, &thread); PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
PR_JOINABLE_THREAD, 0);
return thread; return thread;
} }
#define join_thread(thread) thr_join( (thread_t)thread, NULL, NULL ) #define join_thread(thread) PR_JoinThread (thread)
#define self_thread() (gulong)thr_self() #define self_thread() PR_GetCurrentThread ()
#elif defined(DEFAULTMUTEX) /* we are using solaris threads */
gpointer
new_thread (GHookFunc func, gpointer data)
{
thread_t thread;
thr_create (NULL, 0, (void *(*)(void *)) func, data, THR_BOUND, &thread);
return GUINT_TO_POINTER (thread);
}
#define join_thread(thread) \
thr_join ((thread_t)GPOINTER_TO_UINT (thread), NULL, NULL)
#define self_thread() GUINT_TO_POINTER (thr_self ())
#elif defined(PTHREAD_MUTEX_INITIALIZER) /* we are using posix threads */ #elif defined(PTHREAD_MUTEX_INITIALIZER) /* we are using posix threads */
gulong gpointer
new_thread(GHookFunc func, gpointer data) new_thread(GHookFunc func, gpointer data)
{ {
pthread_t thread; pthread_t thread;
pthread_attr_t pthread_attr; pthread_attr_t pthread_attr;
pthread_attr_init( &pthread_attr ); pthread_attr_init (&pthread_attr);
pthread_attr_setdetachstate( &pthread_attr, PTHREAD_CREATE_JOINABLE ); pthread_attr_setdetachstate (&pthread_attr, PTHREAD_CREATE_JOINABLE);
pthread_create( &thread, &pthread_attr, (void* (*)(void*))func, data ); pthread_create (&thread, &pthread_attr, (void *(*)(void *)) func, data);
return thread; return GUINT_TO_POINTER (thread);
} }
#define join_thread(thread) pthread_join( (pthread_t)thread, NULL ) #define join_thread(thread) \
#define self_thread() (gulong)pthread_self() pthread_join ((pthread_t)GPOINTER_TO_UINT (thread), NULL)
#define self_thread() GUINT_TO_POINTER (pthread_self ())
#else /* we are not having a thread implementation, do nothing */ #else /* we are not having a thread implementation, do nothing */
#define new_thread(func,data) (0)
#define new_thread(func,data) (NULL)
#define join_thread(thread) ((void)0) #define join_thread(thread) ((void)0)
#endif #define self_thread() NULL
#endif
#define G_MICROSEC 1000000 #define G_MICROSEC 1000000
void void
wait_thread(double seconds) wait_thread (double seconds)
{ {
GMutex* mutex; GMutex *mutex;
GCond* cond; GCond *cond;
GTimeVal current_time; GTimeVal current_time;
g_get_current_time (&current_time); g_get_current_time (&current_time);
mutex = g_mutex_new(); mutex = g_mutex_new ();
cond = g_cond_new(); cond = g_cond_new ();
current_time.tv_sec += (guint)seconds; current_time.tv_sec += (guint) seconds;
seconds -= (guint)seconds; seconds -= (guint) seconds;
current_time.tv_usec += (guint)(seconds * G_MICROSEC); current_time.tv_usec += (guint) (seconds * G_MICROSEC);
while( current_time.tv_usec >= G_MICROSEC ) while (current_time.tv_usec >= G_MICROSEC)
{ {
current_time.tv_usec -= G_MICROSEC; current_time.tv_usec -= G_MICROSEC;
current_time.tv_sec++; current_time.tv_sec++;
} }
g_mutex_lock( mutex ); g_mutex_lock (mutex);
g_cond_timed_wait( cond, mutex, &current_time ); g_cond_timed_wait (cond, mutex, &current_time);
g_mutex_unlock( mutex ); g_mutex_unlock (mutex);
g_mutex_free( mutex ); g_mutex_free (mutex);
g_cond_free( cond ); g_cond_free (cond);
} }
gpointer gpointer
private_constructor() private_constructor ()
{ {
guint* result = g_new(guint,2); gpointer *result = g_new (gpointer, 2);
result[0] = 0; result[0] = 0;
result[1] = self_thread(); result[1] = self_thread ();
g_print("allocating data for the thread %d.\n",result[1]); g_print ("allocating data for the thread %p.\n", result[1]);
return result; return result;
} }
void void
private_destructor(gpointer data) private_destructor (gpointer data)
{ {
guint* real = data; gpointer *real = data;
g_print("freeing data for the thread %d.\n",real[1]); g_print ("freeing data for the thread %p.\n", real[1]);
g_free( real ); g_free (real);
} }
GStaticPrivate private; GStaticPrivate private;
void void
test_private_func(void* data) test_private_func (void *data)
{ {
guint i = 0; guint i = 0;
wait_thread(1); wait_thread (1);
while( i < TEST_PRIVATE_ROUNDS ) while (i < TEST_PRIVATE_ROUNDS)
{ {
guint random_value = rand() % 10000; guint random_value = rand () % 10000;
guint* data = g_static_private_get( &private ); guint *data = g_static_private_get (&private);
if (!data) if (!data)
{ {
data = private_constructor(); data = private_constructor ();
g_static_private_set( &private, data, private_destructor ); g_static_private_set (&private, data, private_destructor);
} }
*data = random_value; *data = random_value;
wait_thread(.2); wait_thread (.2);
g_assert( *(guint*)g_static_private_get( &private ) == random_value ); g_assert (*(guint *) g_static_private_get (&private) == random_value);
i++; i++;
} }
} }
void void
test_private() test_private ()
{ {
int i; int i;
gulong threads[ TEST_PRIVATE_THREADS ]; gpointer threads[TEST_PRIVATE_THREADS];
for( i = 0; i < TEST_PRIVATE_THREADS; i++ ) for (i = 0; i < TEST_PRIVATE_THREADS; i++)
{ {
threads[ i ] = new_thread( test_private_func, (gpointer)i ); threads[i] = new_thread (test_private_func, (gpointer) i);
} }
for( i = 0; i < TEST_PRIVATE_THREADS; i++ ) for (i = 0; i < TEST_PRIVATE_THREADS; i++)
{ {
join_thread( threads[ i ] ); join_thread (threads[i]);
} }
g_print("\n"); g_print ("\n");
} }
int int
main() main ()
{ {
test_mutexes(); test_mutexes ();
g_thread_init( NULL ); g_thread_init (NULL);
test_mutexes(); test_mutexes ();
test_private ();
test_private();
/* later we might want to start n copies of that */ /* later we might want to start n copies of that */
testglib_main(0,NULL); testglib_main (0, NULL);
return 0; return 0;
} }