Package single-threaded-ccl for ASDF and XCVB.
authorFrancois-Rene Rideau <fare@tunes.org>
Mon, 28 May 2012 01:40:13 +0000 (21:40 -0400)
committerFrancois-Rene Rideau <fare@tunes.org>
Mon, 28 May 2012 01:40:13 +0000 (21:40 -0400)
README
build.xcvb [new file with mode: 0644]
make-single-threaded-ccl.lisp
single-threaded-ccl.asd [new file with mode: 0644]
single-threaded-ccl.lisp [new file with mode: 0644]

diff --git a/README b/README
index 816a74c..f11584a 100644 (file)
--- a/README
+++ b/README
@@ -1,24 +1,74 @@
-The issue that single-threaded-ccl addresses is as follows.
+SINGLE-THREADED-CCL
+===================
+
+A simple patch to allow Clozure CL (CCL) to run in single-threaded mode.
+
+This is free software, available under the same license as CCL, LLGPL 2.1.
+
+
+Using It
+--------
+
+To create a single-threaded ccl, you may::
+
+       ${CCL_DEFAULT_DIRECTORY}/lx86cl64 --load make-single-threaded-ccl
+
+
+To test that indeed you can run code single-threaded mode, you may::
+
+       ./single-threaded-ccl --eval '(progn (format t "~S" ccl::*application*) (ccl::show-processes) (ccl:quit))'
+
+It your CCL is successfully single-threaded, only one process will show.
+
+
+Note that to be able to use many of the dynamically loaded features of CCL,
+you will need to either put your single-threaded-ccl in the same directory
+as the rest of CCL and use it from there, or you will need to::
+
+       export CCL_DEFAULT_DIRECTORY=/path/to/original-ccl
+
+
+If you build with ASDF, you may also depend on the system single-threaded-ccl,
+and when you next save an image, it will start single-threaded.
+
+
+Last Tested
+-----------
+
+It was last tested to run with this checkout of CCL, revision 15393.
+        http://svn.clozure.com/publicsvn/openmcl/trunk/linuxx86/ccl
+
+
+Won't Make It Upstream
+----------------------
+
+This was submitted for inclusion in the upstream CCL distribution.
+However, Gary Byers has expressed his disinterest in offering and maintaining
+an option for single-threaded startup in the upstream CCL,
+even when I proposed that I could do the porting and maintaining myself.
+
+
+
+Why We Need It
+--------------
 
 CCL by default starts ancillary threads early during initialization,
-which makes any subsequent attempt to use fork (without a prompt exec
-as in run-program) almost guaranteed to lead to massive instability.
+which makes any subsequent attempt to use fork
+almost guaranteed to lead to massive instability
+(unless maybe it's promptly followed by exec, as in run-program,
+without a GC interrupt in between).
 See my blog post:
        http://fare.livejournal.com/148185.html
 
