Merge branch 'master' into boehm-demers-weiser-gc
authorLudovic Courtès <ludo@gnu.org>
Sat, 14 Feb 2009 16:32:46 +0000 (17:32 +0100)
committerLudovic Courtès <ludo@gnu.org>
Sat, 14 Feb 2009 16:32:46 +0000 (17:32 +0100)
Conflicts:
libguile/gc-mark.c
libguile/procs.c
libguile/procs.h
libguile/threads.c
libguile/threads.h

1  2 
libguile/goops.c
libguile/init.c
libguile/inline.h
libguile/procs.c
libguile/procs.h
libguile/threads.h

diff --combined libguile/goops.c
@@@ -1,4 -1,4 +1,4 @@@
 -/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2008
 +/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2008,2009
   * Free Software Foundation, Inc.
   *
   * This library is free software; you can redistribute it and/or
@@@ -742,8 -742,9 +742,8 @@@ SCM_DEFINE (scm_sys_inherit_magic_x, "%
        ls = SCM_CDR (ls);
      }
    flags &= SCM_CLASSF_INHERIT;
 -  if (flags & SCM_CLASSF_ENTITY)
 -    SCM_SET_CLASS_DESTRUCTOR (class, scm_struct_free_entity);
 -  else
 +
 +  if (! (flags & SCM_CLASSF_ENTITY))
      {
        long n = SCM_I_INUM (SCM_SLOT (class, scm_si_nfields));
  #if 0
        {
          /* NOTE: The following depends on scm_struct_i_size. */
          flags |= SCM_STRUCTF_LIGHT + n * sizeof (SCM); /* use light representation */
 -        SCM_SET_CLASS_DESTRUCTOR (class, scm_struct_free_light);
        }
      }
    SCM_SET_CLASS_FLAGS (class, flags);
@@@ -1884,11 -1886,6 +1884,11 @@@ typedef struct t_extension 
    SCM extension;
  } t_extension;
  
 +
 +/* Hint for `scm_gc_malloc ()' et al. when allocating `t_extension'
 +   objects.  */
 +static const char extension_gc_hint[] = "GOOPS extension";
 +
  static t_extension *extensions = 0;
  
  SCM_VARIABLE (scm_var_make_extended_generic, "make-extended-generic");
