Annotation of embedaddon/pcre/sljit/sljitUtils.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:  *    Stack-less Just-In-Time compiler
                      3:  *
1.1.1.2   misho       4:  *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
1.1       misho       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: 
1.1.1.3 ! misho      33: #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
        !            34: 
        !            35: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
        !            36: 
        !            37: static SLJIT_INLINE void allocator_grab_lock(void)
        !            38: {
        !            39:        /* Always successful. */
        !            40: }
        !            41: 
        !            42: static SLJIT_INLINE void allocator_release_lock(void)
        !            43: {
        !            44:        /* Always successful. */
        !            45: }
        !            46: 
        !            47: #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
        !            48: 
        !            49: #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
        !            50: 
        !            51: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
        !            52: {
        !            53:        /* Always successful. */
        !            54: }
        !            55: 
        !            56: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
        !            57: {
        !            58:        /* Always successful. */
        !            59: }
        !            60: 
        !            61: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
        !            62: 
        !            63: #elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */
1.1       misho      64: 
                     65: #include "windows.h"
                     66: 
                     67: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
                     68: 
                     69: static HANDLE allocator_mutex = 0;
                     70: 
                     71: static SLJIT_INLINE void allocator_grab_lock(void)
                     72: {
                     73:        /* No idea what to do if an error occures. Static mutexes should never fail... */
                     74:        if (!allocator_mutex)
                     75:                allocator_mutex = CreateMutex(NULL, TRUE, NULL);
                     76:        else
                     77:                WaitForSingleObject(allocator_mutex, INFINITE);
                     78: }
                     79: 
                     80: static SLJIT_INLINE void allocator_release_lock(void)
                     81: {
                     82:        ReleaseMutex(allocator_mutex);
                     83: }
                     84: 
                     85: #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
                     86: 
                     87: #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
                     88: 
                     89: static HANDLE global_mutex = 0;
                     90: 
                     91: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
                     92: {
                     93:        /* No idea what to do if an error occures. Static mutexes should never fail... */
                     94:        if (!global_mutex)
                     95:                global_mutex = CreateMutex(NULL, TRUE, NULL);
                     96:        else
                     97:                WaitForSingleObject(global_mutex, INFINITE);
                     98: }
                     99: 
                    100: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
                    101: {
                    102:        ReleaseMutex(global_mutex);
                    103: }
                    104: 
                    105: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
                    106: 
                    107: #else /* _WIN32 */
                    108: 
                    109: #include "pthread.h"
                    110: 
                    111: #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
                    112: 
                    113: static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
                    114: 
                    115: static SLJIT_INLINE void allocator_grab_lock(void)
                    116: {
                    117:        pthread_mutex_lock(&allocator_mutex);
                    118: }
                    119: 
                    120: static SLJIT_INLINE void allocator_release_lock(void)
                    121: {
                    122:        pthread_mutex_unlock(&allocator_mutex);
                    123: }
                    124: 
                    125: #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
                    126: 
                    127: #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
                    128: 
                    129: static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
                    130: 
                    131: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
                    132: {
                    133:        pthread_mutex_lock(&global_mutex);
                    134: }
                    135: 
                    136: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
                    137: {
                    138:        pthread_mutex_unlock(&global_mutex);
                    139: }
                    140: 
                    141: #endif /* SLJIT_UTIL_GLOBAL_LOCK */
                    142: 
                    143: #endif /* _WIN32 */
                    144: 
                    145: /* ------------------------------------------------------------------------ */
                    146: /*  Stack                                                                   */
                    147: /* ------------------------------------------------------------------------ */
                    148: 
                    149: #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
                    150: 
                    151: #ifdef _WIN32
                    152: #include "windows.h"
                    153: #else
                    154: #include <sys/mman.h>
                    155: #include <unistd.h>
                    156: #endif
                    157: 
                    158: /* Planning to make it even more clever in the future. */
                    159: static sljit_w sljit_page_align = 0;
                    160: 
                    161: SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
                    162: {
                    163:        struct sljit_stack *stack;
                    164:        union {
                    165:                void *ptr;
                    166:                sljit_uw uw;
                    167:        } base;
                    168: #ifdef _WIN32
                    169:        SYSTEM_INFO si;
                    170: #endif
                    171: 
                    172:        if (limit > max_limit || limit < 1)
                    173:                return NULL;
                    174: 
                    175: #ifdef _WIN32
                    176:        if (!sljit_page_align) {
                    177:                GetSystemInfo(&si);
                    178:                sljit_page_align = si.dwPageSize - 1;
                    179:        }
                    180: #else
                    181:        if (!sljit_page_align) {
                    182:                sljit_page_align = sysconf(_SC_PAGESIZE);
                    183:                /* Should never happen. */
                    184:                if (sljit_page_align < 0)
                    185:                        sljit_page_align = 4096;
                    186:                sljit_page_align--;
                    187:        }
                    188: #endif
                    189: 
                    190:        /* Align limit and max_limit. */
                    191:        max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
                    192: 
                    193:        stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
                    194:        if (!stack)
                    195:                return NULL;
                    196: 
                    197: #ifdef _WIN32
                    198:        base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
                    199:        if (!base.ptr) {
                    200:                SLJIT_FREE(stack);
                    201:                return NULL;
                    202:        }
                    203:        stack->base = base.uw;
                    204:        stack->limit = stack->base;
                    205:        stack->max_limit = stack->base + max_limit;
                    206:        if (sljit_stack_resize(stack, stack->base + limit)) {
                    207:                sljit_free_stack(stack);
                    208:                return NULL;
                    209:        }
                    210: #else
                    211:        base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
                    212:        if (base.ptr == MAP_FAILED) {
                    213:                SLJIT_FREE(stack);
                    214:                return NULL;
                    215:        }
                    216:        stack->base = base.uw;
                    217:        stack->limit = stack->base + limit;
                    218:        stack->max_limit = stack->base + max_limit;
                    219: #endif
                    220:        stack->top = stack->base;
                    221:        return stack;
                    222: }
                    223: 
                    224: #undef PAGE_ALIGN
                    225: 
                    226: SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
                    227: {
                    228: #ifdef _WIN32
                    229:        VirtualFree((void*)stack->base, 0, MEM_RELEASE);
                    230: #else
                    231:        munmap((void*)stack->base, stack->max_limit - stack->base);
                    232: #endif
                    233:        SLJIT_FREE(stack);
                    234: }
                    235: 
                    236: SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
                    237: {
                    238:        sljit_uw aligned_old_limit;
                    239:        sljit_uw aligned_new_limit;
                    240: 
                    241:        if ((new_limit > stack->max_limit) || (new_limit < stack->base))
                    242:                return -1;
                    243: #ifdef _WIN32
                    244:        aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
                    245:        aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
                    246:        if (aligned_new_limit != aligned_old_limit) {
                    247:                if (aligned_new_limit > aligned_old_limit) {
                    248:                        if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
                    249:                                return -1;
                    250:                }
                    251:                else {
                    252:                        if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
                    253:                                return -1;
                    254:                }
                    255:        }
                    256:        stack->limit = new_limit;
                    257:        return 0;
                    258: #else
                    259:        if (new_limit >= stack->limit) {
                    260:                stack->limit = new_limit;
                    261:                return 0;
                    262:        }
                    263:        aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
                    264:        aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
                    265:        if (aligned_new_limit < aligned_old_limit)
1.1.1.3 ! misho     266:                posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED);
1.1       misho     267:        stack->limit = new_limit;
                    268:        return 0;
                    269: #endif
                    270: }
                    271: 
                    272: #endif /* SLJIT_UTIL_STACK */
                    273: 
                    274: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>