Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / doc / ref / libguile-concepts.texi
index 915054c..9e2eb75 100644 (file)
@@ -1,7 +1,7 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011
-@c   Free Software Foundation, Inc.
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010,
+@c   2011, 2013, 2014  Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
 @node General Libguile Concepts
@@ -191,38 +191,34 @@ periodically free all blocks that have been allocated but are not used
 by any active Scheme values.  This activity is called @dfn{garbage
 collection}.
 
-It is easy for Guile to remember all blocks of memory that it has
-allocated for use by Scheme values, but you need to help it with finding
-all Scheme values that are in use by C code.
-
-You do this when writing a SMOB mark function, for example
-(@pxref{Garbage Collecting Smobs}).  By calling this function, the
-garbage collector learns about all references that your SMOB has to
-other @code{SCM} values.
-
-Other references to @code{SCM} objects, such as global variables of type
-@code{SCM} or other random data structures in the heap that contain
-fields of type @code{SCM}, can be made visible to the garbage collector
-by calling the functions @code{scm_gc_protect} or
-@code{scm_permanent_object}.  You normally use these functions for long
-lived objects such as a hash table that is stored in a global variable.
-For temporary references in local variables or function arguments, using
-these functions would be too expensive.
-
-These references are handled differently: Local variables (and function
-arguments) of type @code{SCM} are automatically visible to the garbage
-collector.  This works because the collector scans the stack for
-potential references to @code{SCM} objects and considers all referenced
-objects to be alive.  The scanning considers each and every word of the
-stack, regardless of what it is actually used for, and then decides
-whether it could possibly be a reference to a @code{SCM} object.  Thus,
-the scanning is guaranteed to find all actual references, but it might
-also find words that only accidentally look like references.  These
-`false positives' might keep @code{SCM} objects alive that would
-otherwise be considered dead.  While this might waste memory, keeping an
-object around longer than it strictly needs to is harmless.  This is why
-this technique is called ``conservative garbage collection''.  In
-practice, the wasted memory seems to be no problem.
+Guile's garbage collector will automatically discover references to
+@code{SCM} objects that originate in global variables, static data
+sections, function arguments or local variables on the C and Scheme
+stacks, and values in machine registers.  Other references to @code{SCM}
+objects, such as those in other random data structures in the C heap
+that contain fields of type @code{SCM}, can be made visible to the
+garbage collector by calling the functions @code{scm_gc_protect} or
+@code{scm_permanent_object}.  Collectively, these values form the ``root
+set'' of garbage collection; any value on the heap that is referenced
+directly or indirectly by a member of the root set is preserved, and all
+other objects are eligible for reclamation.
+
+The Scheme stack and heap are scanned precisely; that is to say, Guile
+knows about all inter-object pointers on the Scheme stack and heap.
+This is not the case, unfortunately, for pointers on the C stack and
+static data segment.  For this reason we have to scan the C stack and
+static data segment @dfn{conservatively}; any value that looks like a
+pointer to a GC-managed object is treated as such, whether it actually
+is a reference or not.  Thus, scanning the C stack and static data
+segment is guaranteed to find all actual references, but it might also
+find words that only accidentally look like references.  These ``false
+positives'' might keep @code{SCM} objects alive that would otherwise be
+considered dead.  While this might waste memory, keeping an object
+around longer than it strictly needs to is harmless.  This is why this
+technique is called ``conservative garbage collection''.  In practice,
+the wasted memory seems to be no problem, as the static C root set is
+almost always finite and small, given that the Scheme stack is separate
+from the C stack.
 
 The stack of every thread is scanned in this way and the registers of
 the CPU and all other memory locations where local variables or function
@@ -245,17 +241,17 @@ wanted.
 There are situations, however, where a @code{SCM} object needs to be
 around longer than its reference from a local variable or function
 parameter.  This happens, for example, when you retrieve some pointer
-from a smob and work with that pointer directly.  The reference to the
-@code{SCM} smob object might be dead after the pointer has been
-retrieved, but the pointer itself (and the memory pointed to) is still
-in use and thus the smob object must be protected.  The compiler does
-not know about this connection and might overwrite the @code{SCM}
-reference too early.
+from a foreign object and work with that pointer directly.  The
+reference to the @code{SCM} foreign object might be dead after the
+pointer has been retrieved, but the pointer itself (and the memory
+pointed to) is still in use and thus the foreign object must be
+protected.  The compiler does not know about this connection and might
+overwrite the @code{SCM} reference too early.
 
 To get around this problem, you can use @code{scm_remember_upto_here_1}
 and its cousins.  It will keep the compiler from overwriting the
-reference.  For a typical example of its use, see @ref{Remembering
-During Operations}.
+reference.  @xref{Foreign Object Memory Management}.
+
 
 @node Control Flow
 @subsection Control Flow
@@ -494,12 +490,12 @@ my_list_to_vector (SCM list)
   SCM vector = scm_make_vector (scm_length (list), SCM_UNDEFINED);
   size_t len, i;
 
-  len = SCM_SIMPLE_VECTOR_LENGTH (vector);
+  len = scm_c_vector_length (vector);
   i = 0;
   while (i < len && scm_is_pair (list))
     @{
-      SCM_SIMPLE_VECTOR_SET (vector, i, SCM_CAR (list));
-      list = SCM_CDR (list);
+      scm_c_vector_set_x (vector, i, scm_car (list));
+      list = scm_cdr (list);
       i++;
     @}
 
@@ -516,22 +512,23 @@ But there is no guarantee that the list referenced by @var{list} is not
 modified in another thread while the loop iterates over it.  Thus, while
 copying its elements into the vector, the list might get longer or
 shorter.  For this reason, the loop must check both that it doesn't
-overrun the vector (@code{SCM_SIMPLE_VECTOR_SET} does no range-checking)
-and that it doesn't overrun the list (@code{SCM_CAR} and @code{SCM_CDR}
-likewise do no type checking).
+overrun the vector and that it doesn't overrun the list.  Otherwise,
+@code{scm_c_vector_set_x} would raise an error if the index is out of
+range, and @code{scm_car} and @code{scm_cdr} would raise an error if the
+value is not a pair.
 
-It is safe to use @code{SCM_CAR} and @code{SCM_CDR} on the local
+It is safe to use @code{scm_car} and @code{scm_cdr} on the local
 variable @var{list} once it is known that the variable contains a pair.
 The contents of the pair might change spontaneously, but it will always
 stay a valid pair (and a local variable will of course not spontaneously
 point to a different Scheme object).
 
-Likewise, a simple vector such as the one returned by
-@code{scm_make_vector} is guaranteed to always stay the same length so
-that it is safe to only use SCM_SIMPLE_VECTOR_LENGTH once and store the
-result.  (In the example, @var{vector} is safe anyway since it is a
-fresh object that no other thread can possibly know about until it is
-returned from @code{my_list_to_vector}.)
+Likewise, a vector such as the one returned by @code{scm_make_vector} is
+guaranteed to always stay the same length so that it is safe to only use
+scm_c_vector_length once and store the result.  (In the example,
+@var{vector} is safe anyway since it is a fresh object that no other
+thread can possibly know about until it is returned from
+@code{my_list_to_vector}.)
 
 Of course the behavior of @code{my_list_to_vector} is suboptimal when
 @var{list} does indeed get asynchronously lengthened or shortened in
@@ -549,11 +546,11 @@ my_pedantic_list_to_vector (SCM list)
   SCM vector = scm_make_vector (scm_length (list), SCM_UNDEFINED);
   size_t len, i;
 
-  len = SCM_SIMPLE_VECTOR_LENGTH (vector);
+  len = scm_c_vector_length (vector);
   i = 0;
   while (i < len)
     @{
-      SCM_SIMPLE_VECTOR_SET (vector, i, scm_car (list));
+      scm_c_vector_set_x (vector, i, scm_car (list));
       list = scm_cdr (list);
       i++;
     @}
@@ -562,12 +559,10 @@ my_pedantic_list_to_vector (SCM list)
 @}
 @end example
 
-This version uses the type-checking and thread-robust functions
-@code{scm_car} and @code{scm_cdr} instead of the faster, but less robust
-macros @code{SCM_CAR} and @code{SCM_CDR}.  When the list is shortened
-(that is, when @var{list} holds a non-pair), @code{scm_car} will throw
-an error.  This might be preferable to just returning a half-initialized
-vector.
+This version relies on the error-checking behavior of @code{scm_car} and
+@code{scm_cdr}.  When the list is shortened (that is, when @var{list}
+holds a non-pair), @code{scm_car} will throw an error.  This might be
+preferable to just returning a half-initialized vector.
 
 The API for accessing vectors and arrays of various kinds from C takes a
 slightly different approach to thread-robustness.  In order to get at
@@ -583,13 +578,13 @@ see, Guile itself is again only concerned about robustness, not about
 correctness: without proper synchronization, your program will likely
 not be correct, but the worst consequence is an error message.
 
-Real thread-safeness often requires that a critical section of code is
+Real thread-safety often requires that a critical section of code is
 executed in a certain restricted manner.  A common requirement is that
 the code section is not entered a second time when it is already being
 executed.  Locking a mutex while in that section ensures that no other
 thread will start executing it, blocking asyncs ensures that no
-asynchronous code enters the section again from the current thread,
-and the error checking of Guile mutexes guarantees that an error is
+asynchronous code enters the section again from the current thread, and
+the error checking of Guile mutexes guarantees that an error is
 signalled when the current thread accidentally reenters the critical
 section via recursive function calls.