@@@ -1905,12 -1902,11 +1905,12 @@@ scm_c_extend_primitive_generic (SCM ext
        gext = scm_call_2 (SCM_VARIABLE_REF (scm_var_make_extended_generic),
                         gf,
                         SCM_SNAME (extension));
-       *SCM_SUBR_GENERIC (extension) = gext;
+       SCM_SET_SUBR_GENERIC (extension, gext);
      }
    else
      {
 -      t_extension *e = scm_malloc (sizeof (t_extension));
 +      t_extension *e = scm_gc_malloc (sizeof (t_extension),
 +                                    extension_gc_hint);
        t_extension **loc = &extensions;
        /* Make sure that extensions are placed before their own
         * extensions in the extensions list.  O(N^2) algorithm, but
@@@ -1933,6 -1929,7 +1933,6 @@@ setup_extended_primitive_generics (
        t_extension *e = extensions;
        scm_c_extend_primitive_generic (e->extended, e->extension);
        extensions = e->next;
 -      free (e);
      }
  }
  
@@@ -2822,6 -2819,7 +2822,6 @@@ scm_make_class (SCM meta, char *s_name
      }
    else if (size > 0)
      {
 -      SCM_SET_CLASS_DESTRUCTOR (class, scm_struct_free_light);
        SCM_SET_CLASS_INSTANCE_SIZE (class, size);
      }
  
diff --combined libguile/init.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation, Inc.
   * 
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
@@@ -433,9 -433,7 +433,9 @@@ scm_i_init_guile (SCM_STACKITEM *base
    scm_ports_prehistory ();
    scm_smob_prehistory ();
    scm_fluids_prehistory ();
 -  scm_hashtab_prehistory ();  /* requires storage_prehistory */
 +  scm_weaks_prehistory ();
 +  scm_hashtab_prehistory ();  /* requires storage_prehistory, and
 +                                 weaks_prehistory */
  #ifdef GUILE_DEBUG_MALLOC
    scm_debug_malloc_prehistory ();
  #endif
    
    scm_struct_prehistory ();     /* requires storage */
    scm_symbols_prehistory ();      /* requires storage */
-   scm_init_subr_table ();
  #if 0
    scm_environments_prehistory (); /* requires storage */
  #endif
diff --combined libguile/inline.h
@@@ -54,7 -54,7 +54,7 @@@
     C99 mode and doesn't define `__GNUC_STDC_INLINE__'.  Fall back to "static
     inline" in that case.  */
  
- # if (defined __GNUC__) && (!(__APPLE_CC__ > 5400 && __STDC_VERSION__ >= 199901L))
+ # if (defined __GNUC__) && (!(((defined __APPLE_CC__) && (__APPLE_CC__ > 5400)) && __STDC_VERSION__ >= 199901L))
  #  define SCM_C_USE_EXTERN_INLINE 1
  #  if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2)
  #   define SCM_C_EXTERN_INLINE                                        \
     "inline.c", when `inline' is not supported at all or when "extern inline"
     is used.  */
  
 +#include "libguile/boehm-gc.h"
 +
 +
  SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
 +SCM_API SCM scm_immutable_cell (scm_t_bits car, scm_t_bits cdr);
  SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
                             scm_t_bits ccr, scm_t_bits cdr);
 +SCM_API SCM scm_immutable_double_cell (scm_t_bits car, scm_t_bits cbr,
 +                                     scm_t_bits ccr, scm_t_bits cdr);
  
  SCM_API SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos);
  SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
@@@ -111,82 -105,64 +111,82 @@@ extern unsigned scm_newcell_count
  #ifndef SCM_INLINE_C_INCLUDING_INLINE_H
  SCM_C_EXTERN_INLINE
  #endif
 +
  SCM
  scm_cell (scm_t_bits car, scm_t_bits cdr)
  {
 -  SCM z;
 -  SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist);
 -
 -  if (scm_is_null (*freelist))
 -    z = scm_gc_for_newcell (&scm_i_master_freelist, freelist);
 -  else
 -    {
 -      z = *freelist;
 -      *freelist = SCM_FREE_CELL_CDR (*freelist);
 -    }
 -
 -#if (SCM_DEBUG_CELL_ACCESSES == 1)
 -    if (scm_debug_cell_accesses_p)
 -      {
 -      if (SCM_GC_MARK_P (z))
 -        {
 -          fprintf(stderr, "scm_cell tried to allocate a marked cell.\n");
 -          abort();
 -        }
 -      else if (SCM_GC_CELL_WORD(z, 0) != scm_tc_free_cell)
 -        {
 -          fprintf(stderr, "cell from freelist is not a free cell.\n");
 -          abort();
 -        }
 -      }
 -
 -#if (SCM_DEBUG_MARKING_API == 0)
 -    /*
 -      Always set mark. Otherwise cells that are alloced before
 -      scm_debug_cell_accesses_p is toggled seem invalid.
 -    */
 -    SCM_SET_GC_MARK (z);
 -#endif /* SCM_DEBUG_MARKING_API */
 -    
 -    /*
 -      TODO: figure out if this use of mark bits is valid with
 -      threading. What if another thread is doing GC at this point
 -      ... ?
 -     */
 +  SCM cell = SCM_PACK ((scm_t_bits) (GC_MALLOC (sizeof (scm_t_cell))));
 +
 +  /* Initialize the type slot last so that the cell is ignored by the GC
 +     until it is completely initialized.  This is only relevant when the GC
 +     can actually run during this code, which it can't since the GC only runs
 +     when all other threads are stopped.  */
 +  SCM_GC_SET_CELL_WORD (cell, 1, cdr);
 +  SCM_GC_SET_CELL_WORD (cell, 0, car);
 +
 +  return cell;
 +}
 +
 +#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
 +SCM_C_EXTERN_INLINE
  #endif
 +SCM
 +scm_immutable_cell (scm_t_bits car, scm_t_bits cdr)
 +{
 +  SCM cell = SCM_PACK ((scm_t_bits) (GC_MALLOC_STUBBORN (sizeof (scm_t_cell))));
 +
 +  /* Initialize the type slot last so that the cell is ignored by the GC
 +     until it is completely initialized.  This is only relevant when the GC
 +     can actually run during this code, which it can't since the GC only runs
 +     when all other threads are stopped.  */
 +  SCM_GC_SET_CELL_WORD (cell, 1, cdr);
 +  SCM_GC_SET_CELL_WORD (cell, 0, car);
 +
 +  GC_END_STUBBORN_CHANGE ((void *) cell);
  
 -  
 +  return cell;
 +}
 +
 +#ifndef SCM_INLINE_C_INCLUDING_INLINE_H
 +SCM_C_EXTERN_INLINE
 +#endif
 +SCM
 +scm_double_cell (scm_t_bits car, scm_t_bits cbr,
 +               scm_t_bits ccr, scm_t_bits cdr)
 +{
 +  SCM z;
 +
 +  z = SCM_PACK ((scm_t_bits) (GC_MALLOC (2 * sizeof (scm_t_cell))));
    /* Initialize the type slot last so that the cell is ignored by the
       GC until it is completely initialized.  This is only relevant
       when the GC can actually run during this code, which it can't
       since the GC only runs when all other threads are stopped.
    */
 -  SCM_GC_SET_CELL_WORD (z, 1, cdr);
 +  SCM_GC_SET_CELL_WORD (z, 1, cbr);
 +  SCM_GC_SET_CELL_WORD (z, 2, ccr);
 +  SCM_GC_SET_CELL_WORD (z, 3, cdr);
    SCM_GC_SET_CELL_WORD (z, 0, car);
  
 -#if (SCM_DEBUG_CELL_ACCESSES == 1)
 -  if (scm_expensive_debug_cell_accesses_p )
 -    scm_i_expensive_validation_check (z);
 +  /* When this function is inlined, it's possible that the last
 +     SCM_GC_SET_CELL_WORD above will be adjacent to a following
 +     initialization of z.  E.g., it occurred in scm_make_real.  GCC
 +     from around version 3 (e.g., certainly 3.2) began taking
 +     advantage of strict C aliasing rules which say that it's OK to
 +     interchange the initialization above and the one below when the
 +     pointer types appear to differ sufficiently.  We don't want that,
 +     of course.  GCC allows this behaviour to be disabled with the
 +     -fno-strict-aliasing option, but would also need to be supplied
 +     by Guile users.  Instead, the following statements prevent the
 +     reordering.
 +   */
 +#ifdef __GNUC__
 +  __asm__ volatile ("" : : : "memory");
 +#else
 +  /* portable version, just in case any other compiler does the same
 +     thing.  */
 +  scm_remember_upto_here_1 (z);
  #endif
 -  
 +
    return z;
  }
  
  SCM_C_EXTERN_INLINE
  #endif
  SCM
 -scm_double_cell (scm_t_bits car, scm_t_bits cbr,
 -               scm_t_bits ccr, scm_t_bits cdr)
 +scm_immutable_double_cell (scm_t_bits car, scm_t_bits cbr,
 +                         scm_t_bits ccr, scm_t_bits cdr)
  {
    SCM z;
 -  SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist2);
 -
 -  if (scm_is_null (*freelist))
 -    z = scm_gc_for_newcell (&scm_i_master_freelist2, freelist);
 -  else
 -    {
 -      z = *freelist;
 -      *freelist = SCM_FREE_CELL_CDR (*freelist);
 -    }
  
 +  z = SCM_PACK ((scm_t_bits) (GC_MALLOC_STUBBORN (2 * sizeof (scm_t_cell))));
    /* Initialize the type slot last so that the cell is ignored by the
       GC until it is completely initialized.  This is only relevant
       when the GC can actually run during this code, which it can't
    SCM_GC_SET_CELL_WORD (z, 3, cdr);
    SCM_GC_SET_CELL_WORD (z, 0, car);
  
 -#if (SCM_DEBUG_CELL_ACCESSES == 1)
 -  if (scm_debug_cell_accesses_p)
 -    {
 -      if (SCM_GC_MARK_P (z))
 -      {
 -        fprintf(stderr,
 -                "scm_double_cell tried to allocate a marked cell.\n");
 -        abort();
 -      }
 -    }
 -#if (SCM_DEBUG_MARKING_API == 0)
 -  /* see above. */
 -  SCM_SET_GC_MARK (z);
 -#endif /* SCM_DEBUG_MARKING_API */
 -  
 -#endif
 +  GC_END_STUBBORN_CHANGE ((void *) z);
  
    /* When this function is inlined, it's possible that the last
       SCM_GC_SET_CELL_WORD above will be adjacent to a following
diff --combined libguile/procs.c
  /* {Procedures}
   */
  
- scm_t_subr_entry *scm_subr_table;
  
- /* libguile contained approx. 700 primitive procedures on 24 Aug 1999. */
- /* Increased to 800 on 2001-05-07 -- Guile now has 779 primitives on
-    startup, 786 with guile-readline.  'martin */
- static unsigned long scm_subr_table_size = 0;
- static unsigned long scm_subr_table_room = 800;
- /* Hint for `scm_gc_malloc ()' and friends.  */
- static const char subr_table_gc_hint[] = "subr table";
- SCM 
+ SCM
  scm_c_make_subr (const char *name, long type, SCM (*fcn) ())
  {
    register SCM z;
-   unsigned long entry;
+   SCM *meta_info;
  
-   if (scm_subr_table_size == scm_subr_table_room)
-     {
-       long new_size = scm_subr_table_room * 3 / 2;
-       void *new_table
-       = scm_gc_realloc (scm_subr_table,
-                         sizeof (* scm_subr_table) * scm_subr_table_room,
-                         sizeof (* scm_subr_table) * new_size,
-                         subr_table_gc_hint);
-       scm_subr_table = new_table;
-       scm_subr_table_room = new_size;
-     }
+   meta_info = scm_gc_malloc (2 * sizeof (*meta_info), "subr meta-info");
+   meta_info[0] = scm_from_locale_symbol (name);
+   meta_info[1] = SCM_EOL;  /* properties */
+   z = scm_double_cell ((scm_t_bits) type, (scm_t_bits) fcn,
+                      0 /* generic */, (scm_t_bits) meta_info);
  
-   entry = scm_subr_table_size;
-   z = scm_cell ((entry << 8) + type, (scm_t_bits) fcn);
-   scm_subr_table[entry].handle = z;
-   scm_subr_table[entry].name = scm_from_locale_symbol (name);
-   scm_subr_table[entry].generic = 0;
-   scm_subr_table[entry].properties = SCM_EOL;
-   scm_subr_table_size++;
-   
    return z;
  }
  
@@@ -83,16 -58,25 +58,16 @@@ SC
  scm_c_define_subr (const char *name, long type, SCM (*fcn) ())
  {
    SCM subr = scm_c_make_subr (name, type, fcn);
-   scm_define (SCM_SUBR_ENTRY(subr).name, subr);
+   scm_define (SCM_SNAME (subr), subr);
    return subr;
  }
  
 -/* This function isn't currently used since subrs are never freed. */
 -/* *fixme* Need mutex here. */
 -void
 -scm_free_subr_entry (SCM subr)
 -{
 -  scm_gc_free (SCM_SUBR_META_INFO (subr), 2 * sizeof (SCM),
 -             "subr meta-info");
 -}
 -
  SCM
  scm_c_make_subr_with_generic (const char *name, 
                              long type, SCM (*fcn) (), SCM *gf)
  {
    SCM subr = scm_c_make_subr (name, type, fcn);
-   SCM_SUBR_ENTRY(subr).generic = gf;
+   SCM_SET_SUBR_GENERIC_LOC (subr, gf);
    return subr;
  }
  
@@@ -101,7 -85,7 +76,7 @@@ scm_c_define_subr_with_generic (const c
                                long type, SCM (*fcn) (), SCM *gf)
  {
    SCM subr = scm_c_make_subr_with_generic (name, type, fcn, gf);
-   scm_define (SCM_SUBR_ENTRY(subr).name, subr);
+   scm_define (SCM_SNAME (subr), subr);
    return subr;
  }
  
@@@ -327,16 -311,7 +302,7 @@@ scm_setter (SCM proc
    return SCM_BOOL_F; /* not reached */
  }
  
- void
- scm_init_subr_table ()
- {
-   scm_subr_table
-     = ((scm_t_subr_entry *)
-        scm_gc_malloc (sizeof (* scm_subr_table) * scm_subr_table_room,
-                     subr_table_gc_hint));
- }
\f
  void
  scm_init_procs ()
  {
diff --combined libguile/procs.h
  /* Subrs 
   */
  
- typedef struct
- {
-   SCM handle;                 /* link back to procedure object */
-   SCM name;
-   SCM *generic;                       /* 0 if no generic support
-                                * *generic == 0 until first method
-                                */
-   SCM properties;             /* procedure properties */
- } scm_t_subr_entry;
- #define SCM_SUBRNUM(subr) (SCM_CELL_WORD_0 (subr) >> 8)
- #define SCM_SUBR_ENTRY(x) (scm_subr_table[SCM_SUBRNUM (x)])
- #define SCM_SNAME(x) (SCM_SUBR_ENTRY (x).name)
+ #define SCM_SUBR_META_INFO(x)  ((SCM *) SCM_CELL_WORD_3 (x))
+ #define SCM_SNAME(x) (SCM_SUBR_META_INFO (x) [0])
  #define SCM_SUBRF(x) ((SCM (*)()) SCM_CELL_WORD_1 (x))
 -#define SCM_SET_SUBRF(x, v) (SCM_SET_CELL_WORD_1 ((x), (v)))
  #define SCM_DSUBRF(x) ((double (*)()) SCM_CELL_WORD_1 (x))
- #define SCM_SUBR_PROPS(x) (SCM_SUBR_ENTRY (x).properties)
- #define SCM_SUBR_GENERIC(x) (SCM_SUBR_ENTRY (x).generic)
+ #define SCM_SUBR_PROPS(x) (SCM_SUBR_META_INFO (x) [1])
+ #define SCM_SUBR_GENERIC(x) ((SCM *) SCM_CELL_WORD_2 (x))
+ #define SCM_SET_SUBR_GENERIC(x, g) (*((SCM *) SCM_CELL_WORD_2 (x)) = (g))
+ #define SCM_SET_SUBR_GENERIC_LOC(x, g) (SCM_SET_CELL_WORD_2 (x, (scm_t_bits) g))
  
  #define SCM_CCLO_LENGTH(x) (SCM_CELL_WORD_0 (x) >> 8)
  #define SCM_MAKE_CCLO_TAG(v)  (((v) << 8) + scm_tc7_cclo)
  #define SCM_CLOSURE_BODY(x) SCM_CDR (SCM_CODE (x))
  #define SCM_PROCPROPS(x) SCM_CDR (SCM_CLOSCAR (x))
  #define SCM_SETPROCPROPS(x, p) SCM_SETCDR (SCM_CLOSCAR (x), p)
 -#define SCM_SETCODE(x, e) (SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (scm_cons ((e), SCM_EOL)) \
 -                           + scm_tc3_closure))
  #define SCM_ENV(x) SCM_CELL_OBJECT_1 (x)
 -#define SCM_SETENV(x, e) SCM_SET_CELL_OBJECT_1 ((x), (e))
  #define SCM_TOP_LEVEL(ENV)  (scm_is_null (ENV) || (scm_is_true (scm_procedure_p (SCM_CAR (ENV)))))
  
  /* Procedure-with-setter
  #define SCM_PROCEDURE(obj) SCM_CELL_OBJECT_1 (obj)
  #define SCM_SETTER(obj) SCM_CELL_OBJECT_2 (obj)
  
- SCM_API scm_t_subr_entry *scm_subr_table;
--
--\f
--
 -SCM_API void scm_free_subr_entry (SCM subr);
  SCM_API SCM scm_c_make_subr (const char *name, long type, SCM (*fcn)());
  SCM_API SCM scm_c_make_subr_with_generic (const char *name, long type,
                                          SCM (*fcn)(), SCM *gf);
@@@ -144,7 -139,6 +131,6 @@@ SCM_API SCM scm_procedure_with_setter_
  SCM_API SCM scm_make_procedure_with_setter (SCM procedure, SCM setter);
  SCM_API SCM scm_procedure (SCM proc);
  SCM_API SCM scm_setter (SCM proc);
- SCM_INTERNAL void scm_init_subr_table (void);
  SCM_INTERNAL void scm_init_procs (void);
  
  #ifdef GUILE_DEBUG
diff --combined libguile/threads.h
@@@ -62,18 -62,30 +62,18 @@@ typedef struct scm_i_thread 
    int canceled;
    int exited;
  
 +  /* Boolean indicating whether the thread is in guile mode.  */
 +  int guile_mode;
 +
    SCM sleep_object;
    scm_i_pthread_mutex_t *sleep_mutex;
    scm_i_pthread_cond_t sleep_cond;
    int sleep_fd, sleep_pipe[2];
  
 -  /* This mutex represents this threads right to access the heap.
 -     That right can temporarily be taken away by the GC.
 -  */
 -  scm_i_pthread_mutex_t heap_mutex;
 -
 -  /* Boolean tracking whether the above mutex is currently locked by
 -     this thread.  This is equivalent to whether or not the thread is
 -     in "Guile mode".  This field doesn't need any protection because
 -     it is only ever set or tested by the owning thread.
 -  */
 -  int heap_mutex_locked_by_self;
 -
 -  /* The freelists of this thread.  Each thread has its own lists so
 -     that they can all allocate concurrently.
 -  */
 -  SCM freelist, freelist2;
 -  int clear_freelists_p; /* set if GC was done while thread was asleep */
 -  int gc_running_p;      /* non-zero while this thread does GC or a
 -                          sweep. */
 +  /* Information about the Boehm-GC mark stack during the mark phase.  This
 +     is used by `scm_gc_mark ()'.  */
 +  void *current_mark_stack_ptr;
 +  void *current_mark_stack_limit;
  
    /* Other thread local things.
     */
