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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is

View File

@ -513,7 +513,7 @@ dnl ***********************
dnl *** g_thread checks ***
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 *************************
@ -548,6 +548,7 @@ 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(pthreads,pthread_attr_init,with_threads=posix)
AC_CHECK_LIB(nspr21,PRP_NewNakedCondVar,with_threads=nspr)
fi
fi
@ -586,6 +587,10 @@ case $with_threads in
[solaris_mutex_init_broken=no])
AC_MSG_RESULT($solaris_mutex_init_broken)
;;
nspr)
AC_CHECK_LIB(nspr21,PRP_NewNakedCondVar,
G_THREAD_LIBS="-lnspr21")
;;
none)
;;
*)
@ -793,7 +798,7 @@ outfile_EOF
else
cat >>$outfile <<outfile_EOF
typedef GMutex* GStaticMutex;
typedef struct _GMutex* GStaticMutex;
#define G_STATIC_MUTEX_INIT NULL
#define g_static_mutex_get_mutex(mutex) g_static_mutex_get_mutex_impl(&mutex)
outfile_EOF
@ -1031,6 +1036,9 @@ case $with_threads in
fi
g_mutex_header_file='thread.h'
;;
nspr)
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)
#define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) + 1, \
NULL)
g_static_set (allocating_for_mem_chunk, \
g_static_get (allocating_for_mem_chunk) + 1)
#define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) - 1, \
NULL)
g_static_set (allocating_for_mem_chunk, \
g_static_get (allocating_for_mem_chunk) - 1)
#else
#define ENTER_MEM_CHUNK_ROUTINE()
#define LEAVE_MEM_CHUNK_ROUTINE()
@ -127,17 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
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;
#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 allocated_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() \
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 */
@ -188,7 +188,7 @@ g_malloc (gulong size)
*t = size;
#ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile);
g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif
@ -200,7 +200,7 @@ g_malloc (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
}
# endif
g_unlock(mem_profile);
g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -253,7 +253,7 @@ g_malloc0 (gulong size)
*t = size;
# ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile);
g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif
@ -265,7 +265,7 @@ g_malloc0 (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
}
# endif
g_unlock(mem_profile);
g_mutex_unlock (mem_profile_lock);
# endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -304,9 +304,9 @@ g_realloc (gpointer mem,
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
#ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile);
g_mutex_lock (mem_profile);
freed_mem += *t;
g_unlock (mem_profile);
g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */
mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -341,7 +341,7 @@ g_realloc (gpointer mem,
*t = size;
#ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile);
g_mutex_lock (mem_profile_lock);
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
#endif
@ -353,7 +353,7 @@ g_realloc (gpointer mem,
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
}
#endif
g_unlock(mem_profile);
g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -375,9 +375,9 @@ g_free (gpointer mem)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
size = *t;
#ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile);
g_mutex_lock (mem_profile);
freed_mem += size;
g_unlock (mem_profile);
g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */
mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -408,12 +408,12 @@ g_mem_profile (void)
gulong local_allocated_mem;
gulong local_freed_mem;
g_lock (mem_profile);
g_mutex_lock (mem_profile);
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
local_allocations[i] = allocations[i];
local_allocated_mem = allocated_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++)
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);
*/
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk->next = mem_chunks;
mem_chunk->prev = NULL;
if (mem_chunks)
mem_chunks->prev = mem_chunk;
mem_chunks = mem_chunk;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
LEAVE_MEM_CHUNK_ROUTINE();
@ -533,10 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
if (rmem_chunk->prev)
rmem_chunk->prev->next = rmem_chunk->next;
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
if (rmem_chunk == mem_chunks)
mem_chunks = mem_chunks->next;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
if (rmem_chunk->type == G_ALLOC_AND_FREE)
g_tree_destroy (rmem_chunk->mem_tree);
@ -864,20 +864,20 @@ g_mem_chunk_info (void)
gint count;
count = 0;
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks;
while (mem_chunk)
{
count += 1;
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_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
while (mem_chunk)
{
@ -891,9 +891,9 @@ g_blow_chunks (void)
{
GRealMemChunk *mem_chunk;
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
while (mem_chunk)
{
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
@ -985,3 +985,13 @@ g_allocator_free (GAllocator *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 --- */
static G_LOCK_DEFINE(g_messages_global);
static GMutex* g_messages_lock = NULL;
const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL;
@ -83,7 +83,7 @@ static GErrorFunc glib_error_func = NULL;
static GWarningFunc glib_warning_func = NULL;
static GPrintFunc glib_message_func = NULL;
static GStaticPrivate g_log_depth = G_STATIC_PRIVATE_INIT;
static GPrivate* g_log_depth = NULL;
/* --- functions --- */
@ -92,18 +92,18 @@ g_log_find_domain (const gchar *log_domain)
{
register GLogDomain *domain;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
domain = g_log_domains;
while (domain)
{
if (strcmp (domain->log_domain, log_domain) == 0)
{
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return domain;
}
domain = domain->next;
}
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return NULL;
}
@ -117,10 +117,10 @@ g_log_domain_new (const gchar *log_domain)
domain->fatal_mask = G_LOG_FATAL_MASK;
domain->handlers = NULL;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
domain->next = g_log_domains;
g_log_domains = domain;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return domain;
}
@ -135,7 +135,7 @@ g_log_domain_check_free (GLogDomain *domain)
last = NULL;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
work = g_log_domains;
while (work)
{
@ -151,7 +151,7 @@ g_log_domain_check_free (GLogDomain *domain)
}
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 */
fatal_mask &= ~G_LOG_FLAG_FATAL;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_mask = g_log_always_fatal;
g_log_always_fatal = fatal_mask;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_mask;
}
@ -245,9 +245,9 @@ g_log_set_handler (const gchar *log_domain,
domain = g_log_domain_new (log_domain);
handler = g_new (GLogHandler, 1);
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
handler->id = ++handler_id;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
handler->log_level = log_levels;
handler->log_func = log_func;
handler->data = user_data;
@ -335,7 +335,7 @@ g_logv (const gchar *log_domain,
test_level = 1 << i;
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;
GLogFunc log_func;
gpointer data = NULL;
@ -346,13 +346,13 @@ g_logv (const gchar *log_domain,
test_level |= G_LOG_FLAG_RECURSION;
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) |
g_log_always_fatal) & test_level) != 0)
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 (log_domain, test_level, buffer, data);
@ -363,7 +363,7 @@ g_logv (const gchar *log_domain,
abort ();
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;
#endif
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
local_glib_error_func = glib_error_func;
local_glib_warning_func = glib_warning_func;
local_glib_message_func = glib_message_func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
switch (log_level)
{
@ -593,10 +593,10 @@ g_set_print_handler (GPrintFunc func)
{
GPrintFunc old_print_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_print_func = glib_print_func;
glib_print_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_print_func;
}
@ -615,9 +615,9 @@ g_print (const gchar *format,
string = g_strdup_vprintf (format, args);
va_end (args);
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
local_glib_print_func = glib_print_func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
if (local_glib_print_func)
local_glib_print_func (string);
@ -634,10 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
{
GPrintFunc old_printerr_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_printerr_func = glib_printerr_func;
glib_printerr_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_printerr_func;
}
@ -656,9 +656,9 @@ g_printerr (const gchar *format,
string = g_strdup_vprintf (format, args);
va_end (args);
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
local_glib_printerr_func = glib_printerr_func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
if (local_glib_printerr_func)
local_glib_printerr_func (string);
@ -676,10 +676,10 @@ g_set_error_handler (GErrorFunc func)
{
GErrorFunc old_error_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_error_func = glib_error_func;
glib_error_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_error_func;
}
@ -690,10 +690,10 @@ g_set_warning_handler (GWarningFunc func)
{
GWarningFunc old_warning_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_warning_func = glib_warning_func;
glib_warning_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_warning_func;
}
@ -704,10 +704,17 @@ g_set_message_handler (GPrintFunc func)
{
GPrintFunc old_message_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_message_func = glib_message_func;
glib_message_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
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)
#define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) + 1, \
NULL)
g_static_set (allocating_for_mem_chunk, \
g_static_get (allocating_for_mem_chunk) + 1)
#define ENTER_MEM_CHUNK_ROUTINE() \
g_static_private_set (allocating_for_mem_chunk, \
g_static_private_get (allocating_for_mem_chunk) - 1, \
NULL)
g_static_set (allocating_for_mem_chunk, \
g_static_get (allocating_for_mem_chunk) - 1)
#else
#define ENTER_MEM_CHUNK_ROUTINE()
#define LEAVE_MEM_CHUNK_ROUTINE()
@ -127,17 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
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;
#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 allocated_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() \
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 */
@ -188,7 +188,7 @@ g_malloc (gulong size)
*t = size;
#ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile);
g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif
@ -200,7 +200,7 @@ g_malloc (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
}
# endif
g_unlock(mem_profile);
g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -253,7 +253,7 @@ g_malloc0 (gulong size)
*t = size;
# ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile);
g_mutex_lock (mem_profile_lock);
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
# endif
@ -265,7 +265,7 @@ g_malloc0 (gulong size)
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
}
# endif
g_unlock(mem_profile);
g_mutex_unlock (mem_profile_lock);
# endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -304,9 +304,9 @@ g_realloc (gpointer mem,
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
#ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile);
g_mutex_lock (mem_profile);
freed_mem += *t;
g_unlock (mem_profile);
g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */
mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -341,7 +341,7 @@ g_realloc (gpointer mem,
*t = size;
#ifdef ENABLE_MEM_PROFILE
g_lock(mem_profile);
g_mutex_lock (mem_profile_lock);
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
#endif
@ -353,7 +353,7 @@ g_realloc (gpointer mem,
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
}
#endif
g_unlock(mem_profile);
g_mutex_unlock (mem_profile_lock);
#endif /* ENABLE_MEM_PROFILE */
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -375,9 +375,9 @@ g_free (gpointer mem)
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
size = *t;
#ifdef ENABLE_MEM_PROFILE
g_lock (mem_profile);
g_mutex_lock (mem_profile);
freed_mem += size;
g_unlock (mem_profile);
g_mutex_unlock (mem_profile);
#endif /* ENABLE_MEM_PROFILE */
mem = t;
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
@ -408,12 +408,12 @@ g_mem_profile (void)
gulong local_allocated_mem;
gulong local_freed_mem;
g_lock (mem_profile);
g_mutex_lock (mem_profile);
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
local_allocations[i] = allocations[i];
local_allocated_mem = allocated_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++)
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);
*/
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk->next = mem_chunks;
mem_chunk->prev = NULL;
if (mem_chunks)
mem_chunks->prev = mem_chunk;
mem_chunks = mem_chunk;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
LEAVE_MEM_CHUNK_ROUTINE();
@ -533,10 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
if (rmem_chunk->prev)
rmem_chunk->prev->next = rmem_chunk->next;
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
if (rmem_chunk == mem_chunks)
mem_chunks = mem_chunks->next;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
if (rmem_chunk->type == G_ALLOC_AND_FREE)
g_tree_destroy (rmem_chunk->mem_tree);
@ -864,20 +864,20 @@ g_mem_chunk_info (void)
gint count;
count = 0;
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks;
while (mem_chunk)
{
count += 1;
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_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
while (mem_chunk)
{
@ -891,9 +891,9 @@ g_blow_chunks (void)
{
GRealMemChunk *mem_chunk;
g_lock (mem_chunks);
g_mutex_lock (mem_chunks_lock);
mem_chunk = mem_chunks;
g_unlock (mem_chunks);
g_mutex_unlock (mem_chunks_lock);
while (mem_chunk)
{
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
@ -985,3 +985,13 @@ g_allocator_free (GAllocator *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 --- */
static G_LOCK_DEFINE(g_messages_global);
static GMutex* g_messages_lock = NULL;
const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL;
@ -83,7 +83,7 @@ static GErrorFunc glib_error_func = NULL;
static GWarningFunc glib_warning_func = NULL;
static GPrintFunc glib_message_func = NULL;
static GStaticPrivate g_log_depth = G_STATIC_PRIVATE_INIT;
static GPrivate* g_log_depth = NULL;
/* --- functions --- */
@ -92,18 +92,18 @@ g_log_find_domain (const gchar *log_domain)
{
register GLogDomain *domain;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
domain = g_log_domains;
while (domain)
{
if (strcmp (domain->log_domain, log_domain) == 0)
{
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return domain;
}
domain = domain->next;
}
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return NULL;
}
@ -117,10 +117,10 @@ g_log_domain_new (const gchar *log_domain)
domain->fatal_mask = G_LOG_FATAL_MASK;
domain->handlers = NULL;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
domain->next = g_log_domains;
g_log_domains = domain;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return domain;
}
@ -135,7 +135,7 @@ g_log_domain_check_free (GLogDomain *domain)
last = NULL;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
work = g_log_domains;
while (work)
{
@ -151,7 +151,7 @@ g_log_domain_check_free (GLogDomain *domain)
}
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 */
fatal_mask &= ~G_LOG_FLAG_FATAL;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_mask = g_log_always_fatal;
g_log_always_fatal = fatal_mask;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_mask;
}
@ -245,9 +245,9 @@ g_log_set_handler (const gchar *log_domain,
domain = g_log_domain_new (log_domain);
handler = g_new (GLogHandler, 1);
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
handler->id = ++handler_id;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
handler->log_level = log_levels;
handler->log_func = log_func;
handler->data = user_data;
@ -335,7 +335,7 @@ g_logv (const gchar *log_domain,
test_level = 1 << i;
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;
GLogFunc log_func;
gpointer data = NULL;
@ -346,13 +346,13 @@ g_logv (const gchar *log_domain,
test_level |= G_LOG_FLAG_RECURSION;
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) |
g_log_always_fatal) & test_level) != 0)
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 (log_domain, test_level, buffer, data);
@ -363,7 +363,7 @@ g_logv (const gchar *log_domain,
abort ();
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;
#endif
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
local_glib_error_func = glib_error_func;
local_glib_warning_func = glib_warning_func;
local_glib_message_func = glib_message_func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
switch (log_level)
{
@ -593,10 +593,10 @@ g_set_print_handler (GPrintFunc func)
{
GPrintFunc old_print_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_print_func = glib_print_func;
glib_print_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_print_func;
}
@ -615,9 +615,9 @@ g_print (const gchar *format,
string = g_strdup_vprintf (format, args);
va_end (args);
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
local_glib_print_func = glib_print_func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
if (local_glib_print_func)
local_glib_print_func (string);
@ -634,10 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
{
GPrintFunc old_printerr_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_printerr_func = glib_printerr_func;
glib_printerr_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_printerr_func;
}
@ -656,9 +656,9 @@ g_printerr (const gchar *format,
string = g_strdup_vprintf (format, args);
va_end (args);
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
local_glib_printerr_func = glib_printerr_func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
if (local_glib_printerr_func)
local_glib_printerr_func (string);
@ -676,10 +676,10 @@ g_set_error_handler (GErrorFunc func)
{
GErrorFunc old_error_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_error_func = glib_error_func;
glib_error_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_error_func;
}
@ -690,10 +690,10 @@ g_set_warning_handler (GWarningFunc func)
{
GWarningFunc old_warning_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_warning_func = glib_warning_func;
glib_warning_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
return old_warning_func;
}
@ -704,10 +704,17 @@ g_set_message_handler (GPrintFunc func)
{
GPrintFunc old_message_func;
g_lock (g_messages_global);
g_mutex_lock (g_messages_lock);
old_message_func = glib_message_func;
glib_message_func = func;
g_unlock (g_messages_global);
g_mutex_unlock (g_messages_lock);
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 */
gpointer private_old = g_thread_specific_private;
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_thread_specific_mutex = g_mutex_new();

View File

@ -11,7 +11,7 @@
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
@ -39,46 +39,46 @@
if( error ) { posix_print_error( what, error ); } \
}G_STMT_END
static GMutex*
static GMutex *
g_mutex_new_posix_impl (void)
{
/* we can not use g_new and friends, as they might use mutexes by
themself */
GMutex* result = malloc(sizeof(pthread_mutex_t));
posix_check_for_error( pthread_mutex_init( (pthread_mutex_t*)result,
NULL ) );
GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
posix_check_for_error (pthread_mutex_init ((pthread_mutex_t *) result, NULL));
return result;
}
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) );
free (mutex);
posix_check_for_error (pthread_mutex_destroy ((pthread_mutex_t *) 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
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
g_mutex_trylock_posix_impl (GMutex* mutex)
g_mutex_trylock_posix_impl (GMutex * mutex)
{
int result;
result = pthread_mutex_trylock((pthread_mutex_t*)mutex);
if( result == EBUSY )
{
return FALSE;
}
posix_check_for_error( result );
result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
if (result != EBUSY)
return FALSE;
posix_check_for_error (result);
return TRUE;
}
static GCond*
static GCond *
g_cond_new_posix_impl (void)
{
GCond* result = (GCond*) g_new0 (pthread_cond_t, 1);
posix_check_for_error( pthread_cond_init( (pthread_cond_t*)result, NULL ) );
GCond *result = (GCond *) g_new (pthread_cond_t, 1);
posix_check_for_error (pthread_cond_init ((pthread_cond_t *) result, NULL));
return result;
}
@ -90,10 +90,10 @@ g_cond_new_posix_impl (void)
#define G_MICROSEC 1000000
#define G_NANOSEC 1000000000
static gboolean
g_cond_timed_wait_posix_impl (GCond* cond,
GMutex* entered_mutex,
GTimeVal* abs_time)
static gboolean
g_cond_timed_wait_posix_impl (GCond * cond,
GMutex * entered_mutex,
GTimeVal * abs_time)
{
int result;
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 (entered_mutex != NULL, FALSE);
if (!abs_time)
{
g_cond_wait(cond, entered_mutex);
g_cond_wait (cond, entered_mutex);
return TRUE;
}
end_time.tv_sec = abs_time->tv_sec;
end_time.tv_nsec = abs_time->tv_usec * (G_NANOSEC / G_MICROSEC);
g_assert (end_time.tv_nsec < G_NANOSEC);
result = pthread_cond_timedwait ((pthread_cond_t*)cond,
(pthread_mutex_t*)entered_mutex,
result = pthread_cond_timedwait ((pthread_cond_t *) cond,
(pthread_mutex_t *) entered_mutex,
&end_time);
timed_out = ( result == ETIMEDOUT );
if (!timed_out)
timed_out = (result == ETIMEDOUT);
if (!timed_out)
posix_check_for_error (result);
return !timed_out;
}
static void
g_cond_free_posix_impl(GCond* cond)
static void
g_cond_free_posix_impl (GCond * cond)
{
posix_check_for_error (pthread_cond_destroy((pthread_cond_t*)cond));
g_free (cond);
posix_check_for_error (pthread_cond_destroy ((pthread_cond_t *) cond));
g_free (cond);
}
static GPrivate*
g_private_new_posix_impl(GDestroyNotify destructor)
static GPrivate *
g_private_new_posix_impl (GDestroyNotify destructor)
{
/* we can not use g_new and friends, as they might use mutexes by
themself */
GPrivate* result = malloc( sizeof(pthread_key_t) );
/* FIXME: we shouldn't use g_log here actually */
posix_check_for_error( pthread_key_create( (pthread_key_t*)result,
destructor) );
GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
posix_check_for_error (pthread_key_create ((pthread_key_t *) result,
destructor));
return result;
}
void
g_private_set_posix_impl(GPrivate* private, gpointer value)
{
g_return_if_fail (private != NULL);
/* NOTE: the functions g_private_get and g_private_set may not use
functions from gmem.c and gmessages.c */
/* FIXME: we shouldn't use g_log here actually */
posix_check_for_error( pthread_setspecific(*(pthread_key_t*)private,
value) );
static void
g_private_set_posix_impl (GPrivate * private, gpointer value)
{
if (!private)
return;
pthread_setspecific (*(pthread_key_t *) private, value);
}
gpointer
g_private_get_posix_impl(GPrivate* private)
static gpointer
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
g_thread_functions_for_glib_use_default = {
static GThreadFunctions g_thread_functions_for_glib_use_default =
{
g_mutex_new_posix_impl,
(void(*)(GMutex*))pthread_mutex_lock,
(void (*)(GMutex *)) pthread_mutex_lock,
g_mutex_trylock_posix_impl,
(void(*)(GMutex*))pthread_mutex_unlock,
(void (*)(GMutex *)) pthread_mutex_unlock,
g_mutex_free_posix_impl,
g_cond_new_posix_impl,
(void(*)(GCond*))pthread_cond_signal,
(void(*)(GCond*))pthread_cond_broadcast,
(void(*)(GCond*,GMutex*))pthread_cond_wait,
(void (*)(GCond *)) pthread_cond_signal,
(void (*)(GCond *)) pthread_cond_broadcast,
(void (*)(GCond *, GMutex *)) pthread_cond_wait,
g_cond_timed_wait_posix_impl,
g_cond_free_posix_impl,
g_private_new_posix_impl,
g_private_get_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,
* 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.
*
* You should have received a copy of the GNU Library General Public
@ -29,30 +29,20 @@
#include <stdlib.h>
#include <stdio.h>
/* we can't use g_log in the g_thread functions, because g_log depends
on these functions to work properly, we even should not use
g_strerror (might be a FIXME) */
#define solaris_print_error( name, num ) \
g_error( "file %s: line %d (%s): error %s during %s", \
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
g_strerror((num)), #name )
#define solaris_error_args( name, num ) \
"Gthread: Fatal error in file %s: line %d (%s): error %s during %s\n", \
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
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); \
} \
#define solaris_check_for_error( what ) G_STMT_START{ \
int error = (what); \
if( error ) { solaris_print_error( what, error ); } \
}G_STMT_END
static GMutex *
g_mutex_new_solaris_impl (void)
{
/* we can not use g_new and friends, as they might use mutexes by
themself */
GMutex *result = malloc (sizeof (mutex_t));
solaris_check_for_error (result?NULL:ENOMEM);
GMutex *result = (GMutex *) g_new (mutex_t, 1);
solaris_check_for_error (mutex_init ((mutex_t *) result, USYNC_PROCESS, 0));
return result;
}
@ -64,6 +54,9 @@ g_mutex_free_solaris_impl (GMutex * 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
signature and semantic are right, but without error check then!!!!,
we might want to change this therefore. */
@ -82,7 +75,7 @@ g_mutex_trylock_solaris_impl (GMutex * mutex)
static GCond *
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));
return result;
}
@ -96,7 +89,8 @@ g_cond_new_solaris_impl ()
#define G_NANOSEC 1000000000
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)
{
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 (entered_mutex != NULL, FALSE);
if (!abs_time)
{
g_cond_wait (cond, entered_mutex);
@ -133,39 +127,38 @@ g_cond_free_solaris_impl (GCond * cond)
static GPrivate *
g_private_new_solaris_impl (GDestroyNotify destructor)
{
/* we can not use g_new and friends, as they might use private data
by themself */
GPrivate *result = malloc (sizeof (thread_key_t));
solaris_check_for_error (malloc ? NULL : ENOMEM);
GPrivate *result = (GPrivate *) g_new (thread_key_t,1);
solaris_check_for_error (thr_keycreate ((thread_key_t *) result,
destructor));
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)
{
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)
{
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;
}
static GThreadFunctions
g_thread_functions_for_glib_use_default =
static GThreadFunctions g_thread_functions_for_glib_use_default =
{
g_mutex_new_solaris_impl,
(void (*)(GMutex *)) mutex_lock,

View File

@ -36,10 +36,14 @@ static gboolean thread_system_already_initialized = FALSE;
#include G_THREAD_SOURCE
void g_mutex_init (void);
void g_mem_init (void);
void g_messages_init (void);
void
g_thread_init(GThreadFunctions* init)
{
gboolean supported;
if (thread_system_already_initialized)
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_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_lock &&
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
have thread support, so check this */
if (!g_thread_supported)
if (!supported)
{
if (g_thread_use_default_impl)
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 */
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
void
test_mutexes()
test_mutexes ()
{
GMutex* mutex;
GCond* cond;
GMutex *mutex = NULL;
GCond *cond = NULL;
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();
cond = g_cond_new();
mutex = g_mutex_new ();
cond = g_cond_new ();
}
g_mutex_lock(mutex);
g_mutex_unlock(mutex);
g_static_mutex_lock(static_mutex);
g_static_mutex_unlock(static_mutex);
g_cond_signal(cond);
g_cond_broadcast(cond);
g_lock(test_me);
g_unlock(test_me);
if( g_thread_supported )
g_mutex_lock (mutex);
g_mutex_unlock (mutex);
g_static_mutex_lock (static_mutex);
g_static_mutex_unlock (static_mutex);
g_cond_signal (cond);
g_cond_broadcast (cond);
g_lock (test_me);
g_unlock (test_me);
if (g_thread_supported)
{
g_cond_free(cond);
g_mutex_free(mutex);
g_cond_free (cond);
g_mutex_free (mutex);
}
}
#if defined(DEFAULTMUTEX) /* we are using solaris threads */
gulong
new_thread(GHookFunc func, gpointer data)
#if defined(NSPR) /* we are using nspr threads */
/* this option must be specified by hand during compile of
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;
thr_create( NULL, 0, (void* (*)(void*))func, data, THR_BOUND, &thread);
PRThread *thread = PR_CreateThread (PR_SYSTEM_THREAD, func, data,
PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
PR_JOINABLE_THREAD, 0);
return thread;
}
#define join_thread(thread) thr_join( (thread_t)thread, NULL, NULL )
#define self_thread() (gulong)thr_self()
#define join_thread(thread) PR_JoinThread (thread)
#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 */
gulong
gpointer
new_thread(GHookFunc func, gpointer data)
{
pthread_t thread;
pthread_attr_t pthread_attr;
pthread_attr_init( &pthread_attr );
pthread_attr_setdetachstate( &pthread_attr, PTHREAD_CREATE_JOINABLE );
pthread_create( &thread, &pthread_attr, (void* (*)(void*))func, data );
return thread;
pthread_attr_init (&pthread_attr);
pthread_attr_setdetachstate (&pthread_attr, PTHREAD_CREATE_JOINABLE);
pthread_create (&thread, &pthread_attr, (void *(*)(void *)) func, data);
return GUINT_TO_POINTER (thread);
}
#define join_thread(thread) pthread_join( (pthread_t)thread, NULL )
#define self_thread() (gulong)pthread_self()
#define join_thread(thread) \
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 */
#define new_thread(func,data) (0)
#define new_thread(func,data) (NULL)
#define join_thread(thread) ((void)0)
#endif
#define self_thread() NULL
#endif
#define G_MICROSEC 1000000
void
wait_thread(double seconds)
wait_thread (double seconds)
{
GMutex* mutex;
GCond* cond;
GMutex *mutex;
GCond *cond;
GTimeVal current_time;
g_get_current_time (&current_time);
mutex = g_mutex_new();
cond = g_cond_new();
mutex = g_mutex_new ();
cond = g_cond_new ();
current_time.tv_sec += (guint)seconds;
seconds -= (guint)seconds;
current_time.tv_usec += (guint)(seconds * G_MICROSEC);
while( current_time.tv_usec >= G_MICROSEC )
current_time.tv_sec += (guint) seconds;
seconds -= (guint) seconds;
current_time.tv_usec += (guint) (seconds * G_MICROSEC);
while (current_time.tv_usec >= G_MICROSEC)
{
current_time.tv_usec -= G_MICROSEC;
current_time.tv_sec++;
}
g_mutex_lock( mutex );
g_cond_timed_wait( cond, mutex, &current_time );
g_mutex_unlock( mutex );
g_mutex_lock (mutex);
g_cond_timed_wait (cond, mutex, &current_time);
g_mutex_unlock (mutex);
g_mutex_free( mutex );
g_cond_free( cond );
g_mutex_free (mutex);
g_cond_free (cond);
}
gpointer
private_constructor()
gpointer
private_constructor ()
{
guint* result = g_new(guint,2);
gpointer *result = g_new (gpointer, 2);
result[0] = 0;
result[1] = self_thread();
g_print("allocating data for the thread %d.\n",result[1]);
result[1] = self_thread ();
g_print ("allocating data for the thread %p.\n", result[1]);
return result;
}
void
private_destructor(gpointer data)
private_destructor (gpointer data)
{
guint* real = data;
g_print("freeing data for the thread %d.\n",real[1]);
g_free( real );
gpointer *real = data;
g_print ("freeing data for the thread %p.\n", real[1]);
g_free (real);
}
GStaticPrivate private;
GStaticPrivate private;
void
test_private_func(void* data)
void
test_private_func (void *data)
{
guint i = 0;
wait_thread(1);
while( i < TEST_PRIVATE_ROUNDS )
wait_thread (1);
while (i < TEST_PRIVATE_ROUNDS)
{
guint random_value = rand() % 10000;
guint* data = g_static_private_get( &private );
guint random_value = rand () % 10000;
guint *data = g_static_private_get (&private);
if (!data)
{
data = private_constructor();
g_static_private_set( &private, data, private_destructor );
data = private_constructor ();
g_static_private_set (&private, data, private_destructor);
}
*data = random_value;
wait_thread(.2);
g_assert( *(guint*)g_static_private_get( &private ) == random_value );
wait_thread (.2);
g_assert (*(guint *) g_static_private_get (&private) == random_value);
i++;
}
}
void
test_private()
test_private ()
{
int i;
gulong threads[ TEST_PRIVATE_THREADS ];
for( i = 0; i < TEST_PRIVATE_THREADS; i++ )
gpointer threads[TEST_PRIVATE_THREADS];
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
main()
{
test_mutexes();
main ()
{
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 */
testglib_main(0,NULL);
testglib_main (0, NULL);
return 0;
}