root/src/parameter.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Scm_ParameterTableInit
  2. Scm_MakeParameterSlot
  3. Scm_ParameterRef
  4. Scm_ParameterSet
  5. Scm__InitParameter

   1 /*
   2  * parameter.c - parameter support
   3  *
   4  *   Copyright (c) 2000-2003 Shiro Kawai, All rights reserved.
   5  * 
   6  *   Redistribution and use in source and binary forms, with or without
   7  *   modification, are permitted provided that the following conditions
   8  *   are met:
   9  * 
  10  *   1. Redistributions of source code must retain the above copyright
  11  *      notice, this list of conditions and the following disclaimer.
  12  *
  13  *   2. Redistributions in binary form must reproduce the above copyright
  14  *      notice, this list of conditions and the following disclaimer in the
  15  *      documentation and/or other materials provided with the distribution.
  16  *
  17  *   3. Neither the name of the authors nor the names of its contributors
  18  *      may be used to endorse or promote products derived from this
  19  *      software without specific prior written permission.
  20  *
  21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  *
  33  *  $Id: parameter.c,v 1.6 2004/07/15 23:16:13 shirok Exp $
  34  */
  35 
  36 #define LIBGAUCHE_BODY
  37 #include "gauche.h"
  38 #include "gauche/vm.h"
  39 
  40 /*
  41  * Parameters keep thread-local states.   When a thread is created,
  42  * it inherits the set of parameters from its creator (except the
  43  * primordial thread).
  44  * Parameters have additional features, such as guard procedure
  45  * and observer callbacks.  They are implemented in Scheme level
  46  * (see lib/gauche/parameter.scm).  C level only provides low-level
  47  * accessor and modifier methods.
  48  *
  49  * It is debatable how to implement the inheritance semantics.  MzScheme
  50  * keeps user-defined parameters in a hash table, and uses
  51  * copy-on-write mechanism to delay the copy of the table.  It is nice,
  52  * but difficult to use in preemptive threads, for it requires lock of
  53  * the table every time even in reading parameters.  Guile uses the
  54  * vector (Guile calls them fluids, but it's semantically equivalent
  55  * to parameters), and eagerly copies the vector at the creation of the
  56  * thread.  Since thread creation in Gauche is already heavy anyway,
  57  * I take Guile's approach.
  58  */
  59 
  60 #define PARAMETER_INIT_SIZE 64
  61 #define PARAMETER_GROW      16
  62 
  63 /* Every time a new parameter is created (in any thread), it is
  64  * given an unique ID in the process.  It prevents a thread from
  65  * dereferencnig a parameter created by an unrelated thread.
  66  */
  67 static int next_parameter_id = 0;
  68 ScmInternalMutex parameter_mutex;
  69 
  70 /* Init table.  For primordial thread, base == NULL.  For non-primordial
  71  * thread, base is the current thread (this must be called from the
  72  * creator thread).
  73  */
  74 void Scm_ParameterTableInit(ScmVMParameterTable *table,
  75                             ScmVM *base)
  76 {
  77     int i;
  78 
  79     if (base) {
  80         table->vector = SCM_NEW_ARRAY(ScmObj, base->parameters.numAllocated);
  81         table->ids = SCM_NEW_ATOMIC2(int*, PARAMETER_INIT_SIZE*sizeof(int));
  82         table->numAllocated = base->parameters.numAllocated;
  83         table->numParameters = base->parameters.numParameters;
  84         for (i=0; i<table->numParameters; i++) {
  85             table->vector[i] = base->parameters.vector[i];
  86             table->ids[i] = base->parameters.ids[i];
  87         }
  88     } else {
  89         table->vector = SCM_NEW_ARRAY(ScmObj, PARAMETER_INIT_SIZE);
  90         table->ids = SCM_NEW_ATOMIC2(int*, PARAMETER_INIT_SIZE*sizeof(int));
  91         table->numParameters = 0;
  92         table->numAllocated = PARAMETER_INIT_SIZE;
  93     }
  94 }
  95 
  96 /*
  97  * Allocate new parameter slot
  98  */
  99 int Scm_MakeParameterSlot(ScmVM *vm, int *newid)
 100 {
 101     ScmVMParameterTable *p = &(vm->parameters);
 102     if (p->numParameters == p->numAllocated) {
 103         int i, newsiz = p->numAllocated + PARAMETER_GROW;
 104         ScmObj *newvec = SCM_NEW_ARRAY(ScmObj, newsiz);
 105         int *newids = SCM_NEW_ATOMIC2(int*, newsiz*sizeof(int));
 106         
 107         for (i=0; i<p->numParameters; i++) {
 108             newvec[i] = p->vector[i];
 109             p->vector[i] = SCM_FALSE; /*GC friendly*/
 110             newids[i] = p->ids[i];
 111         }
 112         p->vector = newvec;
 113         p->ids = newids;
 114         p->numAllocated += PARAMETER_GROW;
 115     }
 116     p->vector[p->numParameters] = SCM_UNDEFINED;
 117     SCM_INTERNAL_MUTEX_LOCK(parameter_mutex);
 118     p->ids[p->numParameters] = *newid = next_parameter_id++;
 119     SCM_INTERNAL_MUTEX_UNLOCK(parameter_mutex);
 120     return p->numParameters++;
 121 }
 122 
 123 /*
 124  * Accessor & modifier
 125  */
 126 
 127 ScmObj Scm_ParameterRef(ScmVM *vm, int index, int id)
 128 {
 129     ScmVMParameterTable *p = &(vm->parameters);
 130     SCM_ASSERT(index >= 0);
 131     if (index >= p->numParameters || p->ids[index] != id) {
 132         Scm_Error("the thread %S doesn't have parameter (%d:%d)",
 133                   vm, index, id);
 134     }
 135     SCM_ASSERT(p->vector[index] != NULL);
 136     return p->vector[index];
 137 }
 138 
 139 ScmObj Scm_ParameterSet(ScmVM *vm, int index, int id, ScmObj value)
 140 {
 141     ScmVMParameterTable *p = &(vm->parameters);
 142     SCM_ASSERT(index >= 0);
 143     if (index >= p->numParameters || p->ids[index] != id) {
 144         Scm_Error("the thread %S doesn't have parameter (%d:%d)",
 145                   vm, index, id);
 146     }
 147     p->vector[index] = value;
 148     return value;
 149 }
 150 
 151 /*
 152  * Initialization
 153  */
 154 void Scm__InitParameter(void)
 155 {
 156     SCM_INTERNAL_MUTEX_INIT(parameter_mutex);
 157 }

/* [<][>][^][v][top][bottom][index][help] */