X-Git-Url: https://git.hcoop.net/bpt/guile.git/blobdiff_plain/e88d45aa731eae1c5742f100fdf0731202f7b434..56a3dcd4311d26ef2e9d14ef01021947562c5f17:/libguile/__scm.h diff --git a/libguile/__scm.h b/libguile/__scm.h index 5581c8a4b..c6cbe3fcb 100644 --- a/libguile/__scm.h +++ b/libguile/__scm.h @@ -3,46 +3,23 @@ #ifndef SCM___SCM_H #define SCM___SCM_H -/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA - * - * As a special exception, the Free Software Foundation gives permission - * for additional uses of the text contained in its release of GUILE. - * - * The exception is that, if you link the GUILE library with other files - * to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the GUILE library code into it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by the - * Free Software Foundation under the name GUILE. If you copy - * code from other Free Software Foundation releases into a copy of - * GUILE, as the General Public License permits, the exception does - * not apply to the code that you add in this way. To avoid misleading - * anyone as to the status of such modified files, you must delete - * this exception notice from them. - * - * If you write modifications of your own for GUILE, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. */ + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ @@ -109,6 +86,47 @@ #endif +/* The SCM_EXPECT macros provide branch prediction hints to the compiler. To + * use only in places where the result of the expression under "normal" + * circumstances is known. */ +#if defined(__GNUC__) && (__GNUC__ >= 3) +# define SCM_EXPECT __builtin_expect +#else +# define SCM_EXPECT(_expr, _value) (_expr) +#endif + +#define SCM_LIKELY(_expr) SCM_EXPECT ((_expr), 1) +#define SCM_UNLIKELY(_expr) SCM_EXPECT ((_expr), 0) + +/* The SCM_INTERNAL macro makes it possible to explicitly declare a function + * as having "internal" linkage. However our current tack on this problem is + * to use GCC 4's -fvisibility=hidden, making functions internal by default, + * and then SCM_API marks them for export. */ +#define SCM_INTERNAL extern + +/* The SCM_DEPRECATED macro is used in declarations of deprecated functions + * or variables. Defining `SCM_BUILDING_DEPRECATED_CODE' allows deprecated + * functions to be implemented in terms of deprecated functions, and allows + * deprecated functions to be referred to by `scm_c_define_gsubr ()'. */ +#if !defined (SCM_BUILDING_DEPRECATED_CODE) \ + && defined (__GNUC__) && (__GNUC__ >= 3) +# define SCM_DEPRECATED SCM_API __attribute__ ((__deprecated__)) +#else +# define SCM_DEPRECATED SCM_API +#endif + +/* The SCM_ALIGNED macro, when defined, can be used to instruct the compiler + * to honor the given alignment constraint. */ +#if defined __GNUC__ +# define SCM_ALIGNED(x) __attribute__ ((aligned (x))) +#elif defined __INTEL_COMPILER +# define SCM_ALIGNED(x) __declspec (align (x)) +#else +/* Don't know how to align things. */ +# undef SCM_ALIGNED +#endif + + /* {Supported Options} * * These may be defined or undefined. @@ -141,8 +159,6 @@ */ -#define CCLO - /* Guile Scheme supports the #f/() distinction; Guile Lisp won't. We have horrible plans for their unification. */ #undef SICP @@ -157,13 +173,14 @@ /* SCM_API is a macro prepended to all function and data definitions - which should be exported or imported in the resulting dynamic link - library (DLL) in the Win32 port. */ - -#if defined (SCM_IMPORT) -# define SCM_API __declspec (dllimport) extern -#elif defined (SCM_EXPORT) || defined (DLL_EXPORT) -# define SCM_API __declspec (dllexport) extern + which should be exported from libguile. */ + +#if defined BUILDING_LIBGUILE && defined HAVE_VISIBILITY +# define SCM_API extern __attribute__((__visibility__("default"))) +#elif defined BUILDING_LIBGUILE && defined _MSC_VER +# define SCM_API __declspec(dllexport) extern +#elif defined _MSC_VER +# define SCM_API __declspec(dllimport) extern #else # define SCM_API extern #endif @@ -198,6 +215,14 @@ #define SCM_DEBUG 0 #endif +/* For debugging purposes: define this is to ensure nobody is using + * the mark bits outside of the marking phase. This is meant for + * debugging purposes only. + */ +#ifndef SCM_DEBUG_MARKING_API +#define SCM_DEBUG_MARKING_API 0 +#endif + /* If SCM_DEBUG_CELL_ACCESSES is set to 1, cell accesses will perform * exhaustive parameter checking: It will be verified that cell parameters * actually point to a valid heap cell. Note: If this option is enabled, @@ -412,10 +437,35 @@ # define setjmp setjump # define longjmp longjump # else /* ndef _CRAY1 */ -# include +# if defined (__ia64__) +/* For IA64, emulate the setjmp API using getcontext. */ +# include +# include + typedef struct { + ucontext_t ctx; + int fresh; + } scm_i_jmp_buf; +# define SCM_I_SETJMP(JB) \ + ( (JB).fresh = 1, \ + getcontext (&((JB).ctx)), \ + ((JB).fresh ? ((JB).fresh = 0, 0) : 1) ) +# define SCM_I_LONGJMP(JB,VAL) scm_ia64_longjmp (&(JB), VAL) + void scm_ia64_longjmp (scm_i_jmp_buf *, int); +# else /* ndef __ia64__ */ +# include +# endif /* ndef __ia64__ */ # endif /* ndef _CRAY1 */ #endif /* ndef vms */ +/* For any platform where SCM_I_SETJMP hasn't been defined in some + special way above, map SCM_I_SETJMP, SCM_I_LONGJMP and + scm_i_jmp_buf to setjmp, longjmp and jmp_buf. */ +#ifndef SCM_I_SETJMP +#define scm_i_jmp_buf jmp_buf +#define SCM_I_SETJMP setjmp +#define SCM_I_LONGJMP longjmp +#endif + /* James Clark came up with this neat one instruction fix for * continuations on the SPARC. It flushes the register windows so * that all the state of the process is contained in the stack. @@ -452,11 +502,24 @@ typedef long SCM_STACKITEM; #define SCM_STACK_PTR(ptr) ((SCM_STACKITEM *) (void *) (ptr)) -#define SCM_ASYNC_TICK /*fixme* should change names */ \ -do { \ - if (scm_root->pending_asyncs) \ - scm_async_click (); \ -} while (0) +SCM_API void scm_async_tick (void); + +#ifdef BUILDING_LIBGUILE + +/* FIXME: should change names */ +# define SCM_ASYNC_TICK \ + do \ + { \ + if (SCM_I_CURRENT_THREAD->pending_asyncs) \ + scm_async_click (); \ + } \ + while (0) + +#else /* !BUILDING_LIBGUILE */ + +# define SCM_ASYNC_TICK (scm_async_tick ()) + +#endif /* !BUILDING_LIBGUILE */ /* Anthony Green writes: @@ -482,14 +545,6 @@ do { \ #define SCM_FENCE #endif -#define SCM_DEFER_INTS scm_rec_mutex_lock (&scm_i_defer_mutex); - -#define SCM_ALLOW_INTS scm_rec_mutex_unlock (&scm_i_defer_mutex); - -#define SCM_REDEFER_INTS SCM_DEFER_INTS - -#define SCM_REALLOW_INTS SCM_ALLOW_INTS - #define SCM_TICK \ do { \ SCM_ASYNC_TICK; \ @@ -498,41 +553,6 @@ do { \ -/* Note: The following needs updating. */ - -/* Classification of critical sections - * - * When Guile moves to POSIX threads, it won't be possible to prevent - * context switching. In fact, the whole idea of context switching is - * bogus if threads are run by different processors. Therefore, we - * must ultimately eliminate all critical sections or enforce them by - * use of mutecis. - * - * All instances of SCM_DEFER_INTS and SCM_ALLOW_INTS should therefore - * be classified and replaced by one of the delimiters below. If you - * understand what this is all about, I'd like to encourage you to - * help with this task. The set of classes below must of course be - * incrementally augmented. - * - * MDJ 980419 - */ - -/* A sections - * - * Allocation of a cell with type tag in the CAR. - * - * With POSIX threads, each thread will have a private pool of free - * cells. Therefore, this type of section can be removed. But! It - * is important that the CDR is initialized first (with the CAR still - * indicating a free cell) so that we can guarantee a consistent heap - * at all times. - */ - -#define SCM_ENTER_A_SECTION SCM_CRITICAL_SECTION_START -#define SCM_EXIT_A_SECTION SCM_CRITICAL_SECTION_END - - - /** SCM_ASSERT ** **/ @@ -543,14 +563,14 @@ do { \ #define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg) #define SCM_ASRTGO(_cond, _label) #else -#define SCM_ASSERT(_cond, _arg, _pos, _subr) \ - do { if (!(_cond)) \ +#define SCM_ASSERT(_cond, _arg, _pos, _subr) \ + do { if (SCM_UNLIKELY (!(_cond))) \ scm_wrong_type_arg (_subr, _pos, _arg); } while (0) -#define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg) \ - do { if (!(_cond)) \ +#define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg) \ + do { if (SCM_UNLIKELY (!(_cond))) \ scm_wrong_type_arg_msg(_subr, _pos, _arg, _msg); } while (0) -#define SCM_ASRTGO(_cond, _label) \ - do { if (!(_cond)) \ +#define SCM_ASRTGO(_cond, _label) \ + do { if (SCM_UNLIKELY (!(_cond))) \ goto _label; } while (0) #endif @@ -569,8 +589,9 @@ SCM_API SCM scm_call_generic_0 (SCM gf); return (SCM_UNPACK (gf) \ ? scm_call_generic_0 ((gf)) \ : (scm_error_num_args_subr ((subr)), SCM_UNSPECIFIED)) -#define SCM_GASSERT0(cond, gf, subr) \ - if (!(cond)) SCM_WTA_DISPATCH_0((gf), (subr)) +#define SCM_GASSERT0(cond, gf, subr) \ + if (SCM_UNLIKELY(!(cond))) \ + SCM_WTA_DISPATCH_0((gf), (subr)) SCM_API SCM scm_call_generic_1 (SCM gf, SCM a1); @@ -578,8 +599,16 @@ SCM_API SCM scm_call_generic_1 (SCM gf, SCM a1); return (SCM_UNPACK (gf) \ ? scm_call_generic_1 ((gf), (a1)) \ : (scm_wrong_type_arg ((subr), (pos), (a1)), SCM_UNSPECIFIED)) -#define SCM_GASSERT1(cond, gf, a1, pos, subr) \ - if (!(cond)) SCM_WTA_DISPATCH_1((gf), (a1), (pos), (subr)) + +/* This form is for dispatching a subroutine. */ +#define SCM_WTA_DISPATCH_1_SUBR(subr, a1, pos) \ + return (SCM_UNPACK ((*SCM_SUBR_GENERIC (subr))) \ + ? scm_call_generic_1 ((*SCM_SUBR_GENERIC (subr)), (a1)) \ + : (scm_i_wrong_type_arg_symbol (SCM_SUBR_NAME (subr), (pos), (a1)), SCM_UNSPECIFIED)) + +#define SCM_GASSERT1(cond, gf, a1, pos, subr) \ + if (SCM_UNLIKELY (!(cond))) \ + SCM_WTA_DISPATCH_1((gf), (a1), (pos), (subr)) SCM_API SCM scm_call_generic_2 (SCM gf, SCM a1, SCM a2); @@ -589,8 +618,9 @@ SCM_API SCM scm_call_generic_2 (SCM gf, SCM a1, SCM a2); : (scm_wrong_type_arg ((subr), (pos), \ (pos) == SCM_ARG1 ? (a1) : (a2)), \ SCM_UNSPECIFIED)) -#define SCM_GASSERT2(cond, gf, a1, a2, pos, subr) \ - if (!(cond)) SCM_WTA_DISPATCH_2((gf), (a1), (a2), (pos), (subr)) +#define SCM_GASSERT2(cond, gf, a1, a2, pos, subr) \ + if (SCM_UNLIKELY (!(cond))) \ + SCM_WTA_DISPATCH_2((gf), (a1), (a2), (pos), (subr)) SCM_API SCM scm_apply_generic (SCM gf, SCM args); @@ -601,8 +631,9 @@ SCM_API SCM scm_apply_generic (SCM gf, SCM args); scm_list_ref ((args), \ scm_from_int ((pos) - 1))), \ SCM_UNSPECIFIED)) -#define SCM_GASSERTn(cond, gf, args, pos, subr) \ - if (!(cond)) SCM_WTA_DISPATCH_n((gf), (args), (pos), (subr)) +#define SCM_GASSERTn(cond, gf, args, pos, subr) \ + if (SCM_UNLIKELY (!(cond))) \ + SCM_WTA_DISPATCH_n((gf), (args), (pos), (subr)) #ifndef SCM_MAGIC_SNARFER /* Let these macros pass through if @@ -658,6 +689,14 @@ SCM_API SCM scm_apply_generic (SCM gf, SCM args); #define SCM_C_INLINE_KEYWORD #endif +/* Handling thread-local storage (TLS). */ + +#ifdef SCM_HAVE_THREAD_STORAGE_CLASS +# define SCM_THREAD_LOCAL __thread +#else +# define SCM_THREAD_LOCAL +#endif + #endif /* SCM___SCM_H */ /*