File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / sljit / sljitUtils.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:50:25 2012 UTC (12 years, 5 months ago) by misho
Branches: pcre, MAIN
CVS tags: v8_30, HEAD
pcre

    1: /*
    2:  *    Stack-less Just-In-Time compiler
    3:  *
    4:  *    Copyright 2009-2012 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>