gauche-devel Mailing List for Gauche
R7RS Scheme scripting engine
Status: Beta
Brought to you by:
shirok
You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
(3) |
May
(12) |
Jun
(21) |
Jul
(11) |
Aug
(1) |
Sep
(3) |
Oct
(1) |
Nov
(2) |
Dec
(8) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(7) |
Feb
(5) |
Mar
(1) |
Apr
(2) |
May
(2) |
Jun
(2) |
Jul
(6) |
Aug
(19) |
Sep
(28) |
Oct
(29) |
Nov
(112) |
Dec
(72) |
| 2003 |
Jan
(38) |
Feb
(53) |
Mar
(19) |
Apr
(22) |
May
(16) |
Jun
(40) |
Jul
(18) |
Aug
(33) |
Sep
(24) |
Oct
(72) |
Nov
(35) |
Dec
(38) |
| 2004 |
Jan
(26) |
Feb
(39) |
Mar
(39) |
Apr
(55) |
May
(13) |
Jun
(10) |
Jul
(33) |
Aug
(27) |
Sep
(8) |
Oct
(4) |
Nov
(10) |
Dec
(12) |
| 2005 |
Jan
|
Feb
(2) |
Mar
(6) |
Apr
(29) |
May
(31) |
Jun
(44) |
Jul
(22) |
Aug
(30) |
Sep
(7) |
Oct
(18) |
Nov
(12) |
Dec
(15) |
| 2006 |
Jan
(28) |
Feb
(7) |
Mar
(41) |
Apr
(33) |
May
(35) |
Jun
(7) |
Jul
(7) |
Aug
(31) |
Sep
(15) |
Oct
(10) |
Nov
(21) |
Dec
(11) |
| 2007 |
Jan
(9) |
Feb
|
Mar
(35) |
Apr
(23) |
May
(25) |
Jun
(6) |
Jul
(11) |
Aug
(6) |
Sep
|
Oct
(12) |
Nov
(5) |
Dec
(4) |
| 2008 |
Jan
(3) |
Feb
(4) |
Mar
(8) |
Apr
(6) |
May
(3) |
Jun
(5) |
Jul
(19) |
Aug
(5) |
Sep
(3) |
Oct
(5) |
Nov
|
Dec
(3) |
| 2009 |
Jan
(4) |
Feb
(42) |
Mar
(26) |
Apr
(3) |
May
(3) |
Jun
(22) |
Jul
(14) |
Aug
(8) |
Sep
|
Oct
(17) |
Nov
(23) |
Dec
(9) |
| 2010 |
Jan
(27) |
Feb
(18) |
Mar
(17) |
Apr
(48) |
May
(1) |
Jun
(17) |
Jul
(6) |
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
(19) |
| 2011 |
Jan
(8) |
Feb
(19) |
Mar
(8) |
Apr
|
May
(4) |
Jun
(4) |
Jul
(5) |
Aug
(1) |
Sep
(5) |
Oct
|
Nov
(4) |
Dec
(7) |
| 2012 |
Jan
(20) |
Feb
(3) |
Mar
|
Apr
|
May
(27) |
Jun
(16) |
Jul
(2) |
Aug
|
Sep
(10) |
Oct
(16) |
Nov
(37) |
Dec
(5) |
| 2013 |
Jan
(5) |
Feb
(6) |
Mar
(4) |
Apr
(4) |
May
(10) |
Jun
(3) |
Jul
(22) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2014 |
Jan
|
Feb
|
Mar
(6) |
Apr
(2) |
May
(6) |
Jun
(36) |
Jul
(7) |
Aug
|
Sep
(3) |
Oct
|
Nov
(11) |
Dec
(5) |
| 2015 |
Jan
|
Feb
(6) |
Mar
(4) |
Apr
(40) |
May
(31) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(8) |
Nov
(13) |
Dec
|
| 2016 |
Jan
|
Feb
(1) |
Mar
(3) |
Apr
(15) |
May
(1) |
Jun
(38) |
Jul
(8) |
Aug
(15) |
Sep
|
Oct
(26) |
Nov
|
Dec
|
| 2017 |
Jan
(3) |
Feb
|
Mar
(11) |
Apr
(2) |
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
(15) |
Nov
|
Dec
|
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(7) |
Aug
(4) |
Sep
(1) |
Oct
(2) |
Nov
|
Dec
(2) |
| 2019 |
Jan
|
Feb
|
Mar
|
Apr
(25) |
May
(10) |
Jun
(9) |
Jul
(5) |
Aug
(1) |
Sep
|
Oct
(4) |
Nov
(9) |
Dec
(5) |
| 2020 |
Jan
|
Feb
(1) |
Mar
(2) |
Apr
(9) |
May
(7) |
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
(45) |
Dec
(18) |
| 2021 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(8) |
Nov
|
Dec
(35) |
| 2022 |
Jan
|
Feb
(12) |
Mar
(4) |
Apr
|
May
(1) |
Jun
(2) |
Jul
|
Aug
(5) |
Sep
|
Oct
(4) |
Nov
(9) |
Dec
|
| 2023 |
Jan
(2) |
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
(9) |
Nov
|
Dec
(6) |
| 2024 |
Jan
(2) |
Feb
|
Mar
(7) |
Apr
(25) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(4) |
Oct
(2) |
Nov
(39) |
Dec
(15) |
| 2025 |
Jan
(20) |
Feb
(1) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
|
From: Shiro K. <shi...@gm...> - 2025-12-15 01:21:05
|
Thanks Stephen, I just made a new release https://github.com/shirok/Gauche-gtk2/releases/tag/release-0.6.2 --shiro On Sun, Dec 14, 2025 at 8:44 AM Stephen Lewis <lew...@fr...> wrote: > Shiro, > I had left 'make stubs' in my rpmbuild spec file when I built > the new tarball. Tarball is just fine the way it is. It builds > correctly with just 'make' on Gauche "0.9.12" on AArch64. So, same as > before, if I mess with the *.hints files I use 'make stubs'. > In my local build scripts I leave 'make stubs' in the script, > it doesn't do anything if it doesn't need to. > "Gauche-gtk2-0.6.2_pre1" looks OK to release to me, > Stephen Lewis > > On Sat, 13 Dec 2025 17:29:03 -1000 > Shiro Kawai <shi...@gm...> wrote: > > > I don't quite remember whether I changed the dependency. The tarball > > contains pre-generated stub files. We have .stub.c make rule so the > > touching *.stub file may trigger genstub. *.hints files----I need to > > detangle Makefiles to find out the answer. I would say it's safer to > run > > 'make stubs' whenever you touch one of those "meta" files. > > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Stephen L. <lew...@fr...> - 2025-12-14 18:43:59
|
Shiro, I had left 'make stubs' in my rpmbuild spec file when I built the new tarball. Tarball is just fine the way it is. It builds correctly with just 'make' on Gauche "0.9.12" on AArch64. So, same as before, if I mess with the *.hints files I use 'make stubs'. In my local build scripts I leave 'make stubs' in the script, it doesn't do anything if it doesn't need to. "Gauche-gtk2-0.6.2_pre1" looks OK to release to me, Stephen Lewis On Sat, 13 Dec 2025 17:29:03 -1000 Shiro Kawai <shi...@gm...> wrote: > I don't quite remember whether I changed the dependency. The tarball > contains pre-generated stub files. We have .stub.c make rule so the > touching *.stub file may trigger genstub. *.hints files----I need to > detangle Makefiles to find out the answer. I would say it's safer to run > 'make stubs' whenever you touch one of those "meta" files. |
|
From: Shiro K. <shi...@gm...> - 2025-12-14 03:29:20
|
I don't quite remember whether I changed the dependency. The tarball contains pre-generated stub files. We have .stub.c make rule so the touching *.stub file may trigger genstub. *.hints files----I need to detangle Makefiles to find out the answer. I would say it's safer to run 'make stubs' whenever you touch one of those "meta" files. On Sat, Dec 13, 2025 at 5:19 PM Stephen Lewis <lew...@fr...> wrote: > Shiro, > The new tarball works on Gauche "0.9.12", thanks. Looks like it built all > the stubs > without 'make stubs', I used to need 'make stubs' if I had to patch a > hints file. > Is that a change? > Thanks for the update, > Stephen Lewis > > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Stephen L. <lew...@fr...> - 2025-12-14 03:18:47
|
Shiro, The new tarball works on Gauche "0.9.12", thanks. Looks like it built all the stubs without 'make stubs', I used to need 'make stubs' if I had to patch a hints file. Is that a change? Thanks for the update, Stephen Lewis |
|
From: Shiro K. <shi...@gm...> - 2025-12-14 01:49:36
|
Ah, genstub is moved to tools/genstub some time ago. Hmm, I wish distros will catch up; 0.9.12 was 3.5 years old. But the newer Gauche keeps a compatibility file, so keeping it as genstub still work. Thanks for catching it. Tarball is updated. https://practical-scheme.net/vault/Gauche-gtk2-0.6.2_pre1.tgz --shiro On Sat, Dec 13, 2025 at 2:44 PM Stephen Lewis <lew...@fr...> wrote: > Shiro, > So close, but no cigar! > Under Gauche "0.9.12" the 'src' Makefile does not find "tools/gensub". > > Looks like you moved 'genstub' since Gauche version "0.9.12" > which is the latest version packaged for Fedora Asahi Remix 42 > Though I don't know what other distros are doing. It would be > nice if it built for "0.9.12" but I have built "Gauche-gtk2" 0.6.2_pre1 > with this patch and it builds and works. > > ======================================================================== > --- ./src/Makefile.in.orig 2025-12-13 12:13:45.494483515 -0800 > +++ ./src/Makefile.in 2025-12-13 12:14:04.334394630 -0800 > @@ -7,7 +7,7 @@ > .SUFFIXES: .stub > > .stub.c : > - $(GOSH) tools/genstub $< > + $(GOSH) genstub $< > > # General info > SHELL = @SHELL@ > ======================================================================== > > I see Gauche "0.9.15" is latest but I don't know how many distros > are up to date. Fedora 41, 42, 43 (and Rawhide, I think) are still on > "0.9.12". > > Stephen Lewis > > > > -- > Stephen Lewis <lew...@sd...> > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Stephen L. <lew...@fr...> - 2025-12-14 00:44:21
|
Shiro,
So close, but no cigar!
Under Gauche "0.9.12" the 'src' Makefile does not find "tools/gensub".
Looks like you moved 'genstub' since Gauche version "0.9.12"
which is the latest version packaged for Fedora Asahi Remix 42
Though I don't know what other distros are doing. It would be
nice if it built for "0.9.12" but I have built "Gauche-gtk2" 0.6.2_pre1
with this patch and it builds and works.
========================================================================
--- ./src/Makefile.in.orig 2025-12-13 12:13:45.494483515 -0800
+++ ./src/Makefile.in 2025-12-13 12:14:04.334394630 -0800
@@ -7,7 +7,7 @@
.SUFFIXES: .stub
.stub.c :
- $(GOSH) tools/genstub $<
+ $(GOSH) genstub $<
# General info
SHELL = @SHELL@
========================================================================
I see Gauche "0.9.15" is latest but I don't know how many distros
are up to date. Fedora 41, 42, 43 (and Rawhide, I think) are still on "0.9.12".
Stephen Lewis
--
Stephen Lewis <lew...@sd...>
|
|
From: Shiro K. <shi...@gm...> - 2025-12-13 04:20:03
|
Hi Stephen, Thank you for the patch. It is in the HEAD. I also plan to release 0.6.2 including this patch. A "pre-release" tarball is downloadable from here: https://practical-scheme.net/vault/Gauche-gtk2-0.6.2_pre1.tgz Could you try it at your convenience? --shiro On Fri, Dec 12, 2025 at 9:57 AM Stephen Lewis <lew...@fr...> wrote: > Shiro, > > I built 'gauche-gtk2' from the tarball "Gauche-gtk2-0.6.1.tgz" > > I can use 'gdk-pixbuf-loader-new-with-type' which works fine > then 'gdk-pixbuf-loader-write' and 'gdk-pixbuf-loader-close' > but 'gdk-pixbuf-loader-get-pixbuf' is missing so you can't > access the 'pixbuf' you just made :-( > > Here is my patch to add hint for 'gdk-pixbuf-loader-get-pixbuf'. > > ========================================================================== > --- ./src/gdk-lib.hints.orig 2025-12-08 13:36:52.268016378 -0800 > +++ ./src/gdk-lib.hints 2025-12-08 13:51:52.243272391 -0800 > @@ -1057,6 +1057,13 @@ > ;; gdk-pixbuf-loader.h > ;; > > +(define-cproc-fix gdk-pixbuf-loader-get-pixbuf > + (fix-arguments! '(loader::<gdk-pixbuf-loader>)) > + (fix-body! > + "{ GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); > + if (pixbuf) SCM_RETURN(SCM_MAKE_GDK_PIXBUF(pixbuf)); > + else SCM_RETURN(SCM_FALSE);}")) > + > (define-cproc-fix gdk-pixbuf-loader-new-with-type > (fix-arguments! '(image-type::<const-char*>)) > (fix-body! "GError *perr = NULL; > ========================================================================== > > I really like Gauche and thank you for producing and maintaining it > and 'gauche-gtk2' as well. It still works on Fedora Asahi Remix 42 > which I am running on a Mac Mini M2 Pro. > > Stephen Lewis > -- > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Stephen L. <lew...@fr...> - 2025-12-12 19:56:48
|
Shiro,
I built 'gauche-gtk2' from the tarball "Gauche-gtk2-0.6.1.tgz"
I can use 'gdk-pixbuf-loader-new-with-type' which works fine
then 'gdk-pixbuf-loader-write' and 'gdk-pixbuf-loader-close'
but 'gdk-pixbuf-loader-get-pixbuf' is missing so you can't
access the 'pixbuf' you just made :-(
Here is my patch to add hint for 'gdk-pixbuf-loader-get-pixbuf'.
==========================================================================
--- ./src/gdk-lib.hints.orig 2025-12-08 13:36:52.268016378 -0800
+++ ./src/gdk-lib.hints 2025-12-08 13:51:52.243272391 -0800
@@ -1057,6 +1057,13 @@
;; gdk-pixbuf-loader.h
;;
+(define-cproc-fix gdk-pixbuf-loader-get-pixbuf
+ (fix-arguments! '(loader::<gdk-pixbuf-loader>))
+ (fix-body!
+ "{ GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
+ if (pixbuf) SCM_RETURN(SCM_MAKE_GDK_PIXBUF(pixbuf));
+ else SCM_RETURN(SCM_FALSE);}"))
+
(define-cproc-fix gdk-pixbuf-loader-new-with-type
(fix-arguments! '(image-type::<const-char*>))
(fix-body! "GError *perr = NULL;
==========================================================================
I really like Gauche and thank you for producing and maintaining it
and 'gauche-gtk2' as well. It still works on Fedora Asahi Remix 42
which I am running on a Mac Mini M2 Pro.
Stephen Lewis
--
|
|
From: Andreas E. <and...@gm...> - 2025-07-23 08:02:39
|
On Di 22 Jul 2025 at 13:56, Shiro Kawai <shi...@gm...> wrote: > Hi Andreas, welcome to the list. > Did you re-run ./configure after pulling from git repo? > --shiro Thanks, that fixed it! How foolish of me. Andreas -- ceterum censeo redmondinem esse delendam |
|
From: Shiro K. <shi...@gm...> - 2025-07-22 23:56:25
|
Hi Andreas, welcome to the list. Did you re-run ./configure after pulling from git repo? --shiro On Tue, Jul 22, 2025 at 12:25 PM Andreas Eder via Gauche-devel < gau...@li...> wrote: > Hello list, > > this is my first mail here. > > when doing a 'make check' it dies with tje following error: > > ,---- > | Testing integer arithmetic macros ... passed. > | cat: ../test/TESTS: No such file or directory > | *** ERROR: cannot find "../test/capi.scm" to load > | Stack Trace: > | _______________________________________ > | 0 (report-error e) > | 1 (find-load-file file paths suffixes :error-if-not-found error ... > | 2 (load (cadr args)) > | 3 (main args) > | make[1]: *** [Makefile:482: test] Error 70 > | make[1]: Leaving directory '/source/Gauche/src' > | make: *** [Makefile:55: check] Error 2 > `---- > > I guess the '../test/TESTS' should be a 'tests/TEST'. and > '../test/capi.scm' should be '../tests/capi.scm'. > > Yours, > > Andreas > > -- > ceterum censeo redmondinem esse delendam > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Andreas E. <and...@gm...> - 2025-07-22 22:24:58
|
Hello list, this is my first mail here. when doing a 'make check' it dies with tje following error: ,---- | Testing integer arithmetic macros ... passed. | cat: ../test/TESTS: No such file or directory | *** ERROR: cannot find "../test/capi.scm" to load | Stack Trace: | _______________________________________ | 0 (report-error e) | 1 (find-load-file file paths suffixes :error-if-not-found error ... | 2 (load (cadr args)) | 3 (main args) | make[1]: *** [Makefile:482: test] Error 70 | make[1]: Leaving directory '/source/Gauche/src' | make: *** [Makefile:55: check] Error 2 `---- I guess the '../test/TESTS' should be a 'tests/TEST'. and '../test/capi.scm' should be '../tests/capi.scm'. Yours, Andreas -- ceterum censeo redmondinem esse delendam |
|
From: Shiro K. <shi...@gm...> - 2025-03-22 22:16:42
|
Hmm. From the doc it seems that it should be handled by zlib size by default. Gauche side does not do anything special. Need to dig more. On Wed, Mar 19, 2025 at 12:30 AM Jens Thiele <ka...@ka...> wrote: > Hi, > > Looks like the rfc.zlib module doesn't use the checksum? > > Simulating corruption using tr: > > $ echo hello > hello; zopfli -c --zlib hello|tr H I|pigz -d > lello > pigz: skipping: <stdin>: corrupted -- adler32 mismatch > > $ echo hello > hello; zopfli -c --zlib hello|tr H I \ > |gosh -urfc.zlib -E \ > 'display (inflate-string (port->string (current-input-port)))' > lello > > jens > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Jens T. <ka...@ka...> - 2025-03-19 10:30:21
|
Hi, Looks like the rfc.zlib module doesn't use the checksum? Simulating corruption using tr: $ echo hello > hello; zopfli -c --zlib hello|tr H I|pigz -d lello pigz: skipping: <stdin>: corrupted -- adler32 mismatch $ echo hello > hello; zopfli -c --zlib hello|tr H I \ |gosh -urfc.zlib -E \ 'display (inflate-string (port->string (current-input-port)))' lello jens |
|
From: Jens T. <ka...@ka...> - 2025-02-27 16:08:50
|
Hi,
sorry for the late reply
Shiro Kawai <shi...@gm...> writes:
> The last pushed commit addresses the busy loop issue; thread-terminate!
> sends a signal and wait a bit, and if the target is still running, sends
> the signal again. In the receiving side, if thread termination signal is
> received while the previous one hasn't been processed, it terminates itself.
tested this in a debian/trixie amd64 schroot
seems to work
#!/bin/sh
#| -*- mode: scheme; coding: utf-8; -*-
exec gosh -I. -- $0 "$@"
|#
;; native busy loops are not interrupted by thread-terminate!
;; nb: that changed in commit 7f3cfd906 (Thread termination by signal overhaul)
(use gauche.threads)
(use file.util)
(use runtime-compile)
(compile-and-load
`((inline-stub
(define-cproc busy-loop ()
(let* ((i::int 0))
(while (1)
;; you would do some calculations here
(inc! i))))))
'(busy-loop))
(define (num-threads)
(guard (e
[else
+nan.0])
(length (directory-list "/proc/self/task" :children? #t))))
(define (main args)
#?=(num-threads)
(let1 t (thread-start! (make-thread (lambda()
(busy-loop))))
(sys-sleep 1)
#?=(num-threads)
(thread-terminate! t)
#?=(num-threads)
(guard (e [else #?=e])
(thread-join! t)))
#?=(num-threads)
(sys-sleep 1)
#?=(num-threads)
(sys-sleep 10)
0)
(trixie-amd64-sbuild)karme@amalthea:/tmp/test$ ./busy-loop3.scm
#?="././busy-loop3.scm":29:(num-threads)
#?- 4
#?="././busy-loop3.scm":33:(num-threads)
#?- 5
#?="././busy-loop3.scm":35:(num-threads)
#?- 4
#?=e
#?- #<terminated-thread-exception: #<thread #f (1) terminated 0x7 ...
#?="././busy-loop3.scm":38:(num-threads)
#?- 4
#?="././busy-loop3.scm":40:(num-threads)
#?- 4
> This does not address the cleanup issue.
ok
jens
|
|
From: Shiro K. <shi...@gm...> - 2025-01-31 01:27:38
|
The last pushed commit addresses the busy loop issue; thread-terminate! sends a signal and wait a bit, and if the target is still running, sends the signal again. In the receiving side, if thread termination signal is received while the previous one hasn't been processed, it terminates itself. This does not address the cleanup issue. On Tue, Jan 28, 2025 at 9:35 AM Jens Thiele <ka...@ka...> wrote: > Shiro Kawai <shi...@gm...> writes: > > > Aah, right. On Unix-based systems, thread-terminate! uses a signal to > tell > > the target to terminate. It can't be intercepted by Scheme-level, but it > > is still queued by the receiving side, and only becomes effective when > the > > thread calls Scm_SigCheck()---usually from the VM loop. > > > I think the supposed way is that C extension code needs to invoke > > Scm_SigCheck() occasionally if it doesn't return control to Scheme. > > thanks! > will try to use Scm_SigCheck. Looking at data.queue as example. > > > But that can't be enforced, especially if it's in the third party > > code. > > > > We can employ a similar handling mechanism like typing ^C several times > to > > force gosh quit. That is, thread-terminate! resends thread termination > > signal after a short wait, and if the receiving side gets multiple > > termination signal queued, it terminates the thread then. > > I see you created an issue for that: > https://github.com/shirok/Gauche/issues/1106 > > Jens > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Jens T. <ka...@ka...> - 2025-01-28 19:35:24
|
Shiro Kawai <shi...@gm...> writes: > Aah, right. On Unix-based systems, thread-terminate! uses a signal to tell > the target to terminate. It can't be intercepted by Scheme-level, but it > is still queued by the receiving side, and only becomes effective when the > thread calls Scm_SigCheck()---usually from the VM loop. > I think the supposed way is that C extension code needs to invoke > Scm_SigCheck() occasionally if it doesn't return control to Scheme. thanks! will try to use Scm_SigCheck. Looking at data.queue as example. > But that can't be enforced, especially if it's in the third party > code. > > We can employ a similar handling mechanism like typing ^C several times to > force gosh quit. That is, thread-terminate! resends thread termination > signal after a short wait, and if the receiving side gets multiple > termination signal queued, it terminates the thread then. I see you created an issue for that: https://github.com/shirok/Gauche/issues/1106 Jens |
|
From: Shiro K. <shi...@gm...> - 2025-01-28 08:26:13
|
Aah, right. On Unix-based systems, thread-terminate! uses a signal to tell the target to terminate. It can't be intercepted by Scheme-level, but it is still queued by the receiving side, and only becomes effective when the thread calls Scm_SigCheck()---usually from the VM loop. I think the supposed way is that C extension code needs to invoke Scm_SigCheck() occasionally if it doesn't return control to Scheme. But that can't be enforced, especially if it's in the third party code. We can employ a similar handling mechanism like typing ^C several times to force gosh quit. That is, thread-terminate! resends thread termination signal after a short wait, and if the receiving side gets multiple termination signal queued, it terminates the thread then. On Mon, Jan 27, 2025 at 7:26 AM Jens Thiele <ka...@ka...> wrote: > Hi, > > It looks like native busy loops are not interrupted by thread-terminate! > => they have to cooperate. > > A first test below. Does that make sense? Is it ok to use > SCM_INTERNAL_MUTEX_LOCK/SCM_INTERNAL_MUTEX_UNLOCK/SCM_INTERNAL_THREAD_EXIT > ? > > #!/bin/sh > #| -*- mode: scheme; coding: utf-8; -*- > exec gosh -I. -- $0 "$@" > |# > > ;; native busy loops are not interrupted by thread-terminate! > ;; => they have to cooperate > > (use gauche.threads) > (use file.util) > (use runtime-compile) > > (compile-and-load > `((inline-stub > (define-cproc busy-loop () > (let* ((i::int 0)) > (while (1) > ;; you would do some calculations here > (inc! i) > ;; poll whether we have to terminate > ;; otherwise we keep running on thread-terminate! below > (when (not (% i 100000)) > (let* ((state::int 0)) > (SCM_INTERNAL_MUTEX_LOCK (-> (Scm_VM) vmlock)) > (set! state (-> (Scm_VM) state)) > (SCM_INTERNAL_MUTEX_UNLOCK (-> (Scm_VM) vmlock)) > (printf "%d %d %d\n" i state SCM_VM_TERMINATED) > (when (== state SCM_VM_TERMINATED) > (SCM_INTERNAL_THREAD_EXIT))))))))) > '(busy-loop)) > > ;; todo: linux specific > (define (num-threads) > (guard (e > [else > +nan.0]) > (length (directory-list "/proc/self/task" :children? #t)))) > > (define (main args) > #?=(num-threads) > (let1 t (thread-start! (make-thread (lambda() > (busy-loop)))) > (sys-sleep 1) > #?=(num-threads) > (thread-terminate! t) > #?=(num-threads) > (guard (e [else #?=e]) > (thread-join! t))) > #?=(num-threads) > (sys-sleep 1) > #?=(num-threads) > (sys-sleep 10) > 0) > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Jens T. <ka...@ka...> - 2025-01-27 17:25:39
|
Hi,
It looks like native busy loops are not interrupted by thread-terminate!
=> they have to cooperate.
A first test below. Does that make sense? Is it ok to use
SCM_INTERNAL_MUTEX_LOCK/SCM_INTERNAL_MUTEX_UNLOCK/SCM_INTERNAL_THREAD_EXIT
?
#!/bin/sh
#| -*- mode: scheme; coding: utf-8; -*-
exec gosh -I. -- $0 "$@"
|#
;; native busy loops are not interrupted by thread-terminate!
;; => they have to cooperate
(use gauche.threads)
(use file.util)
(use runtime-compile)
(compile-and-load
`((inline-stub
(define-cproc busy-loop ()
(let* ((i::int 0))
(while (1)
;; you would do some calculations here
(inc! i)
;; poll whether we have to terminate
;; otherwise we keep running on thread-terminate! below
(when (not (% i 100000))
(let* ((state::int 0))
(SCM_INTERNAL_MUTEX_LOCK (-> (Scm_VM) vmlock))
(set! state (-> (Scm_VM) state))
(SCM_INTERNAL_MUTEX_UNLOCK (-> (Scm_VM) vmlock))
(printf "%d %d %d\n" i state SCM_VM_TERMINATED)
(when (== state SCM_VM_TERMINATED)
(SCM_INTERNAL_THREAD_EXIT)))))))))
'(busy-loop))
;; todo: linux specific
(define (num-threads)
(guard (e
[else
+nan.0])
(length (directory-list "/proc/self/task" :children? #t))))
(define (main args)
#?=(num-threads)
(let1 t (thread-start! (make-thread (lambda()
(busy-loop))))
(sys-sleep 1)
#?=(num-threads)
(thread-terminate! t)
#?=(num-threads)
(guard (e [else #?=e])
(thread-join! t)))
#?=(num-threads)
(sys-sleep 1)
#?=(num-threads)
(sys-sleep 10)
0)
|
|
From: Shiro K. <shi...@gm...> - 2025-01-23 03:44:29
|
Thanks. Patch applied.
On Wed, Jan 22, 2025 at 5:15 AM Jens Thiele <ka...@ka...> wrote:
> diff --git a/doc/modsrfi.texi b/doc/modsrfi.texi
> index 391dcd3f6..490d3f878 100644
> --- a/doc/modsrfi.texi
> +++ b/doc/modsrfi.texi
> @@ -13433,7 +13433,7 @@ Same as @code{(map enum-name (enum-set->enum-list
> eset))}.
> @mdindex srfi.210
> @c EN
> This module provides macros and procedures to blend multiple-value
> -expressions naturally into the orinary single-value expressions.
> +expressions naturally into the ordinary single-value expressions.
> @c JP
> このモジュールは、複数の値を返す式を通常の単一の値を扱う式にうまく混ぜて使えるようにする
> マクロや手続きを提供します。
> diff --git a/doc/modutil.texi b/doc/modutil.texi
> index 6092151bb..e01d1216d 100644
> --- a/doc/modutil.texi
> +++ b/doc/modutil.texi
> @@ -2489,7 +2489,7 @@ returned input port.
> This module provides high-level utilities to run code in parallel
> using threads.
> For example, the @code{pmap} procedure applies the given procedure
> -on each elements in the collection and gathers the restuls into a list,
> +on each elements in the collection and gathers the results into a list,
> just like @code{map}, but the appliation of the procedure is done in
> parallel.
> @c JP
> このモジュールは、コードを複数スレッドで並列に走らせる高レベルユーティリティを提供します。
> @@ -2601,7 +2601,7 @@ cancelled and the condition is reraised.
> @subheading Mappers
>
> @c EN
> -A mapper is an object that encapsulates a storategy to run
> +A mapper is an object that encapsulates a strategy to run
> tasks in parallel. We provide the following mappers.
> @c JP
> mapperはタスクを並列に走らせる戦略をカプセル化したものです。
> diff --git a/lib/control/future.scm b/lib/control/future.scm
> index b512b505c..b0e17ed70 100644
> --- a/lib/control/future.scm
> +++ b/lib/control/future.scm
> @@ -34,7 +34,7 @@
> ;; This is a provisional implementation; we'll use implicit thread pool
> ;; to avoid thread creation overhead eventually.
>
> -;; Guile and Racket uses 'touch' to retrive the result of a future, but
> +;; Guile and Racket uses 'touch' to retrieve the result of a future, but
> ;; that name seems too generic. We adopt 'future-get'.
>
> ;; If a future already finished computation, 'future-get' returns
> immediately
> diff --git a/lib/control/pmap.scm b/lib/control/pmap.scm
> index 428a75ce6..69176efc4 100644
> --- a/lib/control/pmap.scm
> +++ b/lib/control/pmap.scm
> @@ -54,7 +54,7 @@
> ;; sequential-mapper - A sigleton mapper that runs in a single
> (current) thread.
> ;; If the running system is single-core, this is the default mapper.
> ;;
> -;; pool-mapper - Use thread pool. This is ideal when each task requies
> +;; pool-mapper - Use thread pool. This is ideal when each task requires
> ;; some processing time, so that the overhead of thread pool is
> ;; negligible.
> ;;
> diff --git a/lib/text/unicode/ucd.scm b/lib/text/unicode/ucd.scm
> index 706f10137..111989fb0 100644
> --- a/lib/text/unicode/ucd.scm
> +++ b/lib/text/unicode/ucd.scm
> @@ -603,7 +603,7 @@
> ;;;
>
> ;; Dump format should be regarded as internal - we may change it at any
> -;; tiem as we like.
> +;; time as we like.
>
> ;; For now, we dump it in three parts, correspoinding to the unichar-db
> ;; slots. To suppress the size of the dump, we use simple run-length
> diff --git a/src/thread.c b/src/thread.c
> index e26a22f5e..a78b0fdeb 100644
> --- a/src/thread.c
> +++ b/src/thread.c
> @@ -376,7 +376,7 @@ ScmObj Scm_ThreadSleep(ScmObj timeout)
> in VM loop, it responds to the flag and terminates itself.
>
> If that fails, we send a signal to the thread. If the thread is
> blocked
> - by a system call, this most likely unblocks the thread and termnates
> it.
> + by a system call, this most likely unblocks the thread and terminates
> it.
> (We use a dedicated signal.
>
> There are cases when signals can fail. On POSIX platform, if the
> thread
>
> _______________________________________________
> Gauche-devel mailing list
> Gau...@li...
> https://lists.sourceforge.net/lists/listinfo/gauche-devel
>
|
|
From: Jens T. <ka...@ka...> - 2025-01-22 15:15:06
|
diff --git a/doc/modsrfi.texi b/doc/modsrfi.texi
index 391dcd3f6..490d3f878 100644
--- a/doc/modsrfi.texi
+++ b/doc/modsrfi.texi
@@ -13433,7 +13433,7 @@ Same as @code{(map enum-name (enum-set->enum-list eset))}.
@mdindex srfi.210
@c EN
This module provides macros and procedures to blend multiple-value
-expressions naturally into the orinary single-value expressions.
+expressions naturally into the ordinary single-value expressions.
@c JP
このモジュールは、複数の値を返す式を通常の単一の値を扱う式にうまく混ぜて使えるようにする
マクロや手続きを提供します。
diff --git a/doc/modutil.texi b/doc/modutil.texi
index 6092151bb..e01d1216d 100644
--- a/doc/modutil.texi
+++ b/doc/modutil.texi
@@ -2489,7 +2489,7 @@ returned input port.
This module provides high-level utilities to run code in parallel
using threads.
For example, the @code{pmap} procedure applies the given procedure
-on each elements in the collection and gathers the restuls into a list,
+on each elements in the collection and gathers the results into a list,
just like @code{map}, but the appliation of the procedure is done in parallel.
@c JP
このモジュールは、コードを複数スレッドで並列に走らせる高レベルユーティリティを提供します。
@@ -2601,7 +2601,7 @@ cancelled and the condition is reraised.
@subheading Mappers
@c EN
-A mapper is an object that encapsulates a storategy to run
+A mapper is an object that encapsulates a strategy to run
tasks in parallel. We provide the following mappers.
@c JP
mapperはタスクを並列に走らせる戦略をカプセル化したものです。
diff --git a/lib/control/future.scm b/lib/control/future.scm
index b512b505c..b0e17ed70 100644
--- a/lib/control/future.scm
+++ b/lib/control/future.scm
@@ -34,7 +34,7 @@
;; This is a provisional implementation; we'll use implicit thread pool
;; to avoid thread creation overhead eventually.
-;; Guile and Racket uses 'touch' to retrive the result of a future, but
+;; Guile and Racket uses 'touch' to retrieve the result of a future, but
;; that name seems too generic. We adopt 'future-get'.
;; If a future already finished computation, 'future-get' returns immediately
diff --git a/lib/control/pmap.scm b/lib/control/pmap.scm
index 428a75ce6..69176efc4 100644
--- a/lib/control/pmap.scm
+++ b/lib/control/pmap.scm
@@ -54,7 +54,7 @@
;; sequential-mapper - A sigleton mapper that runs in a single (current) thread.
;; If the running system is single-core, this is the default mapper.
;;
-;; pool-mapper - Use thread pool. This is ideal when each task requies
+;; pool-mapper - Use thread pool. This is ideal when each task requires
;; some processing time, so that the overhead of thread pool is
;; negligible.
;;
diff --git a/lib/text/unicode/ucd.scm b/lib/text/unicode/ucd.scm
index 706f10137..111989fb0 100644
--- a/lib/text/unicode/ucd.scm
+++ b/lib/text/unicode/ucd.scm
@@ -603,7 +603,7 @@
;;;
;; Dump format should be regarded as internal - we may change it at any
-;; tiem as we like.
+;; time as we like.
;; For now, we dump it in three parts, correspoinding to the unichar-db
;; slots. To suppress the size of the dump, we use simple run-length
diff --git a/src/thread.c b/src/thread.c
index e26a22f5e..a78b0fdeb 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -376,7 +376,7 @@ ScmObj Scm_ThreadSleep(ScmObj timeout)
in VM loop, it responds to the flag and terminates itself.
If that fails, we send a signal to the thread. If the thread is blocked
- by a system call, this most likely unblocks the thread and termnates it.
+ by a system call, this most likely unblocks the thread and terminates it.
(We use a dedicated signal.
There are cases when signals can fail. On POSIX platform, if the thread
|
|
From: Jens T. <ka...@ka...> - 2025-01-21 10:26:42
|
maybe another point (missing multiple values support): gosh> (with-timeout (lambda() (values 1 2)) 1) 1 |
|
From: Shiro K. <shi...@gm...> - 2025-01-21 09:22:07
|
Good point. Safe termination of threads has always been a concern. I vaguely remember I once tried a condition mechanism (e.g. termination sends a special exception to a thread, and the thread rewinds dynamic handlers) but didn't work---the condition mechanism can intercept it. Since the after-thunk of the dynamic handler is free to invoke previously captured continuations, we can't guarantee that it terminates. We may still introduce rewinding of dynamic handlers, just prohibit certain control transfers from them. Another option is to have a separate cleanup stack like pthread_cleanup_push/pop. Current termination semantics is very hard to use safely, anyway, so it may be good to dive and fix this now in some way. On Mon, Jan 20, 2025 at 11:02 PM Jens Thiele <ka...@ka...> wrote: > Hi, > > very likely you are already aware of this: > > some "real-world" examples of imho unexpected behaviour with > control.timeout/with-timeout (one could argue pmap with fully concurrent > mapper + timeout also has this problem) > > 1) stop motor isn't printed: > gosh> (with-timeout > (lambda() (unwind-protect (begin (print "start motor") > (sys-sleep 10)) > (print "stop motor"))) 1) > start motor > #f > > 2) timer isn't stopped: > gosh> (use gauche.time) > gosh> (let1 tc (make <real-time-counter>) > (guard (e [else #?=e]) > (with-timeout (lambda() (with-time-counter tc > (sys-sleep 10) > (error "foo"))) > 1)) > (time-counter-value tc)) > 0 > > looks like guile does run dynamic-wind post thunks before thread > termination (I don't know whether this is really a good idea?): > > test.sh: > ,---- > | #!/bin/bash -xe > | cat > test.scm <<EOF > | (cond-expand > | (guile > | (use-modules (srfi srfi-18)) > | (use-modules (srfi srfi-34))) > | (gauche > | (use gauche.threads) > | (define sleep sys-sleep))) > | (let ((t (thread-start! > | (make-thread (lambda() > | (dynamic-wind > | (lambda _ #t) > | (lambda() > | (display "start motor\n") > | (sleep 10)) > | (lambda() > | (display "stop motor\n")))))))) > | (sleep 1) > | (thread-terminate! t) > | (guard (e (else (display e) (newline))) > | (thread-join! t))) > | EOF > | guile -s test.scm > | gosh test.scm > `---- > > ./test.sh > + cat > + guile -s test.scm > [...] > start motor > stop motor > #<&terminated-thread-exception> > + gosh test.scm > start motor > #<terminated-thread-exception: #<thread #f (1) terminated ... > > jens > > > _______________________________________________ > Gauche-devel mailing list > Gau...@li... > https://lists.sourceforge.net/lists/listinfo/gauche-devel > |
|
From: Jens T. <ka...@ka...> - 2025-01-21 09:02:36
|
Hi,
very likely you are already aware of this:
some "real-world" examples of imho unexpected behaviour with
control.timeout/with-timeout (one could argue pmap with fully concurrent
mapper + timeout also has this problem)
1) stop motor isn't printed:
gosh> (with-timeout
(lambda() (unwind-protect (begin (print "start motor")
(sys-sleep 10))
(print "stop motor"))) 1)
start motor
#f
2) timer isn't stopped:
gosh> (use gauche.time)
gosh> (let1 tc (make <real-time-counter>)
(guard (e [else #?=e])
(with-timeout (lambda() (with-time-counter tc
(sys-sleep 10)
(error "foo")))
1))
(time-counter-value tc))
0
looks like guile does run dynamic-wind post thunks before thread
termination (I don't know whether this is really a good idea?):
test.sh:
,----
| #!/bin/bash -xe
| cat > test.scm <<EOF
| (cond-expand
| (guile
| (use-modules (srfi srfi-18))
| (use-modules (srfi srfi-34)))
| (gauche
| (use gauche.threads)
| (define sleep sys-sleep)))
| (let ((t (thread-start!
| (make-thread (lambda()
| (dynamic-wind
| (lambda _ #t)
| (lambda()
| (display "start motor\n")
| (sleep 10))
| (lambda()
| (display "stop motor\n"))))))))
| (sleep 1)
| (thread-terminate! t)
| (guard (e (else (display e) (newline)))
| (thread-join! t)))
| EOF
| guile -s test.scm
| gosh test.scm
`----
./test.sh
+ cat
+ guile -s test.scm
[...]
start motor
stop motor
#<&terminated-thread-exception>
+ gosh test.scm
start motor
#<terminated-thread-exception: #<thread #f (1) terminated ...
jens
|
|
From: Jens T. <ka...@ka...> - 2025-01-14 17:28:12
|
Shiro Kawai <shi...@gm...> writes:
> I'll come back regarding the resource leak.
I am still playing around there. I now have a reverse proxy using pmap
which still exposes a similar problem after some time but I am not sure
it is really a leak. It looks more like the GC sometimes isn't running
often enough => the finalizers aren't called. After some digging I am
not even sure why the GC tends to run often enough most of the time. Is
that just good luck? At first I thought it is the GC_gcollect() in
port.c - but it isn't called at all?
If I add something like:
(when (> (num-open-files) 550)
(with-output-to-port (current-error-port)
(lambda()
(print "WARNING: explicit gc run because we are getting low on file descriptors")
(flush)
(gc))))
just before the pmap call, this seems to suffice and it doesn't happen
very often. Something like this is also suggested here:
https://www.hboehm.info/gc/finalization.html
"If scarce resources are managed with finalization, the allocation
routine for that resource (e.g. open for file handles) should force a
garbage collection (two if that doesn't suffice) if it finds itself
short of the resource."
#!/bin/sh
#| -*- mode: scheme; coding: utf-8; -*-
export GC_PRINT_STATS=1
export GC_PRINT_VERBOSE_STATS=1
exec gosh -I. -- $0 "$@"
|#
(use makiki)
(use text.html-lite)
(use rfc.http)
(use gauche.threads)
(use file.util)
(use gauche.sequence)
(use control.pmap)
(with-module control.pmap
(define join-exc (make-parameter #f))
(define (%make-joiner r)
(^[thread :optional (timeout #f) (timeout-val #f)]
(guard (e [(terminated-thread-exception? e) r]
[else (join-exc e) r])
(thread-join! thread timeout timeout-val))))
(define-syntax %with-wrapped-join
(syntax-rules ()
[(_ body ...)
(parameterize ([join-exc #f])
(receive rs (begin body ...)
(if (join-exc)
(raise (join-exc))
(apply values rs))))]))
(define-method run-map ((mapper <fully-concurrent-mapper>) proc coll)
(let ([unique (list #f)]
[ts (map (^e (make-thread (^[] (proc e)))) coll)]
[timeout (absolute-time (~ mapper'timeout))]
[timeout-val (~ mapper'timeout-val)])
(%start-threads ts)
(%with-wrapped-join
(let1 join! (%make-joiner #f)
(if timeout
($ map (^r (if (and (pair? r) (eq? (car r) unique))
(begin (thread-terminate! (cdr r)) timeout-val)
r))
$ map (^t (join! t timeout (cons unique t))) ts)
(map join! ts)))))))
;; todo: linux specific
(define (num-open-files)
(guard (e
[else
+nan.0])
(length (directory-list "/proc/self/fd" :children? #t))))
(define-http-handler (GET) "/" (^[req app]
(receive (status headers body)
(http-get "localhost:8081" "/")
(respond/ok req body))))
(define (http-get-body)
(receive (status headers body)
;; todo: detect host name and use it to force a real
;; dns lookup to occur?
(http-get "localhost:8081" "/slow")
body))
(define-http-handler (GET)
"/timeout"
(lambda(req app)
#;(when (> (num-open-files) 550)
#?=(port-buffering (current-error-port))
(with-output-to-port (current-error-port)
(lambda()
(print "WARNING: explicit gc run because we are getting low on file descriptors")
(gc))))
(let1 r (guard (e
[(uncaught-exception-condition? e)
#?=(uncaught-exception-condition-reason e)]
[else #?=e])
(pmap (lambda(i)
#;(when (= i 100) (error "i=100"))
(http-get-body))
(iota 400)
:mapper (make-fully-concurrent-mapper
0.1 'timeout)))
(cond [(and (list? r) (eq? (car r) 'timeout))
(respond/ok req
(list
(html-doctype)
(html:html
(html:head (html:title "timeout"))
(html:body
(html:p "timeout")
(html:p
(string-append
(x->string (num-open-files))
" open files"))))))]
[(and (message-condition? r) (string=? (~ r 'message) "i=100"))
(respond/ok req "i=100\n")]
[else
(request-error :body r)]))))
(define (main args)
#?=(sys-getpid)
(debug-print-width 4000)
(start-http-server :port 8080 :error-log #t)
0)
|
|
From: Shiro K. <shi...@gm...> - 2025-01-13 06:56:45
|
On Sun, Jan 12, 2025 at 8:35 PM Jens Thiele <ka...@ka...> wrote: > > I still wonder about the timeout case. But it looks like one doesn't > have to join after a successful thread-terminate!. Then only a failing > thread-terminate! case might cause a problem/"died a lonely death"? > Correct. Explicit terminate! is obviously an intended behavior. Only uncaught exceptions matter, because it's either intended to be handled after join!, or an unintended exception. |