-However, I have been maintaining this "single-threaded CCL"
-modification that can create an image of CCL that doesn't start these
-ancillary threads (at the cost of having to manually flush output
-streams and of not being able to interrupt computations interactively
-with Ctrl-C).
-
-I use this single-threaded CCL for parallel build with POIU, and have
-had to update it once in a while as upstream upgrades sometimes break
-it.  I also intend to use it in other situations where fork-based
-concurrency is called fork: pre-forking servers, robust erlang-style
-concurrency, isolating semi-trusted C libraries, etc.
-
-For the record, Gary Byers has expressed his disinterest in offering
-and maintaining an option for single-threaded startup in the upstream
-CCL, even when I proposed that I could do the porting and maintaining
-myself.
+However, I have been maintaining this "single-threaded CCL" modification
+that can create an image of CCL that doesn't start these ancillary threads
+(at the cost of having to manually flush output streams and
+of not being able to interrupt computations interactively with Ctrl-C).
+
+I use this single-threaded CCL for parallel build with POIU and XCVB,
+and have had to update it once in a while
+as upstream upgrades sometimes break it.
+I also intend to use it in other situations
+where fork-based concurrency is called for:
+pre-forking servers, robust erlang-style concurrency,
+isolating semi-trusted C libraries, etc.
diff --git a/build.xcvb b/build.xcvb
new file mode 100644 (file)
index 0000000..ac8f032
--- /dev/null
@@ -0,0 +1,4 @@
+(module
+ (:fullname "single-threaded-ccl"
+  :depends-on ((:when (:featurep :clozure) "single-threaded-ccl"))
+  :supersedes-asdf ("single-threaded-ccl")))
index f1c192d..f53f279 100644 (file)
@@ -1,86 +1,10 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;                                                                  ;;;
-;;; Free Software under the GNU LLGPL 2.1 (same as CCL itself)       ;;;
-;;;                                                                  ;;;
-;;; Copyright (c) 2008-2011 ITA Software, Inc.  All rights reserved. ;;;
-;;;                                                                  ;;;
-;;; Original authors: Francois-Rene Rideau                           ;;;
-;;;                                                                  ;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-#|
-This is a simple patch to allow Clozure CL (CCL) to run in single-threaded mode.
-
-It was last tested to run with this checkout of CCL, revision 13568 (same as 13679).
-       http://svn.clozure.com/publicsvn/openmcl/branches/qres
-
-This is free software, available under the same license as CCL.
-
-Note: This was submitted for inclusion in the upstream CCL distribution.
-However, Gary Byers is unwilling to include and maintain this patch.
-
-To create a single-threaded ccl, you may:
-       ${CCL_DEFAULT_DIRECTORY}/lx86cl64 --load make-single-threaded-ccl
-To test that indeed you can run code single-threaded mode, you may:
-       ./single-threaded-ccl --eval '(progn (format t "~S" ccl::*application*) (ccl::show-processes) (ccl:quit))'
-
-Note that to be able to use many of the dynamically loaded features of CCL,
-you will need to either put your single-threaded-ccl in the same directory
-as the rest of CCL and use it from there, or you will need to
-       export CCL_DEFAULT_DIRECTORY=/path/to/ccl
-|#
-
-(in-package :ccl)
-
-(defun finish-outputs ()
-  (finish-output *standard-output*)
-  (finish-output *error-output*)
-  (finish-output *terminal-output*)
-  (finish-output *trace-output*)
-  (housekeeping))
-
-(defun show-processes ()
-  (let ((p (all-processes)))
-    (format t "~&Total number of running lisp processes: ~d~%~W~%" (length p) p)
-    (finish-outputs)))
-
-(defun flushing-rep ()
-  (print-listener-prompt *standard-output*)
-  (finish-outputs)
-  (let* ((eof '#.'#:eof)
-         (sexp (read *standard-input* nil eof nil)))
-    (when (eq sexp eof)
-      (finish-outputs)
-      (throw :flushing-rep-eof nil))
-    ;; This use of eval is OK because it's part of the build infrastructure.
-    (format t "~&~S~%" (eval sexp))
-    (finish-outputs)))
-
-(defun flushing-repl ()
-  (catch :flushing-rep-eof
-    (loop (flushing-rep))))
-
-(defun single-threaded-toplevel ()
-  (housekeeping)
-  ;;(show-processes)
-  ;;(flushing-repl)
-  (listener-function)
-  (quit 0))
-
-(defclass single-threaded-lisp-development-system (lisp-development-system)
-    ())
-
-(defmethod repl-function-name ((a single-threaded-lisp-development-system))
-  'single-threaded-toplevel)
-
-(defmethod toplevel-function ((a single-threaded-lisp-development-system) init-file)
-  (%set-toplevel (or (repl-function-name a) 'single-threaded-toplevel))
-  (startup-ccl (and *load-lisp-init-file* init-file))
-  (toplevel))
-
-(defparameter *application* (make-instance 'single-threaded-lisp-development-system))
+":" ; exec ccl --load "$@" ; exit 42
 
 (in-package :cl-user)
 
-;;(save-application "single-threaded-ccl" :toplevel-function #'single-threaded-toplevel :prepend-kernel t)
+(load (merge-pathnames "single-threaded-ccl" *load-truename*))
 
-(save-application "single-threaded-ccl" :prepend-kernel t)
+(ccl:save-application
+ "single-threaded-ccl"
+ ;; :toplevel-function #'ccl::single-threaded-toplevel
+ :prepend-kernel t)
diff --git a/single-threaded-ccl.asd b/single-threaded-ccl.asd
new file mode 100644 (file)
index 0000000..9a8357d
--- /dev/null
@@ -0,0 +1,14 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;                                                                  ;;;
+;;; Free Software under the GNU LLGPL 2.1 (same as CCL itself)       ;;;
+;;;                                                                  ;;;
+;;; Copyright (c) 2008-2011 ITA Software, Inc.  All rights reserved. ;;;
+;;; Copyright (c) 2011-2012 Google, Inc.  All rights reserved.       ;;;
+;;;                                                                  ;;;
+;;; Original authors: Francois-Rene Rideau                           ;;;
+;;;                                                                  ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defsystem single-threaded-ccl
+  :license "LLGPL 2.1"
+  :components (#+clozure (:file "single-threaded-ccl")))
diff --git a/single-threaded-ccl.lisp b/single-threaded-ccl.lisp
new file mode 100644 (file)
index 0000000..4eb0614
--- /dev/null
@@ -0,0 +1,59 @@
+#+xcvb (module ())
+
+(in-package :ccl)
+
+(defun finish-outputs ()
+  (finish-output *standard-output*)
+  (finish-output *error-output*)
+  (finish-output *terminal-output*)
+  (finish-output *trace-output*)
+  (housekeeping))
+
+(defun show-processes ()
+  (let ((p (all-processes)))
+    (format t "~&Total number of running lisp processes: ~d~%~W~%" (length p) p)
+    (finish-outputs)))
+
+(defun flushing-rep ()
+  (print-listener-prompt *standard-output*)
+  (finish-outputs)
+  (let* ((eof '#.'#:eof)
+         (sexp (read *standard-input* nil eof nil)))
+    (when (eq sexp eof)
+      (finish-outputs)
+      (throw :flushing-rep-eof nil))
+    ;; This use of eval is OK because it's part of the build infrastructure.
+    (format t "~&~S~%" (eval sexp))
+    (finish-outputs)))
+
+(defun flushing-repl ()
+  (catch :flushing-rep-eof
+    (loop (flushing-rep))))
+
+(defun single-threaded-toplevel ()
+  (housekeeping)
+  ;;(show-processes)
+  ;;(flushing-repl)
+  (listener-function)
+  (quit 0))
+
+(defclass single-threaded-lisp-development-system (lisp-development-system)
+  ())
+
+(defmethod repl-function-name ((a single-threaded-lisp-development-system))
+  'single-threaded-toplevel)
+
+(defmethod toplevel-function ((a single-threaded-lisp-development-system) init-file)
+  (%set-toplevel (or (repl-function-name a) 'single-threaded-toplevel))
+  (startup-ccl (and *load-lisp-init-file* init-file))
+  (toplevel))
+
+(defparameter *application* (make-instance 'single-threaded-lisp-development-system))
+
+#|
+;; Use it as follows:
+(ccl::save-application
+ "single-threaded-ccl"
+ ;; :toplevel-function #'single-threaded-toplevel
+ :prepend-kernel t)
+|#