* Makefile.am: Added iselect.c and iselect.h.

* coop.c (coop_qinit): Initialize fields used by
scm_internal_select.
(coop_qget, coop_qget, coop_tmp_queue): Made global.
(coop_next_runnable_thread): If GUILE_ISELECT enabled, use
replacement in iselect.c.
(coop_mutex_lock, coop_condition_variable_wait, coop_abort,
coop_join): If GUILE_ISELECT enabled, use
coop_wait_for_runnable_thread instead of
coop_next_runnable_thread.
(usleep, sleep): New replacements for system functions if
GUILE_ISELECT is enabled.

* coop-threads.h: Declare coop_wait_for_runnable_thread.

* coop-defs.h (coop_t): Added fields used by scm_internal_select.

* filesys.c: Added #include "iselect.h".  Moved FD-macros to
iselect.h.  Implement Scheme level `select' using
scm_internal_select.  (See NEWS.)

* genio.c (scm_getc): Block with scm_internal_select.  (See NEWS.)

* init.c: Call scm_init_iselect.
This commit is contained in:
Mikael Djurfeldt 1997-11-27 18:04:56 +00:00
commit 44e8413c73
8 changed files with 162 additions and 38 deletions

View file

@ -1,3 +1,34 @@
1997-11-27 Mikael Djurfeldt <mdj@mdj.nada.kth.se>
* Makefile.am: Added iselect.c and iselect.h.
* coop.c (coop_qinit): Initialize fields used by
scm_internal_select.
(coop_qget, coop_qget, coop_tmp_queue): Made global.
(coop_next_runnable_thread): If GUILE_ISELECT enabled, use
replacement in iselect.c.
(coop_mutex_lock, coop_condition_variable_wait, coop_abort,
coop_join): If GUILE_ISELECT enabled, use
coop_wait_for_runnable_thread instead of
coop_next_runnable_thread.
(usleep, sleep): New replacements for system functions if
GUILE_ISELECT is enabled.
* coop-threads.h: Declare coop_wait_for_runnable_thread.
* coop-defs.h (coop_t): Added fields used by scm_internal_select.
* filesys.c: Added #include "iselect.h". Moved FD-macros to
iselect.h. Implement Scheme level `select' using
scm_internal_select. (See NEWS.)
* genio.c (scm_getc): Block with scm_internal_select. (See NEWS.)
* init.c: Call scm_init_iselect.
* iselect.h, iselect.c: New files. Implements
scm_internal_select. (See NEWS.)
1997-11-27 Tim Pierce <twp@skepsis.com>
Fix a memory leak in scm_read_line and a type cast bug in the ptob.

View file

@ -32,7 +32,7 @@ EXTRA_libguile_la_SOURCES = _scm.h \
backtrace.c stacks.c debug.c srcprop.c \
strerror.c inet_aton.c putenv.c \
threads.c alloca.c \
regex-posix.c
regex-posix.c iselect.c
## This is kind of nasty... there are ".c" files that we don't want to
## compile, since they are #included in threads.c. So instead we list
@ -62,7 +62,7 @@ modinclude_HEADERS = \
simpos.h smob.h socket.h srcprop.h stackchk.h stacks.h stime.h \
strings.h strop.h strorder.h strports.h struct.h symbols.h tag.h \
tags.h throw.h unif.h variable.h vectors.h version.h vports.h \
weaks.h snarf.h threads.h coop-defs.h fluids.h
weaks.h snarf.h threads.h coop-defs.h fluids.h iselect.h
## This file is generated at configure time. That is why it is DATA
## and not a header -- headers are included in the distribution.

View file

@ -58,6 +58,10 @@
# endif
# endif
#ifdef GUILE_ISELECT
#include "iselect.h"
#endif
/* This file is included by threads.h, which, in turn, is included by
libguile.h while coop-threads.h only is included by
coop-threads.c. */
@ -89,7 +93,18 @@ typedef struct coop_t {
void *joining; /* A queue of threads waiting to join this
thread */
#ifdef GUILE_ISELECT
int nfds;
SELECT_TYPE *readfds;
SELECT_TYPE *writefds;
SELECT_TYPE *exceptfds;
int timeoutp;
struct timeval wakeup_time; /* Time to stop sleeping */
int errno;
int retval;
#else
time_t wakeup_time; /* Time to stop sleeping */
#endif
} coop_t;

View file

@ -132,8 +132,19 @@ extern void coop_yield (void);
extern void coop_abort (void);
/* The following are needed in iselect.c */
extern coop_t *coop_qget (coop_q_t *);
extern void coop_qput (coop_q_t *, coop_t *);
extern void *coop_sleephelp (qt_t *, void *, void *);
#ifdef GUILE_ISELECT
extern coop_t *coop_wait_for_runnable_thread ();
#endif
extern coop_q_t coop_global_runq; /* A queue of runable threads. */
extern coop_q_t coop_global_sleepq;
extern coop_q_t coop_global_sleepq;
extern coop_q_t coop_tmp_queue;
extern coop_q_t coop_global_allq; /* A queue of all threads. */
extern coop_t *coop_global_curr; /* Currently-executing thread. */

