diff options
Diffstat (limited to 'drivers/unix')
-rw-r--r-- | drivers/unix/ip_unix.cpp | 24 | ||||
-rw-r--r-- | drivers/unix/memory_pool_static_malloc.cpp | 432 | ||||
-rw-r--r-- | drivers/unix/memory_pool_static_malloc.h | 82 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 16 | ||||
-rw-r--r-- | drivers/unix/rw_lock_posix.cpp | 77 | ||||
-rw-r--r-- | drivers/unix/rw_lock_posix.h | 37 |
6 files changed, 134 insertions, 534 deletions
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 0ebd593953..ffb37b4f59 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -37,19 +37,25 @@ #ifndef AI_ADDRCONFIG #define AI_ADDRCONFIG 0x00000400 #endif - #ifdef UWP_ENABLED #include <ws2tcpip.h> #include <winsock2.h> #include <windows.h> #include <stdio.h> - #else - #define WINVER 0x0600 - #include <ws2tcpip.h> - #include <winsock2.h> - #include <windows.h> - #include <stdio.h> - #include <iphlpapi.h> - #endif + #ifndef UWP_ENABLED + #if defined(__MINGW32__ ) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 4) + // MinGW-w64 on Ubuntu 12.04 (our Travis build env) has bugs in this code where + // some includes are missing in dependencies of iphlpapi.h for WINVER >= 0x0600 (Vista). + // We don't use this Vista code for now, so working it around by disabling it. + // MinGW-w64 >= 4.0 seems to be better judging by its headers. + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0501 // Windows XP, disable Vista API + #include <iphlpapi.h> + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 // Reenable Vista API + #else + #include <iphlpapi.h> + #endif // MINGW hack + #endif #else #include <netdb.h> #ifdef ANDROID_ENABLED diff --git a/drivers/unix/memory_pool_static_malloc.cpp b/drivers/unix/memory_pool_static_malloc.cpp index a7720cd44a..139597f9cb 100644 --- a/drivers/unix/memory_pool_static_malloc.cpp +++ b/drivers/unix/memory_pool_static_malloc.cpp @@ -1,434 +1,2 @@ -/*************************************************************************/ -/* memory_pool_static_malloc.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "memory_pool_static_malloc.h" -#include "error_macros.h" -#include "os/memory.h" -#include <stdlib.h> -#include <stdio.h> -#include "os/copymem.h" -#include "os/os.h" - -/** - * NOTE NOTE NOTE NOTE - * in debug mode, this prepends the memory size to the allocated block - * so BE CAREFUL! - */ - -void* MemoryPoolStaticMalloc::alloc(size_t p_bytes,const char *p_description) { - - #if DEFAULT_ALIGNMENT == 1 - - return _alloc(p_bytes, p_description); - - #else - - size_t total; - #if defined(_add_overflow) - if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL; - #else - total = p_bytes + DEFAULT_ALIGNMENT; - #endif - uint8_t* ptr = (uint8_t*)_alloc(total, p_description); - ERR_FAIL_COND_V( !ptr, ptr ); - int ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1))); - ptr[ofs-1] = ofs; - return (void*)(ptr + ofs); - #endif -}; - -void* MemoryPoolStaticMalloc::_alloc(size_t p_bytes,const char *p_description) { - - ERR_FAIL_COND_V(p_bytes==0,0); - - MutexLock lock(mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - size_t total; - #if defined(_add_overflow) - if (_add_overflow(p_bytes, sizeof(RingPtr), &total)) return NULL; - #else - total = p_bytes + sizeof(RingPtr); - #endif - void *mem=malloc(total); /// add for size and ringlist - - if (!mem) { - printf("**ERROR: out of memory while allocating %lu bytes by %s?\n", (unsigned long) p_bytes, p_description); - printf("**ERROR: memory usage is %lu\n", (unsigned long) get_total_usage()); - }; - - ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request - - /* setup the ringlist element */ - - RingPtr *ringptr = (RingPtr*)mem; - - /* setup the ringlist element data (description and size ) */ - - ringptr->size = p_bytes; - ringptr->descr=p_description; - - if (ringlist) { /* existing ringlist */ - - /* assign next */ - ringptr->next = ringlist->next; - ringlist->next = ringptr; - /* assign prev */ - ringptr->prev = ringlist; - ringptr->next->prev = ringptr; - } else { /* non existing ringlist */ - - ringptr->next=ringptr; - ringptr->prev=ringptr; - ringlist=ringptr; - - } - - total_mem+=p_bytes; - - /* update statistics */ - if (total_mem > max_mem ) - max_mem = total_mem; - - total_pointers++; - - if (total_pointers > max_pointers) - max_pointers=total_pointers; - - return ringptr + 1; /* return memory after ringptr */ - -#else - void *mem=malloc(p_bytes); - - ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request - return mem; -#endif -} - - -void* MemoryPoolStaticMalloc::realloc(void *p_memory,size_t p_bytes) { - - #if DEFAULT_ALIGNMENT == 1 - - return _realloc(p_memory,p_bytes); - #else - if (!p_memory) - return alloc(p_bytes); - - size_t total; - #if defined(_add_overflow) - if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL; - #else - total = p_bytes + DEFAULT_ALIGNMENT; - #endif - uint8_t* mem = (uint8_t*)p_memory; - int ofs = *(mem-1); - mem = mem - ofs; - uint8_t* ptr = (uint8_t*)_realloc(mem, total); - ERR_FAIL_COND_V(ptr == NULL, NULL); - int new_ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1))); - if (new_ofs != ofs) { - - //printf("realloc moving %i bytes\n", p_bytes); - movemem((ptr + new_ofs), (ptr + ofs), p_bytes); - ptr[new_ofs-1] = new_ofs; - }; - return ptr + new_ofs; - #endif -}; - -void* MemoryPoolStaticMalloc::_realloc(void *p_memory,size_t p_bytes) { - - if (p_memory==NULL) { - - return alloc( p_bytes ); - } - - if (p_bytes==0) { - - this->free(p_memory); - ERR_FAIL_COND_V( p_bytes < 0 , NULL ); - return NULL; - } - - MutexLock lock(mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - - RingPtr *ringptr = (RingPtr*)p_memory; - ringptr--; /* go back an element to find the tingptr */ - - bool single_element = (ringptr->next == ringptr) && (ringptr->prev == ringptr); - bool is_list = ( ringlist == ringptr ); - - RingPtr *new_ringptr=(RingPtr*)::realloc(ringptr, p_bytes+sizeof(RingPtr)); - - ERR_FAIL_COND_V( new_ringptr == 0, NULL ); /// reallocation failed - - /* actualize mem used */ - total_mem -= new_ringptr->size; - new_ringptr->size = p_bytes; - total_mem += new_ringptr->size; - - if (total_mem > max_mem ) //update statistics - max_mem = total_mem; - - if (new_ringptr == ringptr ) - return ringptr + 1; // block didn't move, don't do anything - - if (single_element) { - - new_ringptr->next=new_ringptr; - new_ringptr->prev=new_ringptr; - } else { - - new_ringptr->next->prev=new_ringptr; - new_ringptr->prev->next=new_ringptr; - } - - if (is_list) - ringlist=new_ringptr; - - - return new_ringptr + 1; - -#else - return ::realloc( p_memory, p_bytes ); -#endif -} - -void MemoryPoolStaticMalloc::free(void *p_ptr) { - - ERR_FAIL_COND( !MemoryPoolStatic::get_singleton()); - - #if DEFAULT_ALIGNMENT == 1 - - _free(p_ptr); - #else - - uint8_t* mem = (uint8_t*)p_ptr; - int ofs = *(mem-1); - mem = mem - ofs; - - _free(mem); - #endif -}; - - -void MemoryPoolStaticMalloc::_free(void *p_ptr) { - - MutexLock lock(mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - if (p_ptr==0) { - printf("**ERROR: STATIC ALLOC: Attempted free of NULL pointer.\n"); - return; - }; - - RingPtr *ringptr = (RingPtr*)p_ptr; - - ringptr--; /* go back an element to find the ringptr */ - - -#if 0 - { // check for existing memory on free. - RingPtr *p = ringlist; - - bool found=false; - - if (ringlist) { - do { - if (p==ringptr) { - found=true; - break; - } - - p=p->next; - } while (p!=ringlist); - } - - if (!found) { - printf("**ERROR: STATIC ALLOC: Attempted free of unknown pointer at %p\n",(ringptr+1)); - return; - } - - } -#endif - /* proceed to erase */ - - bool single_element = (ringptr->next == ringptr) && (ringptr->prev == ringptr); - bool is_list = ( ringlist == ringptr ); - - if (single_element) { - /* just get rid of it */ - ringlist=0; - - } else { - /* auto-remove from ringlist */ - if (is_list) - ringlist=ringptr->next; - - ringptr->prev->next = ringptr->next; - ringptr->next->prev = ringptr->prev; - } - - total_mem -= ringptr->size; - total_pointers--; - // catch more errors - zeromem(ringptr,sizeof(RingPtr)+ringptr->size); - ::free(ringptr); //just free that pointer - -#else - ERR_FAIL_COND(p_ptr==0); - - ::free(p_ptr); -#endif -} - - -size_t MemoryPoolStaticMalloc::get_available_mem() const { - - return 0xffffffff; -} - -size_t MemoryPoolStaticMalloc::get_total_usage() { - -#ifdef DEBUG_MEMORY_ENABLED - - return total_mem; -#else - return 0; -#endif - -} - -size_t MemoryPoolStaticMalloc::get_max_usage() { - - return max_mem; -} - -/* Most likely available only if memory debugger was compiled in */ -int MemoryPoolStaticMalloc::get_alloc_count() { - - return total_pointers; -} -void * MemoryPoolStaticMalloc::get_alloc_ptr(int p_alloc_idx) { - - return 0; -} -const char* MemoryPoolStaticMalloc::get_alloc_description(int p_alloc_idx) { - - - return ""; -} -size_t MemoryPoolStaticMalloc::get_alloc_size(int p_alloc_idx) { - - return 0; -} - -void MemoryPoolStaticMalloc::dump_mem_to_file(const char* p_file) { - -#ifdef DEBUG_MEMORY_ENABLED - - ERR_FAIL_COND( !ringlist ); /** WTF BUG !? */ - RingPtr *p = ringlist; - FILE *f = fopen(p_file,"wb"); - - do { - fprintf(f,"%p-%i-%s\n", p+1, (int)p->size, (p->descr?p->descr:"") ); - p=p->next; - } while (p!=ringlist); - - fclose(f); -#endif - -} - -MemoryPoolStaticMalloc::MemoryPoolStaticMalloc() { - -#ifdef DEBUG_MEMORY_ENABLED - total_mem=0; - total_pointers=0; - ringlist=0; - max_mem=0; - max_pointers=0; - - -#endif - - mutex=NULL; -#ifndef NO_THREADS - - mutex=Mutex::create(); // at this point, this should work -#endif - -} - - -MemoryPoolStaticMalloc::~MemoryPoolStaticMalloc() { - - Mutex *old_mutex=mutex; - mutex=NULL; - if (old_mutex) - memdelete(old_mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - if (OS::get_singleton()->is_stdout_verbose()) { - if (total_mem > 0 ) { - printf("**ERROR: STATIC ALLOC: ** MEMORY LEAKS DETECTED **\n"); - printf("**ERROR: STATIC ALLOC: %i bytes of memory in use at exit.\n",(int)total_mem); - - if (1){ - printf("**ERROR: STATIC ALLOC: Following is the list of leaked allocations: \n"); - - ERR_FAIL_COND( !ringlist ); /** WTF BUG !? */ - RingPtr *p = ringlist; - - do { - printf("\t%p - %i bytes - %s\n", (RingPtr*)(p+1), (int)p->size, (p->descr?p->descr:"") ); - p=p->next; - } while (p!=ringlist); - - printf("**ERROR: STATIC ALLOC: End of Report.\n"); - }; - - printf("mem - max %i, pointers %i, leaks %i.\n",(int)max_mem,max_pointers,(int)total_mem); - } else { - - printf("INFO: mem - max %i, pointers %i, no leaks.\n",(int)max_mem,max_pointers); - } - } - -#endif -} diff --git a/drivers/unix/memory_pool_static_malloc.h b/drivers/unix/memory_pool_static_malloc.h index 0d34bac78b..e69de29bb2 100644 --- a/drivers/unix/memory_pool_static_malloc.h +++ b/drivers/unix/memory_pool_static_malloc.h @@ -1,82 +0,0 @@ -/*************************************************************************/ -/* memory_pool_static_malloc.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef MEMORY_POOL_STATIC_MALLOC_H -#define MEMORY_POOL_STATIC_MALLOC_H - -#include "os/memory_pool_static.h" -#include "os/mutex.h" -/** - @author Juan Linietsky <red@lunatea> -*/ -class MemoryPoolStaticMalloc : public MemoryPoolStatic { - - struct RingPtr { - - size_t size; - const char *descr; /* description of memory */ - RingPtr *next; - RingPtr *prev; - }; - - RingPtr *ringlist; - size_t total_mem; - int total_pointers; - - size_t max_mem; - int max_pointers; - - Mutex *mutex; - - void* _alloc(size_t p_bytes,const char *p_description=""); ///< Pointer in p_description shold be to a const char const like "hello" - void* _realloc(void *p_memory,size_t p_bytes); ///< Pointer in - void _free(void *p_ptr); ///< Pointer in p_description shold be to a const char const - -public: - - virtual void* alloc(size_t p_bytes,const char *p_description=""); ///< Pointer in p_description shold be to a const char const like "hello" - virtual void free(void *p_ptr); ///< Pointer in p_description shold be to a const char const - virtual void* realloc(void *p_memory,size_t p_bytes); ///< Pointer in - virtual size_t get_available_mem() const; - virtual size_t get_total_usage(); - virtual size_t get_max_usage(); - - /* Most likely available only if memory debugger was compiled in */ - virtual int get_alloc_count(); - virtual void * get_alloc_ptr(int p_alloc_idx); - virtual const char* get_alloc_description(int p_alloc_idx); - virtual size_t get_alloc_size(int p_alloc_idx); - - void dump_mem_to_file(const char* p_file); - - MemoryPoolStaticMalloc(); - ~MemoryPoolStaticMalloc(); - -}; - -#endif diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 89fd108476..283cff0486 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -30,11 +30,11 @@ #ifdef UNIX_ENABLED -#include "memory_pool_static_malloc.h" -#include "os/memory_pool_dynamic_static.h" + #include "thread_posix.h" #include "semaphore_posix.h" #include "mutex_posix.h" +#include "rw_lock_posix.h" #include "core/os/thread_dummy.h" //#include "core/io/file_access_buffered_fa.h" @@ -116,8 +116,6 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) { return 0; } -static MemoryPoolStaticMalloc *mempool_static=NULL; -static MemoryPoolDynamicStatic *mempool_dynamic=NULL; void OS_Unix::initialize_core() { @@ -130,6 +128,7 @@ void OS_Unix::initialize_core() { ThreadPosix::make_default(); SemaphorePosix::make_default(); MutexPosix::make_default(); + RWLockPosix::make_default(); #endif FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA); @@ -145,8 +144,6 @@ void OS_Unix::initialize_core() { PacketPeerUDPPosix::make_default(); IP_Unix::make_default(); #endif - mempool_static = new MemoryPoolStaticMalloc; - mempool_dynamic = memnew( MemoryPoolDynamicStatic ); ticks_start=0; ticks_start=get_ticks_usec(); @@ -155,9 +152,6 @@ void OS_Unix::initialize_core() { void OS_Unix::finalize_core() { - if (mempool_dynamic) - memdelete( mempool_dynamic ); - delete mempool_static; } @@ -472,7 +466,7 @@ String OS_Unix::get_data_dir() const { if (has_environment("HOME")) { - bool use_godot = Globals::get_singleton()->get("application/use_shared_user_dir"); + bool use_godot = GlobalConfig::get_singleton()->get("application/use_shared_user_dir"); if (use_godot) return get_environment("HOME")+"/.godot/app_userdata/"+an; else @@ -480,7 +474,7 @@ String OS_Unix::get_data_dir() const { } } - return Globals::get_singleton()->get_resource_path(); + return GlobalConfig::get_singleton()->get_resource_path(); } diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp new file mode 100644 index 0000000000..b51e5fd420 --- /dev/null +++ b/drivers/unix/rw_lock_posix.cpp @@ -0,0 +1,77 @@ + +#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) + +#include "os/memory.h" +#include "rw_lock_posix.h" +#include "error_macros.h" +#include <stdio.h> + +void RWLockPosix::read_lock() { + + int err =pthread_rwlock_rdlock(&rwlock); + if (err!=0) { + perror("wtf: "); + } + ERR_FAIL_COND(err!=0); +} + +void RWLockPosix::read_unlock() { + + pthread_rwlock_unlock(&rwlock); +} + +Error RWLockPosix::read_try_lock() { + + if (pthread_rwlock_tryrdlock(&rwlock)!=0) { + return ERR_BUSY; + } else { + return OK; + } + +} + +void RWLockPosix::write_lock() { + + int err = pthread_rwlock_wrlock(&rwlock); + ERR_FAIL_COND(err!=0); +} + +void RWLockPosix::write_unlock() { + + pthread_rwlock_unlock(&rwlock); +} + +Error RWLockPosix::write_try_lock() { + if (pthread_rwlock_trywrlock(&rwlock)!=0) { + return ERR_BUSY; + } else { + return OK; + } +} + + +RWLock *RWLockPosix::create_func_posix() { + + return memnew( RWLockPosix ); +} + +void RWLockPosix::make_default() { + + create_func=create_func_posix; +} + + +RWLockPosix::RWLockPosix() { + + //rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX + pthread_rwlock_init(&rwlock,NULL); +} + + +RWLockPosix::~RWLockPosix() { + + pthread_rwlock_destroy(&rwlock); + +} + +#endif diff --git a/drivers/unix/rw_lock_posix.h b/drivers/unix/rw_lock_posix.h new file mode 100644 index 0000000000..bcc102f6a6 --- /dev/null +++ b/drivers/unix/rw_lock_posix.h @@ -0,0 +1,37 @@ +#ifndef RWLOCKPOSIX_H +#define RWLOCKPOSIX_H + +#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) + +#include <pthread.h> +#include "os/rw_lock.h" + +class RWLockPosix : public RWLock { + + + pthread_rwlock_t rwlock; + + static RWLock *create_func_posix(); + +public: + + virtual void read_lock(); + virtual void read_unlock(); + virtual Error read_try_lock(); + + virtual void write_lock(); + virtual void write_unlock(); + virtual Error write_try_lock(); + + static void make_default(); + + RWLockPosix(); + + ~RWLockPosix(); + +}; + +#endif + + +#endif // RWLOCKPOSIX_H |