Packaged and documented logical garbage collecting

parent bd7255a3
......@@ -16,6 +16,19 @@ AC_PROG_CC
WARN_CFLAGS=-Wall
AC_ARG_ENABLE([Werror], AC_HELP_STRING([--disable-Werror],[Don't stop the build on errors]),
[], WARN_CFLAGS="-Wall")
AC_ARG_WITH([logical-gc],
AS_HELP_STRING([--without-logical-gc],
[Ignore presence of logical gc and disable it]))
AS_IF([test "x$with_logical_gc" != "xno"],
AS_IF([test "x$with_logical_gc" != "xyes"],
AC_DEFINE([HAS_NO_GP_GC],[1],[has logical gc]),
AC_DEFINE([HAS_GP_GC],[1],[has logical gc])),
AC_DEFINE([HAS_NO_GP_GC],[1],[has not logical gc]))
AC_SUBST(WARN_CFLAGS)
PKG_CHECK_MODULES(GUILE, [guile-2.0 >= 2.0.0])
......
......@@ -36,6 +36,7 @@ Documentation for the Guile-Log Logic Programming Environment for Guile 2.0 v0.4
* sed/grep:: Sed and grep functionalities for scheme
* kanren:: Kanren implemented ontop of guile-log
* prolog:: iso-prolog
* garbage-collect:: How to enable full garbage colection of logical variables
* Index:: Complete index.
@end menu
......@@ -2330,6 +2331,19 @@ The main hash datastructure is a vhash datastructure which is a assoc like hash
The basic documentation is tha same as the postpone section for guile-log in the main section. The only addition is that this module exposes @code{postpone_frame} with an underscore.
@node garbage-collect
@chapter Prolog
Guile log sports full garbage collection of logical variables which makes it suitable to run server like prolog code. It is experimental but working. Unfourtunately the bdw-gc that guile uses does not allow this to work effectively and hence you need to download and replace the standard bdw-gc with a modified version of it. You may find it at
@code{https://gitorious.org/bdw-gc-logical-mod}
Now you typically build this and make sure to save the old gc.so that guile is using (you can google how to find which shared libraries guile is using) and then clobber the bdw-gc .so file with the newly created one (sic). This is of cause not a simple thing to do, but until we can get some comparable feature in bdw-gc this is what you need to do. Then finally when configureing guile log do something like
@code{./configure --with-logical-gc}
And then make, make install and you will run guile-log with garbage collection on. Happy hacking!
@node Index
@chapter Index of the guile-log api
@unnumbered Index
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -49,6 +49,7 @@ Up:&nbsp;<a rel="up" accesskey="u" href="../index.html#dir">(dir)</a>
<li><a accesskey="8" href="sed_002fgrep.html#sed_002fgrep">sed/grep</a>: Sed and grep functionalities for scheme
<li><a accesskey="9" href="kanren.html#kanren">kanren</a>: Kanren implemented ontop of guile-log
<li><a href="prolog.html#prolog">prolog</a>: iso-prolog
<li><a href="garbage_002dcollect.html#garbage_002dcollect">garbage-collect</a>: How to enable full garbage colection of logical variables
<li><a href="Index.html#Index">Index</a>: Complete index.
</ul>
......
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- This is a preliminary manual of guile-log package for guile-2.0
Copyright (C) 2012 Stefan Israelsson Tampe -->
<!-- Created by GNU Texinfo 5.1, http://www.gnu.org/software/texinfo/ -->
<html lang="en">
<head>
<title>Preliminary Manual: prolog</title>
<meta name="description" content="Preliminary Manual: prolog">
<meta name="keywords" content="Preliminary Manual: prolog">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Index.html#Index" rel="index" title="Index">
<link href="index.html#Top" rel="up" title="Top">
<link href="running.html#running" rel="next" title="running">
<link href="kanren.html#kanren" rel="previous" title="kanren">
<style type="text/css">
<title>prolog - Preliminary Manual</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Preliminary Manual">
<meta name="generator" content="makeinfo 4.13">
<link title="Top" rel="start" href="index.html#Top">
<link rel="prev" href="kanren.html#kanren" title="kanren">
<link rel="next" href="garbage_002dcollect.html#garbage_002dcollect" title="garbage-collect">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<!--
a.summary-letter {text-decoration: none}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.indentedblock {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
div.smalllisp {margin-left: 3.2em}
kbd {font-style:oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nocodebreak {white-space:nowrap}
span.nolinebreak {white-space:nowrap}
span.roman {font-family:serif; font-weight:normal}
span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
This is a preliminary manual of guile-log package for guile-2.0
Copyright (C) 2012 Stefan Israelsson Tampe-->
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
pre.display { font-family:inherit }
pre.format { font-family:inherit }
pre.smalldisplay { font-family:inherit; font-size:smaller }
pre.smallformat { font-family:inherit; font-size:smaller }
pre.smallexample { font-size:smaller }
pre.smalllisp { font-size:smaller }
span.sc { font-variant:small-caps }
span.roman { font-family:serif; font-weight:normal; }
span.sansserif { font-family:sans-serif; font-weight:normal; }
--></style>
</head>
<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<body>
<div class="node">
<a name="prolog"></a>
<div class="header">
<p>
Next: <a href="Index.html#Index" accesskey="n" rel="next">Index</a>, Previous: <a href="kanren.html#kanren" accesskey="p" rel="previous">kanren</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="Index.html#Index" title="Index" rel="index">Index</a>]</p>
</div>
Next:&nbsp;<a rel="next" accesskey="n" href="garbage_002dcollect.html#garbage_002dcollect">garbage-collect</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="kanren.html#kanren">kanren</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a>
<hr>
<a name="Prolog"></a>
</div>
<h2 class="chapter">10 Prolog</h2>
<p>Guile log also sports an iso-prolog interface as a logic programming interface besides kanren. The interface is pretty complete at this point appart a few points that have not yet been resolved but sure it is currently alpha software and help is very very much appriciated. With this most programs written in iso prolog should probably work. The intention is to enhance this interface so that the bulk of already written prolog programs should be able to run on guile. We will also add the fetures unique to guile-log and hence enhance the prolog experience. Featurewise guile-log prolog is taking over many properties of scheme like closures, continuations, delimeted continuations, the interleaving constructs of kanren and a delicate system to treat dynamic objects like dynamic functions, dynamic hashes and a library to tell how you want the dynamism to work at a fine grained level.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><td align="left" valign="top">&bull; <a href="running.html#running" accesskey="1">running</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">How to hook in prolog code
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="interpreter.html#interpreter" accesskey="2">interpreter</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">A interactive shell for prolog
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="deviations.html#deviations" accesskey="3">deviations</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">What is different and not according to standard and why.
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="modules.html#modules" accesskey="4">modules</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">How to handle name spacing
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="scheme.html#scheme" accesskey="5">scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">Hooking in scheme expressions
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="closures.html#closures" accesskey="6">closures</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">Using closures in prolog
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="prolog_002ddynamic_002dfunctions.html#prolog_002ddynamic_002dfunctions" accesskey="7">prolog-dynamic-functions</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">A discussion of guile log&rsquo;s version of this
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="dynamic_002dfeatures.html#dynamic_002dfeatures" accesskey="8">dynamic-features</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">Special construct to manage dynamic objects
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="prolog_002dlibraries.html#prolog_002dlibraries" accesskey="9">prolog-libraries</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">Libraries that exposes guile-log features
</td></tr>
</table>
<hr>
<div class="header">
<p>
Next: <a href="Index.html#Index" accesskey="n" rel="next">Index</a>, Previous: <a href="kanren.html#kanren" accesskey="p" rel="previous">kanren</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="Index.html#Index" title="Index" rel="index">Index</a>]</p>
</div>
<p>Guile log also sports an iso-prolog interface as a logic programming interface besides kanren. The interface is pretty complete at this point appart a few points that have not yet been resolved but sure it is currently alpha software and help is very very much appriciated. With this most programs written in iso prolog should probably work. The intention is to enhance this interface so that the bulk of already written prolog programs should be able to run on guile. We will also add the fetures unique to guile-log and hence enhance the prolog experience. Featurewise guile-log prolog is taking over many properties of scheme like closures, continuations, delimeted continuations, the interleaving constructs of kanren and a delicate system to treat dynamic objects like dynamic functions, dynamic hashes and a library to tell how you want the dynamism to work at a fine grained level.
<ul class="menu">
<li><a accesskey="1" href="running.html#running">running</a>: How to hook in prolog code
<li><a accesskey="2" href="interpreter.html#interpreter">interpreter</a>: A interactive shell for prolog
<li><a accesskey="3" href="deviations.html#deviations">deviations</a>: What is different and not according to standard and why.
<li><a accesskey="4" href="modules.html#modules">modules</a>: How to handle name spacing
<li><a accesskey="5" href="scheme.html#scheme">scheme</a>: Hooking in scheme expressions
<li><a accesskey="6" href="closures.html#closures">closures</a>: Using closures in prolog
<li><a accesskey="7" href="prolog_002ddynamic_002dfunctions.html#prolog_002ddynamic_002dfunctions">prolog-dynamic-functions</a>: A discussion of guile log's version of this
<li><a accesskey="8" href="dynamic_002dfeatures.html#dynamic_002dfeatures">dynamic-features</a>: Special construct to manage dynamic objects
<li><a accesskey="9" href="prolog_002dlibraries.html#prolog_002dlibraries">prolog-libraries</a>: Libraries that exposes guile-log features
</ul>
</body></html>
</body>
</html>
This diff is collapsed.
#include <pthread.h>
int gp_gc_p = 0;
#ifdef HAS_GP_GC
static int isBefore = 1;
#endif
pthread_mutex_t gp_gc_lock = PTHREAD_MUTEX_INITIALIZER;
void gp_no_gc()
{
#ifdef HAS_GP_GC
pthread_mutex_lock(&gp_gc_lock);
gp_gc_p ++;
pthread_mutex_unlock(&gp_gc_lock);
#endif
}
void gp_do_gc()
{
#ifdef HAS_GP_GC
pthread_mutex_lock(&gp_gc_lock);
gp_gc_p --;
pthread_mutex_unlock(&gp_gc_lock);
#endif
}
int is_gc_locked()
......@@ -34,6 +40,7 @@ int is_gc_locked()
void *gp_after_mark_hook(void *hook_data, void *fn_data, void *data)
{
#ifdef HAS_GP_GC
SCM pt = scm_fluid_ref(gp_stacks);
pthread_mutex_lock(&gp_gc_lock);
......@@ -44,11 +51,13 @@ void *gp_after_mark_hook(void *hook_data, void *fn_data, void *data)
pt = SCM_CDR(pt);
}
pthread_mutex_unlock(&gp_gc_lock);
#endif
return (void *)0;
}
void *gp_before_mark_hook(void *hook_data, void *fn_data, void *data)
{
#ifdef HAS_GP_GC
SCM pt = scm_fluid_ref(gp_stacks);
while(SCM_CONSP(pt))
......@@ -56,15 +65,17 @@ void *gp_before_mark_hook(void *hook_data, void *fn_data, void *data)
gp_clear_marks(SCM_CAR(pt), isBefore);
pt = SCM_CDR(pt);
}
#endif
return (void *)0;
}
void init_gpgc()
{
#ifdef HAS_GP_GC
const int appendp = 0;
void *data = (void *) 0;
scm_c_hook_add(&scm_after_gc_c_hook, gp_after_mark_hook, data, appendp);
scm_c_hook_add(&scm_before_gc_c_hook, gp_before_mark_hook, data, appendp);
#endif
}
......@@ -251,8 +251,14 @@ static inline SCM *make_gp_stack(int id, int nthread, int nc, int ns, int ncs, s
gp->thread_id = nthread;
gp->nrem = 0;
gp->n = 0;
SCM ret = PTR2SCM (GC_generic_malloc (2 * sizeof (scm_t_cell),
SCM ret;
#ifdef HAS_GP_GC
ret = PTR2SCM (GC_generic_malloc (2 * sizeof (scm_t_cell),
gp_variable_gc_kind));
#else
ret = scm_new_smob(gp_stack_type, (scm_t_bits)0);
#endif
GP_GETREF(ret)[0] = SCM_PACK(gp_stack_type);
GP_GETREF(ret)[1] = GP_UNREF((SCM *) gp);
......@@ -834,6 +840,7 @@ void gp_init_stacks()
SCM_DEFINE(gp_gc, "gp-gc", 0, 0, 0, (), "clean up the stack")
#define FUNC_NAME s_gp_gc
{
#ifdef HAS_GP_GC
int mute = 0;
struct gp_stack *gp = get_gp();
gp_no_gc();
......@@ -1002,6 +1009,7 @@ SCM_DEFINE(gp_gc, "gp-gc", 0, 0, 0, (), "clean up the stack")
gp_do_gc();
#endif
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
......@@ -18,11 +18,10 @@
#include<libguile.h>
#include<stdio.h>
#include "../../../config.h"
#include "unify.h"
#define VECTOR_HEADER_SIZE 2
#define GP_USE_GC_MOCK 1
SCM tester = SCM_BOOL_F;
......
......@@ -3,7 +3,7 @@
/*
We need a special variable
*/
#ifdef GP_USE_GC_MOCK!
#ifdef HAS_GP_GC
static int gp_variable_gc_kind;
static struct GC_ms_entry *
......@@ -40,7 +40,7 @@ gp_mark_variable (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
SCM gp_make_variable()
{
#ifdef GP_USE_GC_MOCK
#ifdef HAS_GP_GC
SCM ret = PTR2SCM (GC_generic_malloc (2 * sizeof (scm_t_cell),
gp_variable_gc_kind));
......@@ -51,7 +51,6 @@ SCM gp_make_variable()
return ret;
#else
SCM ret = scm_new_smob(gp_type, (scm_t_bits)0);
SCM *v = GP_GETREF(ret);
v[0] = SCM_PACK(GP_MK_FRAME_UNBD(gp_type) | GPI_SCM_Q);
......@@ -63,7 +62,7 @@ SCM gp_make_variable()
void init_variables()
{
#ifdef GP_USE_GC_MOCK
#ifdef HAS_GP_GC
gp_variable_gc_kind
= GC_new_kind_adv (GC_new_free_list (),
GC_MAKE_PROC (GC_new_proc (gp_mark_variable), 0),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment