1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-10 14:00:21 +02:00

* coop-defs.h (coop_m): Added 'level' field.

(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy, struct timespec): Do not
define.
(coop_condition_variable_broadcast): New.

* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.

* coop.c (coop_new_mutex_init): Initialize level.
(coop_mutex_trylock, coop_mutex_lock, coop_mutex_unlock): maintain
level.
(coop_condition_variable_signal): Renamed to
coop_condition_variable_broadcast and reimplemented in terms of
that.  Thus...
(coop_condition_variable_broadcast): New.
This commit is contained in:
Marius Vollmer 2002-10-27 20:12:07 +00:00
parent 026f9e6654
commit 79cd5b8eda
3 changed files with 111 additions and 48 deletions

View file

@ -3,7 +3,7 @@
#ifndef SCM_COOP_DEFS_H
#define SCM_COOP_DEFS_H
/* Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
/* Copyright (C) 1996,1997,1998,1999,2000,2001, 2002 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -142,24 +142,18 @@ typedef struct coop_q_t {
typedef struct coop_m {
coop_t *owner; /* Mutex owner */
int level; /* for recursive locks. */
coop_q_t waiting; /* Queue of waiting threads */
} coop_m;
typedef int coop_mattr;
typedef coop_m scm_t_mutex;
SCM_API int coop_mutex_init (coop_m*);
SCM_API int coop_new_mutex_init (coop_m*, coop_mattr*);
SCM_API int coop_mutex_lock (coop_m*);
SCM_API int coop_mutex_trylock (coop_m*);
SCM_API int coop_mutex_unlock (coop_m*);
SCM_API int coop_mutex_destroy (coop_m*);
#define scm_mutex_init coop_mutex_init
#define scm_mutex_lock coop_mutex_lock
#define scm_mutex_trylock coop_mutex_lock
#define scm_mutex_unlock coop_mutex_unlock
#define scm_mutex_destroy coop_mutex_destroy
/* A Condition variable is made up of a list of threads waiting on the
condition. */
@ -170,18 +164,6 @@ typedef struct coop_c {
typedef int coop_cattr;
typedef coop_c scm_t_cond;
#ifndef HAVE_STRUCT_TIMESPEC
/* POSIX.4 structure for a time value. This is like a `struct timeval' but
has nanoseconds instead of microseconds. */
struct timespec
{
long int tv_sec; /* Seconds. */
long int tv_nsec; /* Nanoseconds. */
};
#endif
SCM_API int coop_condition_variable_init (coop_c*);
SCM_API int coop_new_condition_variable_init (coop_c*, coop_cattr*);
SCM_API int coop_condition_variable_wait_mutex (coop_c*, coop_m*);
@ -189,13 +171,8 @@ SCM_API int coop_condition_variable_timed_wait_mutex (coop_c*,
coop_m*,
const struct timespec *abstime);
SCM_API int coop_condition_variable_signal (coop_c*);
SCM_API int coop_condition_variable_broadcast (coop_c*);
SCM_API int coop_condition_variable_destroy (coop_c*);
#define scm_cond_init coop_new_condition_variable_init
#define scm_cond_wait coop_condition_variable_wait_mutex
#define scm_cond_timedwait coop_condition_variable_timed_wait_mutex
#define scm_cond_signal coop_condition_variable_signal
#define scm_cond_broadcast coop_condition_variable_signal /* yes */
#define scm_cond_destroy coop_condition_variable_destroy
typedef int coop_k;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc.
/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -66,6 +66,11 @@ scm_threads_init (SCM_STACKITEM *i)
{
coop_init();
scm_tc16_thread = scm_make_smob_type ("thread", 0);
scm_tc16_mutex = scm_make_smob_type ("mutex", sizeof (coop_m));
scm_tc16_condvar = scm_make_smob_type ("condition-variable",
sizeof (coop_c));
scm_thread_count = 1;
#ifndef GUILE_PTHREAD_COMPAT
@ -418,10 +423,20 @@ scm_join_thread (SCM thread)
if (thread_data)
/* The thread is still alive */
coop_join (thread_data);
/* XXX - return real result. */
return SCM_BOOL_T;
}
#undef FUNC_NAME
int
scm_c_thread_exited_p (SCM thread)
#define FUNC_NAME s_scm_thread_exited_p
{
SCM_VALIDATE_THREAD (1, thread);
return SCM_THREAD_DATA (thread) != NULL;
}
#undef FUNC_NAME
SCM
scm_yield (void)
{
@ -456,6 +471,13 @@ scm_lock_mutex (SCM m)
return SCM_BOOL_T;
}
SCM
scm_try_mutex (SCM m)
{
SCM_ASSERT (SCM_MUTEXP (m), m, SCM_ARG1, s_lock_mutex);
return SCM_BOOL (coop_mutex_trylock (SCM_MUTEX_DATA (m)));
}
SCM
scm_unlock_mutex (SCM m)
{
@ -478,8 +500,13 @@ scm_make_condition_variable (void)
}
SCM
scm_wait_condition_variable (SCM c, SCM m)
scm_timed_wait_condition_variable (SCM c, SCM m, SCM t)
#define FUNC_NAME s_wait_condition_variable
{
coop_c *cv;
coop_m *mx;
struct timespec waittime;
SCM_ASSERT (SCM_CONDVARP (c),
c,
SCM_ARG1,
@ -488,10 +515,33 @@ scm_wait_condition_variable (SCM c, SCM m)
m,
SCM_ARG2,
s_wait_condition_variable);
coop_condition_variable_wait_mutex (SCM_CONDVAR_DATA (c),
SCM_MUTEX_DATA (m));
return SCM_BOOL_T;
cv = SCM_CONDVAR_DATA (c);
mx = SCM_MUTEX_DATA (m);
if (!SCM_UNBNDP (t))
{
if (SCM_CONSP (t))
{
SCM_VALIDATE_UINT_COPY (3, SCM_CAR(t), waittime.tv_sec);
SCM_VALIDATE_UINT_COPY (3, SCM_CDR(t), waittime.tv_nsec);
waittime.tv_nsec *= 1000;
}
else
{
SCM_VALIDATE_UINT_COPY (3, t, waittime.tv_sec);
waittime.tv_nsec = 0;
}
return SCM_BOOL(
coop_condition_variable_timed_wait_mutex (cv, mx, &waittime));
}
else
{
coop_condition_variable_wait_mutex (cv, mx);
return SCM_BOOL_T;
}
}
#undef FUNC_NAME
SCM
scm_signal_condition_variable (SCM c)
@ -504,6 +554,17 @@ scm_signal_condition_variable (SCM c)
return SCM_BOOL_T;
}
SCM
scm_broadcast_condition_variable (SCM c)
{
SCM_ASSERT (SCM_CONDVARP (c),
c,
SCM_ARG1,
s_broadcast_condition_variable);
coop_condition_variable_broadcast (SCM_CONDVAR_DATA (c));
return SCM_BOOL_T;
}
/*
Local Variables:
c-file-style: "gnu"

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -40,7 +40,7 @@
* If you do not wish that, delete this exception notice. */
/* $Id: coop.c,v 1.31 2002-08-17 20:39:35 ghouston Exp $ */
/* $Id: coop.c,v 1.32 2002-10-27 20:12:07 mvo Exp $ */
/* Cooperative thread library, based on QuickThreads */
@ -293,6 +293,7 @@ int
coop_new_mutex_init (coop_m *m, coop_mattr *attr)
{
m->owner = NULL;
m->level = 0;
coop_qinit(&(m->waiting));
return 0;
}
@ -305,6 +306,11 @@ coop_mutex_trylock (coop_m *m)
m->owner = coop_global_curr;
return 0;
}
else if (m->owner == coop_global_curr)
{
m->level++;
return 0;
}
else
return EBUSY;
}
@ -316,6 +322,10 @@ coop_mutex_lock (coop_m *m)
{
m->owner = coop_global_curr;
}
else if (m->owner == coop_global_curr)
{
m->level++;
}
else
{
coop_t *old, *newthread;
@ -343,23 +353,31 @@ coop_mutex_unlock (coop_m *m)
{
coop_t *old, *newthread;
newthread = coop_qget (&(m->waiting));
if (newthread != NULL)
if (m->level == 0)
{
/* Record the current top-of-stack before going to sleep */
coop_global_curr->top = &old;
old = coop_global_curr;
coop_global_curr = newthread;
/* The new thread came into m->waiting through a lock operation.
It now owns this mutex. */
m->owner = coop_global_curr;
QT_BLOCK (coop_yieldhelp, old, &coop_global_runq, newthread->sp);
newthread = coop_qget (&(m->waiting));
if (newthread != NULL)
{
/* Record the current top-of-stack before going to sleep */
coop_global_curr->top = &old;
old = coop_global_curr;
coop_global_curr = newthread;
/* The new thread came into m->waiting through a lock operation.
It now owns this mutex. */
m->owner = coop_global_curr;
QT_BLOCK (coop_yieldhelp, old, &coop_global_runq, newthread->sp);
}
else
{
m->owner = NULL;
}
}
else if (m->level > 0)
m->level--;
else
{
m->owner = NULL;
}
abort (); /* XXX */
return 0;
}
@ -472,7 +490,7 @@ coop_condition_variable_timed_wait_mutex (coop_c *c,
}
int
coop_condition_variable_signal (coop_c *c)
coop_condition_variable_broadcast (coop_c *c)
{
coop_t *newthread;
@ -483,6 +501,13 @@ coop_condition_variable_signal (coop_c *c)
return 0;
}
int
coop_condition_variable_signal (coop_c *c)
{
return coop_condition_variable_broadcast (c);
}
/* {Keys}
*/