1 /* Part of SWI-Prolog
2
3 Author: Jan Wielemaker
4 E-mail: J.Wielemaker@vu.nl
5 WWW: http://www.swi-prolog.org
6 Copyright (c) 2011-2013, University of Amsterdam
7 VU University Amsterdam
8 All rights reserved.
9
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
13
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in
19 the documentation and/or other materials provided with the
20 distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #ifndef BUFFER_H_INCLUDED
37 #define BUFFER_H_INCLUDED
38
39 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
40 Triples are buffered in an array. This is used by transactions for
41 committing, etc. The data is allocated using PL_malloc_uncollectable()
42 to make sure that discarded triples are not really removed by GC,
43 notably before their changes can be broadcasted.
44
45 FIXME: Check that all triple buffers are allocated either on the stack
46 or in memory that is scanned by BDWGC. The ones for transactions are
47 stored on the C-stack.
48 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49
50 #define TFAST_SIZE 64
51
52 typedef struct triple_buffer
53 { triple **base;
54 triple **top;
55 triple **max;
56 triple *fast[TFAST_SIZE];
57 } triple_buffer;
58
59
60 static inline void
init_triple_buffer(triple_buffer * b)61 init_triple_buffer(triple_buffer *b)
62 { b->base = b->top = b->fast;
63 b->max = b->top + TFAST_SIZE;
64 }
65
66
67 static inline int
is_empty_buffer(triple_buffer * b)68 is_empty_buffer(triple_buffer *b)
69 { return b->top == b->base;
70 }
71
72
73 static inline int
buffer_triple(triple_buffer * b,triple * t)74 buffer_triple(triple_buffer *b, triple *t)
75 { if ( b->top < b->max )
76 { *b->top++ = t;
77 } else
78 { if ( b->base == b->fast )
79 { triple **tmp = PL_malloc_uncollectable(TFAST_SIZE*2*sizeof(triple*));
80
81 if ( tmp )
82 { memcpy(tmp, b->base, (char*)b->top - (char*)b->base);
83 b->base = tmp;
84 b->max = b->base + TFAST_SIZE*2;
85 b->top = b->base + TFAST_SIZE;
86 *b->top++ = t;
87 } else
88 return FALSE;
89 } else
90 { size_t size = (b->max - b->base);
91 triple **tmp = PL_malloc_uncollectable(size*2*sizeof(triple*));
92
93 assert(b->top == b->max);
94
95 if ( tmp )
96 { memcpy(tmp, b->base, (char*)b->top - (char*)b->base);
97 PL_free(b->base);
98 b->base = tmp;
99 b->top = b->base + size;
100 b->max = b->base + size*2;
101 *b->top++ = t;
102 } else
103 return FALSE;
104 }
105 }
106
107 return TRUE;
108 }
109
110
111 static inline void
free_triple_buffer(triple_buffer * b)112 free_triple_buffer(triple_buffer *b)
113 { if ( b->base && b->base != b->fast )
114 PL_free(b->base);
115 }
116
117 #endif /*BUFFER_H_INCLUDED*/
118