@@@ -137,16 -149,26 +137,16 @@@ SCM_INTERNAL void *scm_i_with_guile_and
                                                void *data, SCM parent);
  
  
 -extern int scm_i_thread_go_to_sleep;
 -
 -SCM_INTERNAL void scm_i_thread_put_to_sleep (void);
 -SCM_INTERNAL void scm_i_thread_wake_up (void);
 -SCM_INTERNAL void scm_i_thread_invalidate_freelists (void);
 -void scm_i_thread_sleep_for_gc (void);
 +void scm_threads_prehistory (SCM_STACKITEM *);
 +void scm_threads_init_first_thread (void);
  
 -SCM_INTERNAL void scm_threads_prehistory (SCM_STACKITEM *);
 -SCM_INTERNAL void scm_threads_init_first_thread (void);
 -SCM_INTERNAL void scm_threads_mark_stacks (void);
  SCM_INTERNAL void scm_init_threads (void);
  SCM_INTERNAL void scm_init_thread_procs (void);
  SCM_INTERNAL void scm_init_threads_default_dynamic_state (void);
  
  
  #define SCM_THREAD_SWITCHING_CODE \
 -do { \
 -  if (scm_i_thread_go_to_sleep) \
 -    scm_i_thread_sleep_for_gc (); \
 -} while (0)
 +  do { } while (0)
  
  SCM_API SCM scm_call_with_new_thread (SCM thunk, SCM handler);
  SCM_API SCM scm_yield (void);
@@@ -210,7 -232,7 +210,7 @@@ SCM_API int scm_pthread_cond_wait (pthr
                                   pthread_mutex_t *mutex);
  SCM_API int scm_pthread_cond_timedwait (pthread_cond_t *cond,
                                        pthread_mutex_t *mutex,
-                                       const struct timespec *abstime);
+                                       const scm_t_timespec *abstime);
  #endif
  
  /* More convenience functions.