Threading changes.
[bpt/guile.git] / libguile / inline.h
CommitLineData
16ea9620
MV
1/* classes: h_files */
2
3#ifndef SCM_INLINE_H
4#define SCM_INLINE_H
5
d2e53ed6 6/* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
16ea9620 7 *
73be1d9e
MV
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
16ea9620 12 *
73be1d9e 13 * This library is distributed in the hope that it will be useful,
16ea9620 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
16ea9620 17 *
73be1d9e
MV
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
16ea9620
MV
22
23/* This file is for inline functions. On platforms that don't support
24 inlining functions, they are turned into ordinary functions. See
25 "inline.c".
26*/
27
60e7529a 28#include "libguile/__scm.h"
c8a1bdc4 29
1e71eafb
HWN
30#if (SCM_DEBUG_CELL_ACCESSES == 1)
31#include <stdio.h>
1e71eafb
HWN
32#endif
33
16ea9620
MV
34#include "libguile/pairs.h"
35#include "libguile/gc.h"
9bc4701c 36#include "libguile/threads.h"
9598a406 37#include "libguile/unif.h"
16ea9620 38
c8a1bdc4
HWN
39
40SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
41SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
42 scm_t_bits ccr, scm_t_bits cdr);
43
9598a406
MV
44SCM_API SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos);
45SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
16ea9620 46
60e7529a
RB
47
48#if defined SCM_C_INLINE || defined SCM_INLINE_C_INCLUDING_INLINE_H
49/* either inlining, or being included from inline.c. We use (and
50 repeat) this long #if test here and below so that we don't have to
51 introduce any extraneous symbols into the public namespace. We
52 only need SCM_C_INLINE to be seen publically . */
c8a1bdc4
HWN
53
54extern unsigned scm_newcell2_count;
55extern unsigned scm_newcell_count;
56
60e7529a
RB
57#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
58/* definitely inlining */
2b2c6fca
MV
59#ifdef __GNUC__
60extern
61#else
62static
63#endif
64SCM_C_INLINE
60e7529a 65#endif
c8a1bdc4 66SCM
228a24ef 67scm_cell (scm_t_bits car, scm_t_bits cdr)
16ea9620
MV
68{
69 SCM z;
9bc4701c 70 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist);
16ea9620 71
5e1e20c8
MV
72 if (scm_gc_running_p)
73 {
74 abort();
75 }
76
d2e53ed6 77 if (scm_is_null (*freelist))
9bc4701c 78 z = scm_gc_for_newcell (&scm_i_master_freelist, freelist);
c8a1bdc4 79 else
16ea9620 80 {
9bc4701c
MD
81 z = *freelist;
82 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620 83 }
c8a1bdc4
HWN
84
85 /*
86 We update scm_cells_allocated from this function. If we don't
87 update this explicitly, we will have to walk a freelist somewhere
88 later on, which seems a lot more expensive.
89 */
90 scm_cells_allocated += 1;
91
92#if (SCM_DEBUG_CELL_ACCESSES == 1)
93 if (scm_debug_cell_accesses_p)
1e71eafb
HWN
94 {
95 if (SCM_GC_MARK_P (z))
96 {
97 fprintf(stderr, "scm_cell tried to allocate a marked cell.\n");
98 abort();
99 }
6b69393d 100 else if (SCM_GC_CELL_WORD(z, 0) != scm_tc_free_cell)
1e71eafb
HWN
101 {
102 fprintf(stderr, "cell from freelist is not a free cell.\n");
103 abort();
104 }
105 }
106
107 /*
108 Always set mark. Otherwise cells that are alloced before
109 scm_debug_cell_accesses_p is toggled seem invalid.
110 */
111 SCM_SET_GC_MARK (z);
112
113 /*
114 TODO: figure out if this use of mark bits is valid with
115 threading. What if another thread is doing GC at this point
116 ... ?
117 */
c8a1bdc4 118
c8a1bdc4 119#endif
16ea9620 120
c8a1bdc4 121
16ea9620
MV
122 /* Initialize the type slot last so that the cell is ignored by the
123 GC until it is completely initialized. This is only relevant
124 when the GC can actually run during this code, which it can't for
125 cooperating threads, but it might be important when we get true
126 preemptive threads.
127 */
1fc8902f
DH
128 SCM_GC_SET_CELL_WORD (z, 1, cdr);
129 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 130
9bc4701c 131#if 0 /*fixme* Hmm... let's consider this later. */
60e7529a 132#if !defined(SCM_USE_COOP_THREADS) && !defined(SCM_USE_NULL_THREADS) && !defined(SCM_USE_COPT_THREADS)
389626c5 133 /* When we are using preemtive threads, we might need to make
16ea9620
MV
134 sure that the initial values for the slots are protected until
135 the cell is completely initialized.
136 */
137#error review me
138 scm_remember_upto_here_1 (SCM_PACK (cdr));
139#endif
9bc4701c 140#endif
c8a1bdc4 141
eab1b259
HWN
142#if (SCM_DEBUG_CELL_ACCESSES == 1)
143 if (scm_expensive_debug_cell_accesses_p )
144 scm_i_expensive_validation_check (z);
145#endif
c8a1bdc4 146
16ea9620
MV
147 return z;
148}
149
60e7529a
RB
150#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
151/* definitely inlining */
2b2c6fca
MV
152#ifdef __GNUC__
153extern
154#else
155static
156#endif
157SCM_C_INLINE
60e7529a 158#endif
c8a1bdc4 159SCM
228a24ef
DH
160scm_double_cell (scm_t_bits car, scm_t_bits cbr,
161 scm_t_bits ccr, scm_t_bits cdr)
16ea9620 162{
5e1e20c8
MV
163 SCM z;
164 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist2);
165
497eb0b7
HWN
166 if (scm_gc_running_p)
167 {
168 abort();
169 }
170
d2e53ed6 171 if (scm_is_null (*freelist))
9bc4701c 172 z = scm_gc_for_newcell (&scm_i_master_freelist2, freelist);
16ea9620
MV
173 else
174 {
9bc4701c
MD
175 z = *freelist;
176 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620
MV
177 }
178
c8a1bdc4
HWN
179 scm_cells_allocated += 2;
180
16ea9620
MV
181 /* Initialize the type slot last so that the cell is ignored by the
182 GC until it is completely initialized. This is only relevant
183 when the GC can actually run during this code, which it can't for
184 cooperating threads, but it might be important when we get true
185 preemptive threads.
186 */
1fc8902f
DH
187 SCM_GC_SET_CELL_WORD (z, 1, cbr);
188 SCM_GC_SET_CELL_WORD (z, 2, ccr);
189 SCM_GC_SET_CELL_WORD (z, 3, cdr);
190 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 191
9bc4701c 192#if 0 /*fixme* Hmm... let's consider this later. */
60e7529a 193#if !defined(SCM_USE_COOP_THREADS) && !defined(SCM_USE_NULL_THREADS) && !defined(SCM_USE_COPT_THREADS)
16ea9620
MV
194 /* When we are using non-cooperating threads, we might need to make
195 sure that the initial values for the slots are protected until
196 the cell is completely initialized.
197 */
198#error review me
199 scm_remember_upto_here_3 (SCM_PACK (cbr), SCM_PACK (ccr), SCM_PACK (cdr));
200#endif
9bc4701c 201#endif
16ea9620 202
16ea9620 203
c8a1bdc4
HWN
204#if (SCM_DEBUG_CELL_ACCESSES == 1)
205 if (scm_debug_cell_accesses_p)
206 {
207 if (SCM_GC_MARK_P (z))
208 {
209 fprintf(stderr,
210 "scm_double_cell tried to allocate a marked cell.\n");
211 abort();
212 }
c8a1bdc4 213 }
4ad0814a
HWN
214
215 /* see above. */
216 SCM_SET_GC_MARK (z);
217
3553e1d1
GH
218#endif
219
220 /* When this function is inlined, it's possible that the last
221 SCM_GC_SET_CELL_WORD above will be adjacent to a following
222 initialization of z. E.g., it occurred in scm_make_real. GCC
223 from around version 3 (e.g., certainly 3.2) began taking
224 advantage of strict C aliasing rules which say that it's OK to
225 interchange the initialization above and the one below when the
226 pointer types appear to differ sufficiently. We don't want that,
227 of course. GCC allows this behaviour to be disabled with the
228 -fno-strict-aliasing option, but would also need to be supplied
229 by Guile users. Instead, the following statements prevent the
230 reordering.
231 */
232#ifdef __GNUC__
233 asm volatile ("" : : : "memory");
234#else
235 /* portable version, just in case any other compiler does the same
236 thing. */
237 scm_remember_upto_here_1 (z);
c8a1bdc4 238#endif
6253f3f1 239
c8a1bdc4
HWN
240 return z;
241}
6253f3f1 242
9598a406
MV
243#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
244/* definitely inlining */
245#ifdef __GNUC__
246extern
247#else
248static
249#endif
250SCM_C_INLINE
251#endif
252SCM
253scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
254{
255 return h->ref (h, p);
256}
eab1b259 257
9598a406
MV
258#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
259/* definitely inlining */
260#ifdef __GNUC__
261extern
262#else
263static
264#endif
265SCM_C_INLINE
266#endif
267void
268scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
269{
270 h->set (h, p, v);
271}
eab1b259 272
16ea9620 273#endif
16ea9620 274#endif