[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Add `scm_std_read ()'
From: |
Ludovic Courtès |
Subject: |
Add `scm_std_read ()' |
Date: |
Tue, 15 Apr 2008 17:24:16 +0200 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) |
Hi,
This is roughly a followup to:
http://thread.gmane.org/gmane.lisp.guile.devel/6549/focus=6613
The attached patch adds an `scm_std_read ()' call, which is to read(2)
what `scm_std_select ()' is to select(2). It changes `fport_fill_input'
to use it, which removes the call to select(2) that precedes each
read(2) call (!).
Using the same "I/O benchmark" as in my previous message, and compared
to Guile with the inlined `scm_getc' patch, it yields an additional 5%
speedup when reading by 4096-octet blocks, and a negligible improvement
when using smaller buffer sizes.
OK to apply?
Thanks,
Ludovic.
>From f305530cbd31b4a0963f40ed9a7dd27a94aa05a8 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ludovic=20Court=C3=A8s?= <address@hidden>
Date: Mon, 14 Apr 2008 22:52:37 +0200
Subject: [PATCH] Add `scm_std_read ()', use it in `fport_fill_input ()'.
---
libguile/fports.c | 32 +-------------------------------
libguile/threads.c | 24 +++++++++++++++++++++++-
libguile/threads.h | 2 ++
3 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/libguile/fports.c b/libguile/fports.c
index efbd278..7817808 100644
--- a/libguile/fports.c
+++ b/libguile/fports.c
@@ -553,33 +553,6 @@ fport_print (SCM exp, SCM port, scm_print_state *pstate
SCM_UNUSED)
return 1;
}
-#ifndef __MINGW32__
-/* thread-local block for input on fport's fdes. */
-static void
-fport_wait_for_input (SCM port)
-{
- int fdes = SCM_FSTREAM (port)->fdes;
-
- if (!fport_input_waiting (port))
- {
- int n;
- SELECT_TYPE readfds;
- int flags = fcntl (fdes, F_GETFL);
-
- if (flags == -1)
- scm_syserror ("scm_fdes_wait_for_input");
- if (!(flags & O_NONBLOCK))
- do
- {
- FD_ZERO (&readfds);
- FD_SET (fdes, &readfds);
- n = scm_std_select (fdes + 1, &readfds, NULL, NULL, NULL);
- }
- while (n == -1 && errno == EINTR);
- }
-}
-#endif /* !__MINGW32__ */
-
static void fport_flush (SCM port);
/* fill a port's read-buffer with a single read. returns the first
@@ -591,10 +564,7 @@ fport_fill_input (SCM port)
scm_t_port *pt = SCM_PTAB_ENTRY (port);
scm_t_fport *fp = SCM_FSTREAM (port);
-#ifndef __MINGW32__
- fport_wait_for_input (port);
-#endif /* !__MINGW32__ */
- SCM_SYSCALL (count = read (fp->fdes, pt->read_buf, pt->read_buf_size));
+ count = scm_std_read (fp->fdes, pt->read_buf, pt->read_buf_size);
if (count == -1)
scm_syserror ("fport_fill_input");
if (count == 0)
diff --git a/libguile/threads.c b/libguile/threads.c
index 68c5f79..84aa5ea 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -1690,7 +1690,8 @@ scm_threads_mark_stacks (void)
SCM_MARK_BACKING_STORE ();
}
-/*** Select */
+
+/* Convenience API for I/O that properly leaves guile mode when blocking. */
int
scm_std_select (int nfds,
@@ -1741,6 +1742,27 @@ scm_std_select (int nfds,
return res;
}
+ssize_t
+scm_std_read (int fd, void *buf, size_t size)
+{
+ int eno;
+ ssize_t count;
+ scm_t_guile_ticket ticket;
+
+ SCM_TICK;
+
+ ticket = scm_leave_guile ();
+
+ SCM_SYSCALL (count = read (fd, buf, size));
+ eno = errno;
+
+ scm_enter_guile (ticket);
+
+ errno = eno;
+ return count;
+}
+
+
/* Convenience API for blocking while in guile mode. */
#if SCM_USE_PTHREAD_THREADS
diff --git a/libguile/threads.h b/libguile/threads.h
index e1944a5..aac6b0b 100644
--- a/libguile/threads.h
+++ b/libguile/threads.h
@@ -224,6 +224,8 @@ SCM_API int scm_pthread_cond_timedwait (pthread_cond_t
*cond,
SCM_API unsigned int scm_std_sleep (unsigned int);
SCM_API unsigned long scm_std_usleep (unsigned long);
+SCM_API ssize_t scm_std_read (int, void *, size_t);
+
#endif /* SCM_THREADS_H */
--
1.5.5
>From 823a559a47866bd6dbbe93161938581b32b050a0 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ludovic=20Court=C3=A8s?= <address@hidden>
Date: Tue, 15 Apr 2008 09:34:29 +0200
Subject: [PATCH] Document `scm_std_read ()'.
---
doc/ref/api-scheduling.texi | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/doc/ref/api-scheduling.texi b/doc/ref/api-scheduling.texi
index ec136fb..9916e7e 100644
--- a/doc/ref/api-scheduling.texi
+++ b/doc/ref/api-scheduling.texi
@@ -1,6 +1,6 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
address@hidden Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007
address@hidden Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007,
2008
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@@ -583,9 +583,12 @@ leaves guile mode while waiting for the condition variable.
@end deftypefn
@deftypefn {C Function} int scm_std_select (int nfds, fd_set *readfds, fd_set
*writefds, fd_set *exceptfds, struct timeval *timeout)
-Like @code{select} but leaves guile mode while waiting. Also, the
-delivery of a system async causes this function to be interrupted with
-error code @code{EINTR}.
address@hidden {C Function} ssize_t scm_std_read (int fd, void *buffer, size_t
size)
+Like the C library @code{select} and @code{read} (@pxref{Low-Level I/O,
+Low-Level Input/Output,, libc, The GNU C Library Reference Manual}),
+respectively, but leaves guile mode while waiting. Also, the delivery
+of a system async causes this function to be interrupted with error code
address@hidden
@end deftypefn
@deftypefn {C Function} {unsigned int} scm_std_sleep ({unsigned int} seconds)
--
1.5.5
- Add `scm_std_read ()',
Ludovic Courtès <=