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:
parent
026f9e6654
commit
79cd5b8eda
3 changed files with 111 additions and 48 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
*/
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue