Annotation of embedaddon/pcre/sljit/sljitUtils.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Stack-less Just-In-Time compiler
3: *
4: * Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without modification, are
7: * permitted provided that the following conditions are met:
8: *
9: * 1. Redistributions of source code must retain the above copyright notice, this list of
10: * conditions and the following disclaimer.
11: *
12: * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13: * of conditions and the following disclaimer in the documentation and/or other materials
14: * provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19: * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22: * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: /* ------------------------------------------------------------------------ */
28: /* Locks */
29: /* ------------------------------------------------------------------------ */
30:
31: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
32:
33: #ifdef _WIN32
34:
35: #include "windows.h"
36:
37: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
38:
39: static HANDLE allocator_mutex = 0;
40:
41: static SLJIT_INLINE void allocator_grab_lock(void)
42: {
43: /* No idea what to do if an error occures. Static mutexes should never fail... */
44: if (!allocator_mutex)
45: allocator_mutex = CreateMutex(NULL, TRUE, NULL);
46: else
47: WaitForSingleObject(allocator_mutex, INFINITE);
48: }
49:
50: static SLJIT_INLINE void allocator_release_lock(void)
51: {
52: ReleaseMutex(allocator_mutex);
53: }
54:
55: #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
56:
57: #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
58:
59: static HANDLE global_mutex = 0;
60:
61: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
62: {
63: /* No idea what to do if an error occures. Static mutexes should never fail... */
64: if (!global_mutex)
65: global_mutex = CreateMutex(NULL, TRUE, NULL);
66: else
67: WaitForSingleObject(global_mutex, INFINITE);
68: }
69:
70: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
71: {
72: ReleaseMutex(global_mutex);
73: }
74:
75: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
76:
77: #else /* _WIN32 */
78:
79: #include "pthread.h"
80:
81: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
82:
83: static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
84:
85: static SLJIT_INLINE void allocator_grab_lock(void)
86: {
87: pthread_mutex_lock(&allocator_mutex);
88: }
89:
90: static SLJIT_INLINE void allocator_release_lock(void)
91: {
92: pthread_mutex_unlock(&allocator_mutex);
93: }
94:
95: #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
96:
97: #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
98:
99: static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
100:
101: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
102: {
103: pthread_mutex_lock(&global_mutex);
104: }
105:
106: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
107: {
108: pthread_mutex_unlock(&global_mutex);
109: }
110:
111: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
112:
113: #endif /* _WIN32 */
114:
115: /* ------------------------------------------------------------------------ */
116: /* Stack */
117: /* ------------------------------------------------------------------------ */
118:
119: #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
120:
121: #ifdef _WIN32
122: #include "windows.h"
123: #else
124: #include <sys/mman.h>
125: #include <unistd.h>
126: #endif
127:
128: /* Planning to make it even more clever in the future. */
129: static sljit_w sljit_page_align = 0;
130:
131: SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
132: {
133: struct sljit_stack *stack;
134: union {
135: void *ptr;
136: sljit_uw uw;
137: } base;
138: #ifdef _WIN32
139: SYSTEM_INFO si;
140: #endif
141:
142: if (limit > max_limit || limit < 1)
143: return NULL;
144:
145: #ifdef _WIN32
146: if (!sljit_page_align) {
147: GetSystemInfo(&si);
148: sljit_page_align = si.dwPageSize - 1;
149: }
150: #else
151: if (!sljit_page_align) {
152: sljit_page_align = sysconf(_SC_PAGESIZE);
153: /* Should never happen. */
154: if (sljit_page_align < 0)
155: sljit_page_align = 4096;
156: sljit_page_align--;
157: }
158: #endif
159:
160: /* Align limit and max_limit. */
161: max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
162:
163: stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
164: if (!stack)
165: return NULL;
166:
167: #ifdef _WIN32
168: base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
169: if (!base.ptr) {
170: SLJIT_FREE(stack);
171: return NULL;
172: }
173: stack->base = base.uw;
174: stack->limit = stack->base;
175: stack->max_limit = stack->base + max_limit;
176: if (sljit_stack_resize(stack, stack->base + limit)) {
177: sljit_free_stack(stack);
178: return NULL;
179: }
180: #else
181: base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
182: if (base.ptr == MAP_FAILED) {
183: SLJIT_FREE(stack);
184: return NULL;
185: }
186: stack->base = base.uw;
187: stack->limit = stack->base + limit;
188: stack->max_limit = stack->base + max_limit;
189: #endif
190: stack->top = stack->base;
191: return stack;
192: }
193:
194: #undef PAGE_ALIGN
195:
196: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
197: {
198: #ifdef _WIN32
199: VirtualFree((void*)stack->base, 0, MEM_RELEASE);
200: #else
201: munmap((void*)stack->base, stack->max_limit - stack->base);
202: #endif
203: SLJIT_FREE(stack);
204: }
205:
206: SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
207: {
208: sljit_uw aligned_old_limit;
209: sljit_uw aligned_new_limit;
210:
211: if ((new_limit > stack->max_limit) || (new_limit < stack->base))
212: return -1;
213: #ifdef _WIN32
214: aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
215: aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
216: if (aligned_new_limit != aligned_old_limit) {
217: if (aligned_new_limit > aligned_old_limit) {
218: if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
219: return -1;
220: }
221: else {
222: if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
223: return -1;
224: }
225: }
226: stack->limit = new_limit;
227: return 0;
228: #else
229: if (new_limit >= stack->limit) {
230: stack->limit = new_limit;
231: return 0;
232: }
233: aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
234: aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
235: if (aligned_new_limit < aligned_old_limit)
236: madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
237: stack->limit = new_limit;
238: return 0;
239: #endif
240: }
241:
242: #endif /* SLJIT_UTIL_STACK */
243:
244: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>