@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2013
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
-@page
@node General Libguile Concepts
@section General concepts for using libguile
@}
@end example
-Often, you need to convert between @code{SCM} values and approriate C
+Often, you need to convert between @code{SCM} values and appropriate C
values. For example, we needed to convert the integer @code{1} to its
@code{SCM} representation in order to add it to @var{a}. Libguile
provides many function to do these conversions, both from C to
@code{scm_t_bits}. This is an unsigned integral type of sufficient
size to hold all information that is directly contained in a
@code{SCM} value. The @code{scm_t_bits} type is used internally by
-Guile to do all the bit twiddling explained in @ref{Data
-Representation}, but you will encounter it occasionally in low-level
-user code as well.
+Guile to do all the bit twiddling explained in @ref{Data Representation}, but
+you will encounter it occasionally in low-level user code as well.
@node Garbage Collection
Some values fit entirely into a @code{SCM} value (such as small
integers), but other values require additional storage in the heap (such
as strings and vectors). This additional storage is managed
-automatically by Guile. You don't need to explicitely deallocate it
+automatically by Guile. You don't need to explicitly deallocate it
when a @code{SCM} value is no longer used.
Two things must be guaranteed so that Guile is able to manage the
@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 funtions for long
+@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.
long as it is really on the stack (or in some register). As an
optimization, the C compiler might reuse its location for some other
value and the @code{SCM} object would no longer be protected. Normally,
-this leads to exactly the right behabvior: the compiler will only
+this leads to exactly the right behavior: the compiler will only
overwrite a reference when it is no longer needed and thus the object
becomes unprotected precisely when the reference disappears, just as
wanted.
But only Scheme functions can call other functions in a tail position:
C functions can not. This matters when you have, say, two functions
that call each other recursively to form a common loop. The following
-(unrealistic) example shows how one might go about determing whether a
+(unrealistic) example shows how one might go about determining whether a
non-negative integer @var{n} is even or odd.
@lisp
guile mode for the first time, it gets a Scheme representation and is
listed by @code{all-threads}, for example.
-While in guile mode, a thread promises to reach a safe point
-reasonably frequently (@pxref{Asynchronous Signals}). In addition to
-running signal handlers, these points are also potential rendezvous
-points of all guile mode threads where Guile can orchestrate global
-things like garbage collection. Consequently, when a thread in guile
-mode blocks and does no longer frequent safe points, it might cause
-all other guile mode threads to block as well. To prevent this from
-happening, a guile mode thread should either only block in libguile
-functions (who know how to do it right), or should temporarily leave
-guile mode with @code{scm_without_guile}.
-
-For some common blocking operations, Guile provides convenience
-functions. For example, if you want to lock a pthread mutex while in
-guile mode, you might want to use @code{scm_pthread_mutex_lock} which is
-just like @code{pthread_mutex_lock} except that it leaves guile mode
+Threads in guile mode can block (e.g., do blocking I/O) without causing any
+problems@footnote{In Guile 1.8, a thread blocking in guile mode would prevent
+garbage collection to occur. Thus, threads had to leave guile mode whenever
+they could block. This is no longer needed with Guile 2.0.}; temporarily
+leaving guile mode with @code{scm_without_guile} before blocking slightly
+improves GC performance, though. For some common blocking operations, Guile
+provides convenience functions. For example, if you want to lock a pthread
+mutex while in guile mode, you might want to use @code{scm_pthread_mutex_lock}
+which is just like @code{pthread_mutex_lock} except that it leaves guile mode
while blocking.
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++;
@}
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 overrung 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
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++;
@}
@}
@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
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.