View file

@ -40,7 +40,7 @@
* If you do not wish that, delete this exception notice. */
/* $Id: coop.c,v 1.2 1997-05-26 22:31:48 jimb Exp $ */
/* $Id: coop.c,v 1.3 1997-11-27 18:04:53 mdj Exp $ */
/* Cooperative thread library, based on QuickThreads */
@ -69,14 +69,21 @@ coop_qinit (q)
q->t.all_prev = NULL;
q->t.all_next = NULL;
#ifdef GUILE_ISELECT
q->t.nfds = 0;
q->t.readfds = NULL;
q->t.writefds = NULL;
q->t.exceptfds = NULL;
q->t.timeoutp = 0;
#endif
}
#ifdef __STDC__
static coop_t *
coop_t *
coop_qget (coop_q_t *q)
#else
static coop_t *
coop_t *
coop_qget (q)
coop_q_t *q;
#endif
@ -96,10 +103,10 @@ coop_qget (q)
#ifdef __STDC__
static void
void
coop_qput (coop_q_t *q, coop_t *t)
#else
static void
void
coop_qput (q, t)
coop_q_t *q;
coop_t *t;
@ -148,12 +155,12 @@ coop_all_qremove (q, t)
/* Thread routines. */
coop_q_t coop_global_runq; /* A queue of runable threads. */
coop_q_t coop_global_sleepq; /* A queue of sleeping threads. */
static coop_q_t tmp_queue; /* A temp working queue */
coop_q_t coop_global_allq; /* A queue of all threads. */
static coop_t coop_global_main; /* Thread for the process. */
coop_t *coop_global_curr; /* Currently-executing thread. */
coop_q_t coop_global_runq; /* A queue of runable threads. */
coop_q_t coop_global_sleepq; /* A queue of sleeping threads. */
coop_q_t coop_tmp_queue; /* A temp working queue */
coop_q_t coop_global_allq; /* A queue of all threads. */
static coop_t coop_global_main; /* Thread for the process. */
coop_t *coop_global_curr; /* Currently-executing thread. */
static void *coop_starthelp (qt_t *old, void *ignore0, void *ignore1);
static void coop_only (void *pu, void *pt, qt_userf_t *f);
@ -171,7 +178,7 @@ coop_init()
{
coop_qinit (&coop_global_runq);
coop_qinit (&coop_global_sleepq);
coop_qinit (&tmp_queue);
coop_qinit (&coop_tmp_queue);
coop_qinit (&coop_global_allq);
coop_global_curr = &coop_global_main;
}
@ -181,6 +188,9 @@ coop_init()
and there are sleeping threads - wait until one wakes up. Otherwise,
return NULL. */
#ifdef GUILE_ISELECT
extern coop_t *coop_next_runnable_thread ();
#else
#ifdef __STDC__
coop_t *
coop_next_runnable_thread()
@ -204,9 +214,9 @@ coop_next_runnable_thread()
if (t->wakeup_time <= now)
coop_qput(&coop_global_runq, t);
else
coop_qput(&tmp_queue, t);
coop_qput(&coop_tmp_queue, t);
}
while ((t = coop_qget(&tmp_queue)) != NULL)
while ((t = coop_qget(&coop_tmp_queue)) != NULL)
coop_qput(&coop_global_sleepq, t);
t = coop_qget (&coop_global_runq);
@ -215,7 +225,7 @@ coop_next_runnable_thread()
return t;
}
#endif
#ifdef __STDC__
void
@ -284,7 +294,11 @@ coop_mutex_lock ()
/* Record the current top-of-stack before going to sleep */
coop_global_curr->top = &old;
#ifdef GUILE_ISELECT
newthread = coop_wait_for_runnable_thread();
#else
newthread = coop_next_runnable_thread();
#endif
old = coop_global_curr;
coop_global_curr = newthread;
QT_BLOCK (coop_yieldhelp, old, &(m->waiting), newthread->sp);
@ -344,7 +358,11 @@ coop_condition_variable_wait (c)
{
coop_t *old, *newthread;
#ifdef GUILE_ISELECT
newthread = coop_wait_for_runnable_thread();
#else
newthread = coop_next_runnable_thread();
#endif
old = coop_global_curr;
coop_global_curr = newthread;
QT_BLOCK (coop_yieldhelp, old, &(c->waiting), newthread->sp);
@ -436,7 +454,11 @@ coop_abort ()
free(coop_global_curr->joining);
}
#ifdef GUILE_ISELECT
newthread = coop_wait_for_runnable_thread();
#else
newthread = coop_next_runnable_thread();
#endif
coop_all_qremove(&coop_global_allq, coop_global_curr);
old = coop_global_curr;
coop_global_curr = newthread;
@ -490,7 +512,11 @@ coop_join()
coop_qinit((coop_q_t *) t->joining);
}
#ifdef GUILE_ISELECT
newthread = coop_wait_for_runnable_thread();
#else
newthread = coop_next_runnable_thread();
#endif
old = coop_global_curr;
coop_global_curr = newthread;
QT_BLOCK (coop_yieldhelp, old, (coop_q_t *) t->joining, newthread->sp);
@ -541,10 +567,10 @@ coop_yieldhelp (sp, old, blockq)
for the process - but not for the system (it busy-waits) */
#ifdef __STDC__
static void *
void *
coop_sleephelp (qt_t *sp, void *old, void *blockq)
#else
static void *
void *
coop_sleephelp (sp, old, bolckq)
qt_t *sp;
void *old;
@ -557,6 +583,32 @@ coop_sleephelp (sp, old, bolckq)
return NULL;
}
#ifdef GUILE_ISELECT
void
usleep (unsigned usec)
{
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = usec;
scm_internal_select (0, NULL, NULL, NULL, &timeout);
}
unsigned
sleep (unsigned sec)
{
time_t now = time (NULL);
struct timeval timeout;
int slept;
timeout.tv_sec = sec;
timeout.tv_usec = 0;
scm_internal_select (0, NULL, NULL, NULL, &timeout);
slept = time (NULL) - now;
return slept > sec ? 0 : sec - slept;
}
#else /* GUILE_ISELECT */
#ifdef __STDC__
unsigned
sleep (unsigned s)
@ -567,7 +619,7 @@ sleep (s)
#endif
{
coop_t *newthread, *old;
time_t now = time(NULL);
time_t now = time (NULL);
coop_global_curr->wakeup_time = now + s;
/* Put the current thread on the sleep queue */
@ -586,3 +638,5 @@ sleep (s)
return s;
}
#endif /* GUILE_ISELECT */

