+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * configure.in: Add a surrogate for thread priorities using PID
+ niceness for systems with no thread priorities and different PIDs
+ for threads of the same process (most notably: Linux). Define
+ G_THREAD_USE_PID_SURROGATE in that case, as used by
+ gthread-posix.c. Also make the system thread bigger by
+ sizeof (long) to contain the thread's PID.
+
+ * gfileutils.c: Include stdlib.h for mkstemp prototype.
+
+ * gthread.c: Add priority range checks to the affected functions.
+
+ * gthreadpool.c: Remove unused variable.
+
Mon Nov 20 18:55:17 2000 Jonathan Blandford <jrb@redhat.com>
* gtree.[hc]: Patch from David Benson <daveb@idealab.com> to add
fi
AC_DEFINE_UNQUOTED(POSIX_YIELD_FUNC,$posix_yield_func,[The POSIX RT yield function])
CPPFLAGS="$glib_save_CPPFLAGS"
+
+ AC_MSG_CHECKING(whether to use the PID niceness surrogate for thread priorities)
+ AC_TRY_RUN([#include <pthread.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ pid_t other_pid = 0;
+
+ void* func(void* data) {other_pid = getpid();}
+ main()
+ { pthread_t t;
+ void *ret;
+ pthread_create (&t, $defattr, func, NULL);
+ pthread_join (t, &ret);
+ exit (getpid()==other_pid ||
+ $posix_priority_min != $posix_priority_max);
+ }],
+ [AC_MSG_RESULT(yes),
+ AC_DEFINE(G_THREAD_USE_PID_SURROGATE, 1,
+ [whether to use the PID niceness surrogate for thread priorities])
+
+ glib_cv_sizeof_system_thread=`expr $glib_cv_sizeof_system_thread + $ac_cv_sizeof_long`],
+ [AC_MSG_RESULT(no)])
+
else # solaris threads
GLIB_SIZEOF([#include <thread.h>],
thread_t,
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <stdlib.h>
#ifdef G_OS_WIN32
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <stdlib.h>
#ifdef G_OS_WIN32
#include <io.h>
GRealThread* result = g_new (GRealThread, 1);
GError *local_error = NULL;
g_return_val_if_fail (thread_func, NULL);
+ g_return_val_if_fail (priority >= G_THREAD_PRIORITY_LOW, NULL);
+ g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
result->thread.joinable = joinable;
result->thread.bound = bound;
g_return_if_fail (thread);
g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
thread->priority = priority;
G_THREAD_CF (thread_set_priority, (void)0, (&real->system_thread, priority));
g_thread_pool_thread_proxy (gpointer data)
{
GRealThreadPool *pool = data;
- GThread* self = g_thread_self ();
g_async_queue_lock (pool->queue);
while (TRUE)
GRealThread* result = g_new (GRealThread, 1);
GError *local_error = NULL;
g_return_val_if_fail (thread_func, NULL);
+ g_return_val_if_fail (priority >= G_THREAD_PRIORITY_LOW, NULL);
+ g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
result->thread.joinable = joinable;
result->thread.bound = bound;
g_return_if_fail (thread);
g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
thread->priority = priority;
G_THREAD_CF (thread_set_priority, (void)0, (&real->system_thread, priority));
+2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread-impl.c, gthread-posix.c, gthread-solaris.c: Removed
+ g_thread_map_priority function in favour of the
+ g_thread_priority_map array. Initialize the array with
+ PRIORITY_{...}_VALUE, if available and interpolate beetween the
+ bounds if .._NORMAL_.. and .._HIGH_.. are not available.
+
+ * gthread-posix.c: If we should use the PID niceness as a
+ surrogate for thread priorities (G_THREAD_USE_PID_SURROGATE is
+ defined), then disable normal priority handling and use PIDs and
+ setpriority() instead. Depends on the thread to write its PID into
+ the place after the thread id right after thread creation.
+
2000-11-15 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread-posix.c: Include <sched.h> if available.
#include <glib.h>
static gboolean thread_system_already_initialized = FALSE;
-static gint g_thread_map_priority (GThreadPriority priority);
-static gint g_thread_min_priority = 0;
-static gint g_thread_max_priority = 0;
+static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT];
#include G_THREAD_SOURCE
+#ifndef PRIORITY_LOW_VALUE
+# define PRIORITY_LOW_VALUE 0
+#endif
+
+#ifndef PRIORITY_URGENT_VALUE
+# define PRIORITY_URGENT_VALUE 0
+#endif
+
+#ifndef PRIORITY_NORMAL_VALUE
+# define PRIORITY_NORMAL_VALUE \
+ PRIORITY_LOW_VALUE + (PRIORITY_URGENT_VALUE - PRIORITY_LOW_VALUE) * 40 / 100
+#endif /* PRIORITY_NORMAL_VALUE */
+
+#ifndef PRIORITY_HIGH_VALUE
+# define PRIORITY_HIGH_VALUE \
+ PRIORITY_LOW_VALUE + (PRIORITY_URGENT_VALUE - PRIORITY_LOW_VALUE) * 80 / 100
+#endif /* PRIORITY_HIGH_VALUE */
+
void g_mutex_init (void);
void g_mem_init (void);
void g_messages_init (void);
g_thread_impl_init();
#endif
+ g_thread_priority_map [G_THREAD_PRIORITY_LOW] = PRIORITY_LOW_VALUE;
+ g_thread_priority_map [G_THREAD_PRIORITY_NORMAL] = PRIORITY_NORMAL_VALUE;
+ g_thread_priority_map [G_THREAD_PRIORITY_HIGH] = PRIORITY_HIGH_VALUE;
+ g_thread_priority_map [G_THREAD_PRIORITY_URGENT] = PRIORITY_URGENT_VALUE;
+
/* now call the thread initialization functions of the different
* glib modules. order does matter, g_mutex_init MUST come first.
*/
/* we want the main thread to run with normal priority */
g_thread_set_priority (g_thread_self(), G_THREAD_PRIORITY_NORMAL);
}
-
-static gint
-g_thread_map_priority (GThreadPriority priority)
-{
- guint procent;
- switch (priority)
- {
- case G_THREAD_PRIORITY_LOW: procent = 0; break;
- default: case G_THREAD_PRIORITY_NORMAL: procent = 40; break;
- case G_THREAD_PRIORITY_HIGH: procent = 80; break;
- case G_THREAD_PRIORITY_URGENT: procent = 100; break;
- }
- return g_thread_min_priority +
- (g_thread_max_priority - g_thread_min_priority) * procent / 100;
-}
#include <errno.h>
#include <stdlib.h>
#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+# include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
+
#ifdef HAVE_SCHED_H
#include <sched.h>
#endif
+#ifdef G_THREAD_USE_PID_SURROGATE
+# include <sys/resource.h>
+# define PID_IN_THREAD(thread) (*(pid_t*)(((gchar*)thread)+sizeof(pthread_t)))
+# define SET_PRIO(pid, prio) \
+ posix_check_cmd_prio ((setpriority (PRIO_PROCESS, (pid), \
+ g_thread_priority_map [prio]) == -1) ? \
+ (errno == EACCES ? EPERM : errno ): 0)
+#endif /* G_THREAD_USE_PID_SURROGATE */
+
#define posix_check_err(err, name) G_STMT_START{ \
int error = (err); \
if (error) \
- g_error ("file %s: line %d (%s): error %s during %s", \
+ g_error ("file %s: line %d (%s): error '%s' during '%s'", \
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
g_strerror (error), name); \
}G_STMT_END
if (!posix_check_cmd_prio_warned) \
{ \
posix_check_cmd_prio_warned = TRUE; \
- g_warning ("Priorities can only be changed by root."); \
+ g_warning ("Priorities can only be changed " \
+ "(resp. increased) by root."); \
} \
} \
else \
# error This should not happen. Contact the GLib team.
#endif
-#if defined (POSIX_MIN_PRIORITY) && defined (POSIX_MAX_PRIORITY)
-# define HAVE_PRIORITIES 1
-#endif
+#ifdef G_THREAD_USE_PID_SURROGATE
+# define PRIORITY_LOW_VALUE 15
+# define PRIORITY_NORMAL_VALUE 0
+# define PRIORITY_HIGH_VALUE -15
+# define PRIORITY_URGENT_VALUE -20
+#elif defined (POSIX_MIN_PRIORITY) && defined (POSIX_MAX_PRIORITY)
+# define HAVE_PRIORITIES 1
+# define PRIORITY_LOW_VALUE POSIX_MIN_PRIORITY
+# define PRIORITY_URGENT_VALUE POSIX_MAX_PRIORITY
+#endif /* POSIX_MIN_PRIORITY && POSIX_MAX_PRIORITY */
gulong g_thread_min_stack_size = 0;
#define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
+#ifdef _SC_THREAD_STACK_MIN
#define HAVE_G_THREAD_IMPL_INIT
static void
g_thread_impl_init()
{
-#ifdef HAVE_PRIORITIES
- g_thread_min_priority = POSIX_MIN_PRIORITY;
- g_thread_max_priority = POSIX_MAX_PRIORITY;
-#endif /* HAVE_PRIORITIES */
-#ifdef _SC_THREAD_STACK_MIN
g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0);
-#endif /* _SC_THREAD_STACK_MIN */
}
+#endif /* _SC_THREAD_STACK_MIN */
static GMutex *
g_mutex_new_posix_impl (void)
#endif
}
+#ifdef G_THREAD_USE_PID_SURROGATE
+struct proxy_data
+{
+ GThreadFunc thread_func;
+ gpointer arg;
+ gpointer thread;
+ GThreadPriority priority;
+};
+
+static void
+g_thread_create_posix_impl_proxy (struct proxy_data *data)
+{
+ GThreadFunc thread_func = data->thread_func;
+ GThreadFunc arg = data->arg;
+ PID_IN_THREAD (data->thread) = getpid();
+ SET_PRIO (PID_IN_THREAD (data->thread), data->priority);
+ g_free (data);
+ thread_func (arg);
+}
+#endif /* G_THREAD_USE_PID_SURROGATE */
+
static void
g_thread_create_posix_impl (GThreadFunc thread_func,
gpointer arg,
gint ret;
g_return_if_fail (thread_func);
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
posix_check_cmd (pthread_attr_init (&attr));
joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
#endif /* G_THREADS_IMPL_POSIX */
-#ifdef HAVE_PRIORITIES
-# ifdef G_THREADS_IMPL_POSIX
+#ifdef G_THREAD_USE_PID_SURROGATE
+ {
+ struct proxy_data *data = g_new (struct proxy_data, 1);
+ data->thread_func = thread_func;
+ data->arg = arg;
+ data->thread = thread;
+ data->priority = priority;
+ PID_IN_THREAD (thread) = 0;
+ ret = posix_error (pthread_create (thread, &attr, (void* (*)(void*))
+ g_thread_create_posix_impl_proxy,
+ data));
+ }
+#else /* G_THREAD_USE_PID_SURROGATE */
+# ifdef HAVE_PRIORITIES
+# ifdef G_THREADS_IMPL_POSIX
{
struct sched_param sched;
posix_check_cmd (pthread_attr_getschedparam (&attr, &sched));
- sched.sched_priority = g_thread_map_priority (priority);
+ sched.sched_priority = g_thread_priority_map [priority];
posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched));
}
-# else /* G_THREADS_IMPL_DCE */
+# else /* G_THREADS_IMPL_DCE */
posix_check_cmd_prio
- (pthread_attr_setprio (&attr, g_thread_map_priority (priority)));
-# endif /* G_THREADS_IMPL_DCE */
-#endif /* HAVE_PRIORITIES */
-
+ (pthread_attr_setprio (&attr, g_thread_priority_map [priority]));
+# endif /* G_THREADS_IMPL_DCE */
+# endif /* HAVE_PRIORITIES */
ret = posix_error (pthread_create (thread, &attr,
(void* (*)(void*))thread_func, arg));
-
+#endif /* !G_THREAD_USE_PID_SURROGATE */
+
posix_check_cmd (pthread_attr_destroy (&attr));
if (ret == EAGAIN)
static void
g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
{
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
#ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX
- struct sched_param sched;
- int policy;
- posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy,
- &sched));
- sched.sched_priority = g_thread_map_priority (priority);
- posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy,
- &sched));
+ {
+ struct sched_param sched;
+ int policy;
+ posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy,
+ &sched));
+ sched.sched_priority = g_thread_priority_map [priority];
+ posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy,
+ &sched));
+ }
# else /* G_THREADS_IMPL_DCE */
posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread,
- g_thread_map_priority (priority)));
+ g_thread_priority_map [priority]));
# endif
-#endif /* HAVE_PRIORITIES */
+#elif defined (G_THREAD_USE_PID_SURROGATE)
+ /* If the addressed thread hasn't yet been able to provide it's pid,
+ * we ignore the request. Should be more than rare */
+ if (PID_IN_THREAD (thread) != 0)
+ SET_PRIO (PID_IN_THREAD (thread), priority);
+#endif /* G_THREAD_USE_PID_SURROGATE */
}
static void
g_thread_self_posix_impl (gpointer thread)
{
*(pthread_t*)thread = pthread_self();
+#ifdef G_THREAD_USE_PID_SURROGATE
+ PID_IN_THREAD (thread) = getpid();
+#endif /* G_THREAD_USE_PID_SURROGATE */
}
static GThreadFunctions g_thread_functions_for_glib_use_default =
#define G_MUTEX_SIZE (sizeof (mutex_t))
+#define PRIORITY_LOW_VALUE 0
+#define PRIORITY_URGENT_VALUE 127
+
+#ifdef _SC_THREAD_STACK_MIN
#define HAVE_G_THREAD_IMPL_INIT
static void
g_thread_impl_init()
{
- g_thread_min_priority = 0;
- g_thread_max_priority = 127;
-#ifdef _SC_THREAD_STACK_MIN
g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0);
-#endif /* _SC_THREAD_STACK_MIN */
}
+#endif /* _SC_THREAD_STACK_MIN */
static GMutex *
g_mutex_new_solaris_impl (void)
g_thread_set_priority_solaris_impl (gpointer thread, GThreadPriority priority)
{
solaris_check_for_error (thr_setprio (*(thread_t*)thread,
- g_thread_map_priority (priority)));
+ g_thread_priority_map [priority]));
}
static void
gint ret;
g_return_if_fail (thread_func);
+ g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+ g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
stack_size = MAX (g_thread_min_stack_size, stack_size);
g_thread_pool_thread_proxy (gpointer data)
{
GRealThreadPool *pool = data;
- GThread* self = g_thread_self ();
g_async_queue_lock (pool->queue);
while (TRUE)