View file

@ -45,6 +45,7 @@
#include "smob.h"
#include "feature.h"
#include "fports.h"
#include "iselect.h"
#include "filesys.h"
@ -82,23 +83,6 @@
#include <pwd.h>
#ifdef FD_SET
#define SELECT_TYPE fd_set
#define SELECT_SET_SIZE FD_SETSIZE
#else /* no FD_SET */
/* Define the macros to access a single-int bitmap of descriptors. */
#define SELECT_SET_SIZE 32
#define SELECT_TYPE int
#define FD_SET(n, p) (*(p) |= (1 << (n)))
#define FD_CLR(n, p) (*(p) &= ~(1 << (n)))
#define FD_ISSET(n, p) (*(p) & (1 << (n)))
#define FD_ZERO(p) (*(p) = 0)
#endif /* no FD_SET */
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
@ -987,8 +971,13 @@ scm_select (reads, writes, excepts, secs, usecs)
}
SCM_DEFER_INTS;
#ifdef GUILE_ISELECT
sreturn = scm_internal_select (SELECT_SET_SIZE,
&read_set, &write_set, &except_set, time_p);
#else
sreturn = select (SELECT_SET_SIZE,
&read_set, &write_set, &except_set, time_p);
#endif
if (sreturn < 0)
scm_syserror (s_select);
SCM_ALLOW_INTS;

View file

@ -42,6 +42,9 @@
#include <stdio.h>
#include "_scm.h"
#include "chars.h"
#ifdef GUILE_ISELECT
#include "filesys.h"
#endif
#include "genio.h"
@ -107,6 +110,21 @@ scm_getc (port)
{
f = SCM_STREAM (port);
i = SCM_PTOBNUM (port);
#ifdef GUILE_ISELECT
if (SCM_FPORTP (port) && !scm_input_waiting_p ((FILE *) f, "scm_getc"))
{
int n;
SELECT_TYPE readfds;
int fd = fileno ((FILE *) f);
FD_ZERO (&readfds);
do
{
FD_SET (fd, &readfds);
n = scm_internal_select (fd + 1, &readfds, NULL, NULL, NULL);
}
while (n == -1 && errno == EINTR);
}
#endif
SCM_SYSCALL (c = (scm_ptobs[i].fgetc) (f));
}

View file

@ -68,6 +68,9 @@
#include "gsubr.h"
#include "hash.h"
#include "hashtab.h"
#ifdef GUILE_ISELECT
#include "iselect.h"
#endif
#include "ioext.h"
#include "kw.h"
#include "list.h"
@ -405,6 +408,9 @@ scm_boot_guile_1 (base, closure)
scm_init_gdbint ();
scm_init_hash ();
scm_init_hashtab ();
#ifdef GUILE_ISELECT
scm_init_iselect ();
#endif
scm_init_ioext ();
scm_init_kw ();
scm_init_list ();