diff --git a/include/ulib/base/base.h b/include/ulib/base/base.h index 1cbc365b..9ca7e373 100644 --- a/include/ulib/base/base.h +++ b/include/ulib/base/base.h @@ -26,15 +26,15 @@ # endif #endif -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) -#ifdef HAVE__USR_SRC_LINUX_INCLUDE_GENERATED_UAPI_LINUX_VERSION_H +#ifdef U_LINUX +# ifdef HAVE__USR_SRC_LINUX_INCLUDE_GENERATED_UAPI_LINUX_VERSION_H # include "/usr/src/linux/include/generated/uapi/linux/version.h" -# else +# else # include -# endif -# ifndef LINUX_VERSION_CODE -# error "You need to use at least 2.0 Linux kernel." -# endif +# endif +# ifndef LINUX_VERSION_CODE +# error "You need to use at least 2.0 Linux kernel." +# endif #endif #ifdef USE_LIBSSL diff --git a/include/ulib/base/macro.h b/include/ulib/base/macro.h index d6eda4cf..b03e37ac 100644 --- a/include/ulib/base/macro.h +++ b/include/ulib/base/macro.h @@ -70,7 +70,7 @@ #endif #if defined(DEBUG) || defined(U_TEST) -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# ifdef U_LINUX # define U_NULL_POINTER (const void*)0x0000ffff # else # define U_NULL_POINTER (const void*)0 @@ -162,7 +162,13 @@ #define MAX_FILENAME_LEN 255U #endif +#define U_2M (2U*1024U*1024U) +#define U_1G (1024U*1024U*1024U) + +#define U_2M_MASK (U_2M-1) +#define U_1G_MASK (U_1G-1) #define U_PAGEMASK (PAGESIZE-1) + #define U_TO_FREE ((uint32_t)-2) #define U_NOT_FOUND ((uint32_t)-1) diff --git a/include/ulib/debug/macro.h b/include/ulib/debug/macro.h index 599a9c78..2d4423a3 100644 --- a/include/ulib/debug/macro.h +++ b/include/ulib/debug/macro.h @@ -16,22 +16,22 @@ // Design by contract - if (expr == false) then stop -#ifdef DEBUG -# define U_ASSERT(expr) { UTrace::suspend(); U_INTERNAL_ASSERT(expr); UTrace::resume(); } -# define U_ASSERT_MINOR(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_MINOR(a,b); UTrace::resume(); } -# define U_ASSERT_MAJOR(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_MAJOR(a,b); UTrace::resume(); } -# define U_ASSERT_EQUALS(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_EQUALS(a,b); UTrace::resume(); } -# define U_ASSERT_DIFFERS(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_DIFFERS(a,b); UTrace::resume(); } -# define U_ASSERT_POINTER(ptr) { UTrace::suspend(); U_INTERNAL_ASSERT_POINTER(ptr); UTrace::resume(); } -# define U_ASSERT_RANGE(a,x,b) { UTrace::suspend(); U_INTERNAL_ASSERT_RANGE(a,x,b); UTrace::resume(); } +#ifdef DEBUG // NB: we need to save the status on the stack because of thread (ex. time resolution optimation) +# define U_ASSERT(expr) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT(expr); u_trace_suspend = _s; } +# define U_ASSERT_MINOR(a,b) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_MINOR(a,b); u_trace_suspend = _s; } +# define U_ASSERT_MAJOR(a,b) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_MAJOR(a,b); u_trace_suspend = _s; } +# define U_ASSERT_EQUALS(a,b) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_EQUALS(a,b); u_trace_suspend = _s; } +# define U_ASSERT_DIFFERS(a,b) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_DIFFERS(a,b); u_trace_suspend = _s; } +# define U_ASSERT_POINTER(ptr) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_POINTER(ptr); u_trace_suspend = _s; } +# define U_ASSERT_RANGE(a,x,b) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_RANGE(a,x,b); u_trace_suspend = _s; } -# define U_ASSERT_MSG(expr,info) { UTrace::suspend(); U_INTERNAL_ASSERT_MSG(expr,info); UTrace::resume(); } -# define U_ASSERT_MINOR_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_MINOR_MSG(a,b,info); UTrace::resume(); } -# define U_ASSERT_MAJOR_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_MAJOR_MSG(a,b,info); UTrace::resume(); } -# define U_ASSERT_EQUALS_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_EQUALS_MSG(a,b,info); UTrace::resume(); } -# define U_ASSERT_DIFFERS_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_DIFFERS_MSG(a,b,info); UTrace::resume(); } -# define U_ASSERT_POINTER_MSG(ptr,info) { UTrace::suspend(); U_INTERNAL_ASSERT_POINTER_MSG(ptr,info); UTrace::resume(); } -# define U_ASSERT_RANGE_MSG(a,x,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_RANGE_MSG(a,x,b,info); UTrace::resume(); } +# define U_ASSERT_MSG(expr,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_MSG(expr,info); u_trace_suspend = _s; } +# define U_ASSERT_MINOR_MSG(a,b,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_MINOR_MSG(a,b,info); u_trace_suspend = _s; } +# define U_ASSERT_MAJOR_MSG(a,b,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_MAJOR_MSG(a,b,info); u_trace_suspend = _s; } +# define U_ASSERT_EQUALS_MSG(a,b,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_EQUALS_MSG(a,b,info); u_trace_suspend = _s; } +# define U_ASSERT_DIFFERS_MSG(a,b,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_DIFFERS_MSG(a,b,info); u_trace_suspend = _s; } +# define U_ASSERT_POINTER_MSG(ptr,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_POINTER_MSG(ptr,info); u_trace_suspend = _s; } +# define U_ASSERT_RANGE_MSG(a,x,b,info) { int _s = u_trace_suspend; u_trace_suspend = 1; U_INTERNAL_ASSERT_RANGE_MSG(a,x,b,info); u_trace_suspend = _s; } #elif defined(U_TEST) # define U_ASSERT(expr) U_INTERNAL_ASSERT(expr) # define U_ASSERT_MINOR(a,b) U_INTERNAL_ASSERT_MINOR(a,b) @@ -85,8 +85,8 @@ // NB: U_DUMP, U_SYSCALL() and U_RETURN() depend on presence of U_TRACE() -# define U_INTERNAL_DUMP(args...) { if (utr.active[0]) u_trace_dump(args); } -# define U_DUMP(args...) { if (utr.active[0]) { UTrace::suspend(); u_trace_dump(args); UTrace::resume(); } } +# define U_INTERNAL_DUMP(args...) { if (utr.active[0]) u_trace_dump(args); } +# define U_DUMP(args...) { if (utr.active[0]) { utr.suspend(); u_trace_dump(args); utr.resume(); } } # define U_SYSCALL_NO_PARAM(name) (utr.trace_syscall("::"#name"()",0), \ utr.trace_sysreturn_type(::name())) @@ -94,11 +94,11 @@ # define U_SYSCALL_VOID_NO_PARAM(name) { utr.trace_syscall("::"#name"()",0); \ name(); utr.trace_sysreturn(false,0); } -# define U_SYSCALL(name,format,args...) (UTrace::suspend(), utr.trace_syscall("::"#name"(" format ")" , ##args), \ - UTrace::resume(), utr.trace_sysreturn_type(::name(args))) +# define U_SYSCALL(name,format,args...) (utr.suspend(), utr.trace_syscall("::"#name"(" format ")" , ##args), \ + utr.resume(), utr.trace_sysreturn_type(::name(args))) -# define U_SYSCALL_VOID(name,format,args...) { UTrace::suspend(); utr.trace_syscall("::"#name"(" format ")" , ##args); \ - UTrace::resume(); ::name(args); utr.trace_sysreturn(false,0); } +# define U_SYSCALL_VOID(name,format,args...) { utr.suspend(); utr.trace_syscall("::"#name"(" format ")" , ##args); \ + utr.resume(); ::name(args); utr.trace_sysreturn(false,0); } # define U_RETURN(r) return (utr.trace_return_type((r))) # define U_RETURN_STRING(str) {U_INTERNAL_ASSERT((str).invariant()); return (utr.trace_return("%V",(str).rep),(str));} diff --git a/include/ulib/debug/trace.h b/include/ulib/debug/trace.h index 24fc8bf7..ba43e5f1 100644 --- a/include/ulib/debug/trace.h +++ b/include/ulib/debug/trace.h @@ -123,14 +123,14 @@ public: U_MANAGE_SYSRETURN_VALUE(tdbdata_t, "%J", false) #endif - static void resume() { u_trace_suspend = status; } - static void suspend() { status = u_trace_suspend; u_trace_suspend = 1; } + void resume() { u_trace_suspend = status; } + void suspend() { status = u_trace_suspend; u_trace_suspend = 1; } private: - char buffer_trace[1019], buffer_syscall[1019]; + char buffer_trace[1017], buffer_syscall[1017]; uint32_t buffer_trace_len, buffer_syscall_len; + int status; - static int status; static UCrono* time_syscall_read_or_write; void set(int level) U_NO_EXPORT; diff --git a/include/ulib/event/event_fd.h b/include/ulib/event/event_fd.h index 969449af..29088144 100644 --- a/include/ulib/event/event_fd.h +++ b/include/ulib/event/event_fd.h @@ -42,9 +42,9 @@ /** * Valid opcodes ( "op" parameter ) to issue to epoll_ctl() * - * #define EPOLL_CTL_ADD 1 // Add a file descriptor to the interface + * #define EPOLL_CTL_ADD 1 // Add a file descriptor to the interface * #define EPOLL_CTL_DEL 2 // Remove a file descriptor from the interface - * #define EPOLL_CTL_MOD 3 // Change file descriptor epoll_event structure + * #define EPOLL_CTL_MOD 3 // Change a file descriptor in epoll_event structure */ class U_EXPORT UEventFd { diff --git a/include/ulib/event/event_time.h b/include/ulib/event/event_time.h index c9997aad..fd8a1255 100644 --- a/include/ulib/event/event_time.h +++ b/include/ulib/event/event_time.h @@ -56,8 +56,6 @@ public: ms = (diff1 * 1000L) + (diff2 / 1000L); - U_INTERNAL_DUMP("ms = %ld", ms) - U_ASSERT(checkMilliSecond()) U_RETURN(false); diff --git a/include/ulib/examples/wi_auth_declaration.h b/include/ulib/examples/wi_auth_declaration.h index 02e6d252..394b08d9 100644 --- a/include/ulib/examples/wi_auth_declaration.h +++ b/include/ulib/examples/wi_auth_declaration.h @@ -782,6 +782,7 @@ public: U_CHECK_MEMORY + U_INTERNAL_ASSERT(_mac) U_INTERNAL_ASSERT(nodog) U_INTERNAL_ASSERT_EQUALS(u_buffer_len, 0) @@ -841,6 +842,8 @@ public: is.get(); // skip ' ' _user.get(is); + + U_INTERNAL_ASSERT(_mac) } UString getAP(UString& label) @@ -1268,6 +1271,8 @@ next: U_INTERNAL_DUMP("db_user->isRecordFound() = %b _index_access_point = %u nodog = %V", db_user->isRecordFound(), _index_access_point, nodog.rep) + U_INTERNAL_ASSERT(*mac) + _ip = *ip; _mac = *mac; // agent = UHTTP::getUserAgent(); @@ -1329,6 +1334,8 @@ next: * ------------------------------------------------------------------------------------------------------------------------------------------------------ */ + U_INTERNAL_ASSERT(_mac) + ULog::log(file_LOG->getFd(), "op: %s, uid: %v, ap: %v, ip: %v, mac: %v, timeout: %v, traffic: %v, policy: %v", op, uid->rep, getAP().rep, _ip.rep, _mac.rep, time_counter->rep, traffic_counter->rep, getPolicy().rep); } @@ -4213,6 +4220,8 @@ next: if (write_to_log && user_rec->setNodogReference()) { + ask_logout = true; + user_rec->writeToLOG(write_to_log); } diff --git a/include/ulib/file.h b/include/ulib/file.h index 83bcb240..afd6562b 100644 --- a/include/ulib/file.h +++ b/include/ulib/file.h @@ -16,6 +16,12 @@ #include +#ifdef _MSWINDOWS_ +#define st_ino u_inode +#elif defined(U_LINUX) +# include +#endif + #include // struct stat { @@ -34,10 +40,6 @@ // time_t st_ctime; /* time of last change */ // }; -#ifdef _MSWINDOWS_ -#define st_ino u_inode -#endif - // File-permission-bit symbols #define U_PERM__rw_r__r__ 0644 @@ -634,9 +636,8 @@ public: // LOCKING - bool lock(short l_type = F_WRLCK, uint32_t start = 0, uint32_t len = 0) const; /* set the lock, waiting if necessary */ - - bool unlock(uint32_t start = 0, uint32_t len = 0) const { return lock(F_UNLCK, start, len); } + bool lock(short l_type = F_WRLCK, uint32_t start = 0, uint32_t len = 0) const; // set the lock, waiting if necessary + bool unlock( uint32_t start = 0, uint32_t len = 0) const { return lock(F_UNLCK, start, len); } // MEMORY MAPPED I/O (Basically, you can tell the OS that some file is the backing store for a certain portion of the process memory) @@ -848,19 +849,17 @@ public: // ---------------------------------------------------------------------------------------------------------------------- // create a unique temporary file // ---------------------------------------------------------------------------------------------------------------------- - // char pathname[] = "/tmp/dataXXXXXX" - // The last six characters of template must be XXXXXX and these are replaced with a string that makes the filename unique - // ---------------------------------------------------------------------------------------------------------------------- - bool mkTemp(char* _template); + bool mkTemp(); + bool mkTempForLock(); // -------------------------------------------------------------------------------------------------------------- // mkdtemp - create a unique temporary directory // -------------------------------------------------------------------------------------------------------------- // The mkdtemp() function generates a uniquely-named temporary directory from template. The last six characters - // of template must be XXXXXX and these are replaced with a string that makes the directory name unique. - // The directory is then created with permissions 0700. - // Since it will be modified, template must not be a string constant, but should be declared as a character array + // of template must be XXXXXX and these are replaced with a string that makes the directory name unique. The + // directory is then created with permissions 0700. Since it will be modified, template must not be a string + // constant, but should be declared as a character array // -------------------------------------------------------------------------------------------------------------- static bool mkdtemp(UString& _template); @@ -881,15 +880,81 @@ public: // MEMORY POOL + static uint32_t getPageMask(uint32_t length) // NB: munmap() length of MAP_HUGETLB memory must be hugepage aligned... + { + U_TRACE(0, "UFile::getPageMask(%u)", length) + +# if defined(U_LINUX) && defined(U_MEMALLOC_WITH_HUGE_PAGE) && (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_2MB)) // (since Linux 3.8) + if (nr_hugepages) + { + U_INTERNAL_DUMP("nr_hugepages = %u rlimit_memfree = %u", nr_hugepages, rlimit_memfree) + + U_INTERNAL_ASSERT_EQUALS(rlimit_memfree, U_2M) + +# ifdef MAP_HUGE_1GB + if (length >= U_1G) U_RETURN(U_1G_MASK); +# endif +# ifdef MAP_HUGE_2MB + U_RETURN(U_2M_MASK); +# endif + } +# endif + + U_RETURN(U_PAGEMASK); + } + + static bool checkPageAlignment(uint32_t length) // NB: munmap() length of MAP_HUGETLB memory must be hugepage aligned... + { + U_TRACE(0, "UFile::checkPageAlignment(%u)", length) + +# if defined(U_LINUX) && defined(U_MEMALLOC_WITH_HUGE_PAGE) && (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_2MB)) // (since Linux 3.8) + if (nr_hugepages) + { + U_INTERNAL_DUMP("nr_hugepages = %u rlimit_memfree = %u", nr_hugepages, rlimit_memfree) + + U_INTERNAL_ASSERT_EQUALS(rlimit_memfree, U_2M) + +# ifdef MAP_HUGE_1GB + if (length >= U_1G) + { + if ((length & U_1G_MASK) == 0) U_RETURN(true); + + U_RETURN(false); + } +# endif +# ifdef MAP_HUGE_2MB + if ((length & U_2M_MASK) == 0) U_RETURN(true); + + U_RETURN(false); +# endif + } +# endif + if ((length & U_PAGEMASK) == 0) U_RETURN(true); + + U_RETURN(false); + } + + static uint32_t getSizeAligned(uint32_t length) // NB: munmap() length of MAP_HUGETLB memory must be hugepage aligned... + { + U_TRACE(0, "UFile::getSizeAligned(%u)", length) + + uint32_t pmask = getPageMask(length), + sz = (length + pmask) & ~pmask; + + U_ASSERT(checkPageAlignment(sz)) + + U_RETURN(sz); + } + static bool isAllocableFromPool(uint32_t sz) { U_TRACE(0, "UFile::isAllocableFromPool(%u)", sz) -# if defined(ENABLE_MEMPOOL) +# ifdef ENABLE_MEMPOOL U_INTERNAL_DUMP("nfree = %u pfree = %p", nfree, pfree) if (sz > U_CAPACITY && - nfree > (sz + rlimit_memfree)) + nfree > (getSizeAligned(sz) + rlimit_memfree)) { U_RETURN(true); } @@ -902,8 +967,7 @@ public: { U_TRACE(0, "UFile::isLastAllocation(%p,%lu)", ptr, sz) -# if defined(ENABLE_MEMPOOL) - U_INTERNAL_ASSERT_EQUALS(sz & U_PAGEMASK, 0) +# ifdef ENABLE_MEMPOOL U_INTERNAL_ASSERT(sz >= U_MAX_SIZE_PREALLOCATE) U_INTERNAL_DUMP("nfree = %u pfree = %p", nfree, pfree) @@ -912,7 +976,12 @@ public: { U_INTERNAL_ASSERT_MAJOR(nfree, rlimit_memfree) - if ((pfree - sz) == ptr) U_RETURN(true); + if ((pfree - sz) == ptr) + { + U_ASSERT(UFile::checkPageAlignment(sz)) // NB: munmap() length of MAP_HUGETLB memory must be hugepage aligned... + + U_RETURN(true); + } } # endif @@ -936,7 +1005,7 @@ protected: static uint32_t cwd_save_len; static char* pfree; - static uint32_t nfree, rlimit_memfree, rlimit_memalloc; + static uint32_t nfree, rlimit_memfree, rlimit_memalloc, nr_hugepages; void substitute(UFile& file); bool creatForWrite(bool append, bool bmkdirs); @@ -947,6 +1016,8 @@ protected: static void ftw_tree_push(); static void ftw_vector_push(); + static char* mmap_anon_huge(uint32_t* plength, int flags); + private: #ifdef _MSWINDOWS_ uint64_t u_inode; diff --git a/include/ulib/internal/memory_pool.h b/include/ulib/internal/memory_pool.h index ec52efdc..4371be41 100644 --- a/include/ulib/internal/memory_pool.h +++ b/include/ulib/internal/memory_pool.h @@ -508,6 +508,8 @@ private: friend class UNoCatPlugIn; friend class UStackMemoryPool; + friend void check_mmap(uint32_t); + template friend class UVector; }; diff --git a/include/ulib/internal/objectIO.h b/include/ulib/internal/objectIO.h index fe5048fa..f0d1a8f8 100644 --- a/include/ulib/internal/objectIO.h +++ b/include/ulib/internal/objectIO.h @@ -120,7 +120,8 @@ template inline char* U_OBJECT_TO_TRACE(T& object) U_INTERNAL_TRACE("U_OBJECT_TO_TRACE(%p)", &object) #ifdef DEBUG - UTrace::suspend(); + int status = u_trace_suspend; + u_trace_suspend = 1; #endif char* str = UObject2String(object); @@ -128,7 +129,7 @@ template inline char* U_OBJECT_TO_TRACE(T& object) str = strndup(str, UObjectIO::buffer_output_len); #ifdef DEBUG - UTrace::resume(); + u_trace_suspend = status; #endif return str; diff --git a/include/ulib/internal/platform.h b/include/ulib/internal/platform.h index 591d8f14..855a3de1 100644 --- a/include/ulib/internal/platform.h +++ b/include/ulib/internal/platform.h @@ -18,7 +18,9 @@ /* see if targeting legacy Microsoft windows platform */ -#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) +#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) || defined(__linux) +# define U_LINUX +#elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) # define _MSWINDOWS_ # if defined(_MSC_VER) # define NOMINMAX @@ -83,7 +85,7 @@ __GNUC_MINOR__ * 100 + \ __GNUC_PATCHLEVEL__) # if GCC_VERSION_NUM > 29600 && GCC_VERSION_NUM != 30303 /* Test for GCC == 3.3.3 (SuSE Linux) */ -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) || defined(_MSWINDOWS_) +# if defined(U_LINUX) || defined(_MSWINDOWS_) # define __pure __attribute__((pure)) # endif # define LIKELY(x) __builtin_expect(!!(x), 1) @@ -344,18 +346,35 @@ typedef int socket_t; #undef putchar #if !defined(_GNU_SOURCE) || defined(__OSX__) || defined(__NetBSD__) || defined(__UNIKERNEL__) -typedef void (*sighandler_t)(int); /* Convenient typedef for signal handlers */ +typedef void (*sighandler_t)(int); /* Convenient typedef for signal handlers */ #endif -typedef unsigned long timeout_t; /* Typedef for millisecond timer values */ +typedef unsigned long timeout_t; /* Typedef for millisecond timer values */ #include #include #include -#ifdef MAP_UNINITIALIZED // (since Linux 2.6.33) -#define U_MAP_ANON (MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED) +#ifndef U_LINUX +# define U_MAP_ANON MAP_ANONYMOUS +# define MAP_HUGETLB 0 +# define U_MAP_ANON_HUGE 0 +# define U_MAP_ANON_HUGE_ADDR (void*)(0x0UL) #else -#define U_MAP_ANON (MAP_PRIVATE | MAP_ANONYMOUS) +# ifdef MAP_UNINITIALIZED /* (since Linux 2.6.33) */ +# define U_MAP_ANON (MAP_ANONYMOUS | MAP_UNINITIALIZED) +# else +# define U_MAP_ANON MAP_ANONYMOUS +# endif +# ifndef MAP_HUGETLB /* (since Linux 2.6.32) */ +# define MAP_HUGETLB 0x40000 /* arch specific */ +# endif +# ifdef __ia64__ /* Only ia64 requires this */ +# define U_MAP_ANON_HUGE (MAP_HUGETLB | MAP_FIXED) +# define U_MAP_ANON_HUGE_ADDR (void*)(0x8000000000000000UL) +# else +# define U_MAP_ANON_HUGE MAP_HUGETLB +# define U_MAP_ANON_HUGE_ADDR (void*)(0x0UL) +# endif #endif #endif diff --git a/include/ulib/log.h b/include/ulib/log.h index 60619f90..a245f7d2 100644 --- a/include/ulib/log.h +++ b/include/ulib/log.h @@ -138,6 +138,7 @@ protected: void checkForLogRotateDataToWrite(); #endif + static uint32_t log_data_sz; static long tv_sec_old_1, tv_sec_old_2, tv_sec_old_3; void write(const struct iovec* iov, int n); diff --git a/include/ulib/net/socket.h b/include/ulib/net/socket.h index 1b075fa4..1def03a5 100644 --- a/include/ulib/net/socket.h +++ b/include/ulib/net/socket.h @@ -460,7 +460,7 @@ public: U_INTERNAL_ASSERT_POINTER(sk) -# if defined(TCP_CORK) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) +# if defined(TCP_CORK) && defined(U_LINUX) (void) sk->setSockOpt(SOL_TCP, TCP_CORK, (const void*)&value, sizeof(uint32_t)); # endif } @@ -475,7 +475,7 @@ public: { U_TRACE_NO_PARAM(0, "USocket::setTcpDeferAccept()") -# if defined(TCP_DEFER_ACCEPT) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) +# if defined(TCP_DEFER_ACCEPT) && defined(U_LINUX) (void) setSockOpt(SOL_TCP, TCP_DEFER_ACCEPT, (const int[]){ 1 }, sizeof(int)); # endif } @@ -484,7 +484,7 @@ public: { U_TRACE_NO_PARAM(0, "USocket::setTcpFastOpen()") -# if !defined(U_SERVER_CAPTIVE_PORTAL) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) // && LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) +# if !defined(U_SERVER_CAPTIVE_PORTAL) && defined(U_LINUX) // && LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) # ifndef TCP_FASTOPEN # define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ # endif @@ -496,7 +496,7 @@ public: { U_TRACE(0, "USocket::setTcpQuickAck(%d)", value) -# if defined(TCP_QUICKACK) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) +# if defined(TCP_QUICKACK) && defined(U_LINUX) (void) setSockOpt(SOL_TCP, TCP_QUICKACK, &value, sizeof(int)); # endif } @@ -514,7 +514,7 @@ public: { U_TRACE(0, "USocket::setTcpCongestion(%S)", value) -# if defined(TCP_CONGESTION) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) +# if defined(TCP_CONGESTION) && defined(U_LINUX) (void) setSockOpt(IPPROTO_TCP, TCP_CONGESTION, (const void*)&value, u__strlen(value, __PRETTY_FUNCTION__) + 1); # endif } diff --git a/include/ulib/thread.h b/include/ulib/thread.h index 0e606fb6..a83a1c0b 100644 --- a/include/ulib/thread.h +++ b/include/ulib/thread.h @@ -17,19 +17,17 @@ #include #include -#ifdef _MSWINDOWS_ +#ifdef U_LINUX +# define U_SIGSTOP (SIGRTMIN+5) +# define U_SIGCONT (SIGRTMIN+6) +#elif defined(_MSWINDOWS_) # include # undef sleep # undef signal # define PTHREAD_CREATE_DETACHED 1 #else -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) -# define U_SIGSTOP (SIGRTMIN+5) -# define U_SIGCONT (SIGRTMIN+6) -# else -# define U_SIGSTOP SIGSTOP -# define U_SIGCONT SIGCONT -# endif +# define U_SIGSTOP SIGSTOP +# define U_SIGCONT SIGCONT #endif class UNotifier; diff --git a/include/ulib/utility/semaphore.h b/include/ulib/utility/semaphore.h index d3062d12..bcd58625 100644 --- a/include/ulib/utility/semaphore.h +++ b/include/ulib/utility/semaphore.h @@ -105,7 +105,7 @@ protected: #if defined(__MACOSX__) || defined(__APPLE__) sem_t* psem; char name[24]; -#elif defined(_MSWINDOWS_) || (defined(HAVE_SEM_INIT) && ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))) +#elif defined(_MSWINDOWS_) || (defined(HAVE_SEM_INIT) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))) sem_t* psem; #else UFile* psem; @@ -117,8 +117,7 @@ protected: static bool checkForDeadLock(UTimeVal& time); // NB: check if process has restarted and it had a lock active... -#if !defined(__MACOSX__) && !defined(__APPLE__) && defined(HAVE_SEM_GETVALUE) && \ - ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) +#if !defined(__MACOSX__) && !defined(__APPLE__) && defined(HAVE_SEM_GETVALUE) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) int getValue() { int value = -1; (void) sem_getvalue(psem, &value); return value; } #else int getValue() { return -1; } diff --git a/src/ulib/base/base.c b/src/ulib/base/base.c index cd4584e8..2b5b8bee 100644 --- a/src/ulib/base/base.c +++ b/src/ulib/base/base.c @@ -2451,7 +2451,7 @@ case_o: goto nosign; case_p: /* The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printable characters, in an implementation-defined manner */ -# if defined(HAVE_ARCH64) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) +# if defined(HAVE_ARCH64) && defined(U_LINUX) argument = (long) VA_ARG(const char* restrict); # else argument = (long) VA_ARG(const char* restrict) & 0x00000000ffffffffLL; diff --git a/src/ulib/base/base_trace.c b/src/ulib/base/base_trace.c index 7923277a..167358c4 100644 --- a/src/ulib/base/base_trace.c +++ b/src/ulib/base/base_trace.c @@ -191,10 +191,10 @@ void u_trace_close(void) { ptrdiff_t write_size = file_ptr - file_mem; - U_INTERNAL_ASSERT_MINOR(write_size,(ptrdiff_t)file_size) + U_INTERNAL_ASSERT_MINOR(write_size, (ptrdiff_t)file_size) - // (void) msync(file_mem, write_size, MS_SYNC); - (void) munmap(file_mem, file_size); + (void) msync(file_mem, write_size, MS_SYNC | MS_INVALIDATE); + (void) munmap(file_mem, file_size); (void) ftruncate(lfd, write_size); (void) fsync(lfd); diff --git a/src/ulib/base/utility.c b/src/ulib/base/utility.c index c68e988d..79c7d10e 100644 --- a/src/ulib/base/utility.c +++ b/src/ulib/base/utility.c @@ -38,7 +38,7 @@ #ifndef _MSWINDOWS_ # include -# if defined(__linux__) && defined(HAVE_LIBCAP) +# if defined(U_LINUX) && defined(HAVE_LIBCAP) # include # include # ifdef SECBIT_KEEP_CAPS @@ -265,7 +265,7 @@ uint32_t u_gettid(void) GetCurrentThreadId(); # elif defined(HAVE_PTHREAD_GETTHREADID_NP) pthread_getthreadid_np(); -# elif defined(linux) +# elif defined(U_LINUX) syscall(SYS_gettid); # elif defined(__sun) pthread_self(); @@ -392,7 +392,7 @@ void u_dont_need_root(void) void u_never_need_root(void) { #ifndef _MSWINDOWS_ -# if defined(__linux__) && defined(HAVE_LIBCAP) +# if defined(U_LINUX) && defined(HAVE_LIBCAP) /* cap_list[] = { {"chown", CAP_CHOWN}, diff --git a/src/ulib/container/vector.cpp b/src/ulib/container/vector.cpp index bfcdff77..fddbaeaa 100644 --- a/src/ulib/container/vector.cpp +++ b/src/ulib/container/vector.cpp @@ -14,6 +14,10 @@ #include #include +#if defined(ENABLE_MEMPOOL) && defined(U_LINUX) +# include +#endif + bool UVector::istream_loading; void UVector::push(const void* elem) // add to end @@ -192,10 +196,8 @@ UVector::UVector(const UString& str, char delim) : UVector if (n > 64) { -# if defined(ENABLE_MEMPOOL) && !defined(_MSWINDOWS_) - uint32_t npage = (((n * sizeof(UStringRep)) + U_PAGEMASK) & ~U_PAGEMASK) / sizeof(UStringRep); - - UMemoryPool::allocateMemoryBlocks(U_SIZE_TO_STACK_INDEX(sizeof(UStringRep)), npage); +# if defined(ENABLE_MEMPOOL) && defined(U_LINUX) + UMemoryPool::allocateMemoryBlocks(U_SIZE_TO_STACK_INDEX(sizeof(UStringRep)), UFile::getSizeAligned(n * sizeof(UStringRep)) / sizeof(UStringRep)); # endif UMemoryPool::_free(vec, _capacity, sizeof(void*)); diff --git a/src/ulib/debug/error.cpp b/src/ulib/debug/error.cpp index 17f5439b..eecae2e2 100644 --- a/src/ulib/debug/error.cpp +++ b/src/ulib/debug/error.cpp @@ -28,7 +28,7 @@ vPF UError::callerDataDump; # include # ifdef HAVE_DLFCN_H # include -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# ifdef U_LINUX static uint32_t execute_addr2line(char* buffer, uint32_t buffer_size, const char* image, void* addr) { ssize_t len; @@ -170,7 +170,7 @@ void UError::stackDump() if (trace_size <= 2) abort(); -# if !defined(LINUX) && !defined(__LINUX__) && !defined(__linux__) +# ifndef U_LINUX // This function is similar to backtrace_symbols() but it writes the result immediately // to a file and can therefore also be used in situations where malloc() is not usable anymore diff --git a/src/ulib/debug/trace.cpp b/src/ulib/debug/trace.cpp index ca8f6a2f..3b467910 100644 --- a/src/ulib/debug/trace.cpp +++ b/src/ulib/debug/trace.cpp @@ -23,7 +23,6 @@ #include -int UTrace::status; UCrono* UTrace::time_syscall_read_or_write; U_NO_EXPORT void UTrace::set(int level) @@ -48,7 +47,7 @@ UTrace::UTrace(int level, uint32_t len, const char* name) { U_INTERNAL_TRACE("UTrace::UTrace(%d,%u,%s)", level, len, name) - U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_trace), 1019) + U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_trace), 1017) buffer_trace_len = buffer_syscall_len = 0; @@ -67,7 +66,7 @@ UTrace::UTrace(int level, const char* format, ...) { U_INTERNAL_TRACE("UTrace::UTrace(%d,%s)", level, format) - U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_trace), 1019) + U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_trace), 1017) buffer_trace_len = buffer_syscall_len = 0; @@ -117,7 +116,7 @@ void UTrace::trace_return(const char* format, ...) { U_INTERNAL_TRACE("UTrace::trace_return(%s)", format) - U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_trace), 1019) + U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_trace), 1017) if (active[0] && (sizeof(buffer_trace) - buffer_trace_len) > 32) @@ -178,7 +177,7 @@ void UTrace::trace_sysreturn(bool error, const char* format, ...) { U_INTERNAL_TRACE("UTrace::trace_sysreturn(%d,%s)", error, format) - U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_syscall), 1019) + U_INTERNAL_ASSERT_EQUALS(sizeof(buffer_syscall), 1017) #ifdef _MSWINDOWS_ if (format && diff --git a/src/ulib/file.cpp b/src/ulib/file.cpp index de9a45d1..d81ef088 100644 --- a/src/ulib/file.cpp +++ b/src/ulib/file.cpp @@ -25,6 +25,7 @@ char* UFile::cwd_save; char* UFile::pfree; uint32_t UFile::nfree; +uint32_t UFile::nr_hugepages; uint32_t UFile::cwd_save_len; uint32_t UFile::rlimit_memfree = 16U * 1024U; uint32_t UFile::rlimit_memalloc = 256U * 1024U * 1024U; @@ -465,7 +466,81 @@ void UFile::shm_unlink(const char* name) #endif } -// On 64-bit platforms maps (but not reserves) 256+ Megabytes of virtual address space +// On linux platforms maps (but not reserves) 256+ Megabytes of virtual address space + +char* UFile::mmap_anon_huge(uint32_t* plength, int flags) +{ + U_TRACE(1, "UFile::mmap_anon_huge(%p,%d,%u)", plength, flags) + +#ifdef U_LINUX + if (nr_hugepages) + { + char* ptr; + uint32_t length; + + U_INTERNAL_DUMP("nr_hugepages = %u rlimit_memfree = %u", nr_hugepages, rlimit_memfree) + + U_INTERNAL_ASSERT_EQUALS(rlimit_memfree, U_2M) + +# ifdef MAP_HUGE_1GB /* (since Linux 3.8) */ + if (*plength >= U_1G) + { + length = (*plength + U_1G_MASK) & ~U_1G_MASK; // NB: munmap() length of MAP_HUGETLB memory must be hugepage aligned... + + U_INTERNAL_ASSERT_EQUALS(length & U_1G_MASK, 0) + + U_DEBUG("we are going to allocate (%u GB - %u bytes) MAP_HUGE_1GB - nfree = %u flags = %B", length / U_1G, length, nfree, flags | U_MAP_ANON_HUGE | MAP_HUGE_1GB); + + ptr = (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", U_MAP_ANON_HUGE_ADDR, length, PROT_READ | PROT_WRITE, flags | U_MAP_ANON_HUGE | MAP_HUGE_1GB, -1, 0); + + if (ptr != (char*)MAP_FAILED) + { + *plength = length; + + return ptr; + } + } +# endif +# ifdef MAP_HUGE_2MB /* (since Linux 3.8) */ + length = (*plength + U_2M_MASK) & ~U_2M_MASK; // NB: munmap() length of MAP_HUGETLB memory must be hugepage aligned... + + U_INTERNAL_ASSERT_EQUALS(length & U_2M_MASK, 0) + + U_DEBUG("we are going to allocate (%u MB - %u bytes) MAP_HUGE_2MB - nfree = %u flags = %B", length / (1024U*1024U), length, nfree, flags | U_MAP_ANON_HUGE | MAP_HUGE_2MB); + + ptr = (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", U_MAP_ANON_HUGE_ADDR, length, PROT_READ | PROT_WRITE, flags | U_MAP_ANON_HUGE | MAP_HUGE_2MB, -1, 0); + + if (ptr != (char*)MAP_FAILED) + { + *plength = length; + + return ptr; + } + + if (*plength < U_1G) + { + unsigned long vsz, rss; + + u_get_memusage(&vsz, &rss); + + U_ERROR("cannot allocate %u bytes (%u MB) of memory MAP_HUGE_2MB - " + "address space usage: %.2f MBytes - " + "rss usage: %.2f MBytes", + *plength, *plength / (1024U*1024U), (double)vsz / (1024.0 * 1024.0), + (double)rss / (1024.0 * 1024.0)); + } +# endif + } +#endif + + *plength = (*plength + U_PAGEMASK) & ~U_PAGEMASK; + + U_INTERNAL_ASSERT_EQUALS(*plength & U_PAGEMASK, 0) + + U_DEBUG("we are going to allocate (%u KB - %u bytes) - nfree = %u flags = %B", *plength / 1024U, *plength, nfree, flags); + + return (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, *plength, PROT_READ | PROT_WRITE, flags, -1, 0); +} char* UFile::mmap(uint32_t* plength, int _fd, int prot, int flags, uint32_t offset) { @@ -473,44 +548,45 @@ char* UFile::mmap(uint32_t* plength, int _fd, int prot, int flags, uint32_t offs U_INTERNAL_ASSERT_POINTER(plength) -#ifndef _MSWINDOWS_ -# ifndef HAVE_ARCH64 +#ifdef U_LINUX +# ifndef HAVE_ARCH64 U_INTERNAL_ASSERT_RANGE(1U, *plength, 3U * 1024U * 1024U * 1024U) // limit of linux system on 32bit -# endif +# endif if (_fd != -1) #endif return (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, *plength, prot, flags, _fd, offset); - *plength = (*plength + U_PAGEMASK) & ~U_PAGEMASK; + U_INTERNAL_ASSERT_EQUALS(prot, PROT_READ | PROT_WRITE) - U_INTERNAL_ASSERT_EQUALS(*plength & U_PAGEMASK, 0) + if ((flags & MAP_SHARED) != 0) + { + U_INTERNAL_ASSERT_DIFFERS(flags & MAP_ANONYMOUS, 0) - if ((flags & MAP_SHARED) != 0) return (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, *plength, prot, flags, -1, 0); + return mmap_anon_huge(plength, flags); + } + + U_INTERNAL_ASSERT_DIFFERS(flags & MAP_PRIVATE, 0) char* _ptr; bool _abort = false; - if (*plength >= rlimit_memalloc) // NB: we try to save some swap pressure... + if (*plength >= rlimit_memalloc) // NB: we try to avoid huge swap pressure... { -#if !defined(U_SERVER_CAPTIVE_PORTAL) +#ifndef U_SERVER_CAPTIVE_PORTAL try_from_file_system: #endif UFile tmp; - char _template[32]; -# ifdef DEBUG - U_WARNING("we are going to allocate from file system (%u KB - %u bytes) (pid %P)", *plength / 1024, *plength); -# endif + *plength = (*plength + U_PAGEMASK) & ~U_PAGEMASK; - // By default, /tmp on Fedora 18 will be on a tmpfs. Storage of large temporary files should be done in /var/tmp. - // This will reduce the I/O generated on disks, increase SSD lifetime, save power, and improve performance of the /tmp filesystem + U_INTERNAL_ASSERT_EQUALS(*plength & U_PAGEMASK, 0) - (void) strcpy(_template, "/var/tmp/mapXXXXXX"); + U_DEBUG("we are going to allocate from file system (%u KB - %u bytes)", *plength / 1024, *plength); - _ptr = (tmp.mkTemp(_template) == false || + _ptr = (tmp.mkTemp() == false || tmp.fallocate(*plength) == false ? (char*)MAP_FAILED - : (char*)U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, tmp.st_size, prot, MAP_PRIVATE | MAP_NORESERVE, tmp.fd, 0)); + : (char*)U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, tmp.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE, tmp.fd, 0)); if (tmp.isOpen()) tmp.close(); @@ -530,11 +606,10 @@ try_from_file_system: } } -#if defined(U_SERVER_CAPTIVE_PORTAL) -# ifdef DEBUG - U_WARNING("we are going to malloc %u bytes (%u KB) (pid %P)", *plength, *plength / 1024); -# endif - _ptr = (char*) U_SYSCALL(malloc, "%u", *plength); +#ifdef U_SERVER_CAPTIVE_PORTAL + U_DEBUG("we are going to malloc %u bytes (%u KB)", *plength, *plength / 1024); + + return (char*) U_SYSCALL(malloc, "%u", *plength); #else U_INTERNAL_DUMP("plength = %u nfree = %u pfree = %p", *plength, nfree, pfree) @@ -545,16 +620,20 @@ try_from_file_system: u_get_memusage(&vsz, &rss); - U_WARNING("we are going to allocate %u MB (pid %P) - " + U_DEBUG("we are going to allocate %u MB - " "address space usage: %.2f MBytes - " "rss usage: %.2f MBytes", rlimit_memalloc / (1024 * 1024), - (double)vsz / (1024.0 * 1024.0), - (double)rss / (1024.0 * 1024.0)); + (double)vsz / (1024.0 * 1024.0), + (double)rss / (1024.0 * 1024.0)); # endif nfree = rlimit_memalloc; - pfree = (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, nfree, prot, U_MAP_ANON, -1, 0); +# ifdef U_MEMALLOC_WITH_HUGE_PAGE + pfree = mmap_anon_huge(&nfree, MAP_PRIVATE | U_MAP_ANON); +# else + pfree = (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, nfree, PROT_READ | PROT_WRITE, MAP_PRIVATE | U_MAP_ANON, -1, 0); +# endif if (pfree == (char*)MAP_FAILED) { @@ -565,11 +644,7 @@ try_from_file_system: if (*plength > nfree) { -# ifdef DEBUG - U_WARNING("we are going to allocate (%u KB - %u bytes) (pid %P) - nfree = %u", *plength / 1024, *plength, nfree); -# endif - - _ptr = (char*) U_SYSCALL(mmap, "%d,%u,%d,%d,%d,%u", 0, *plength, prot, U_MAP_ANON, -1, 0); + _ptr = mmap_anon_huge(plength, MAP_PRIVATE | U_MAP_ANON); if (_ptr == (char*)MAP_FAILED) { @@ -581,6 +656,34 @@ try_from_file_system: return _ptr; } +# ifdef U_MEMALLOC_WITH_HUGE_PAGE + if (nr_hugepages) + { +# ifdef MAP_HUGE_1GB + if (*plength >= U_1G) + { + *plength = (*plength + U_1G_MASK) & ~U_1G_MASK; + + U_INTERNAL_ASSERT_EQUALS(*plength & U_1G_MASK, 0) + } + else +# endif +# ifdef MAP_HUGE_2MB + { + *plength = (*plength + U_2M_MASK) & ~U_2M_MASK; + + U_INTERNAL_ASSERT_EQUALS(*plength & U_2M_MASK, 0) + } +# endif + } + else +# endif + { + *plength = (*plength + U_PAGEMASK) & ~U_PAGEMASK; + + U_INTERNAL_ASSERT_EQUALS(*plength & U_PAGEMASK, 0) + } + _ptr = pfree; nfree -= *plength; @@ -592,9 +695,9 @@ try_from_file_system: } U_INTERNAL_DUMP("plength = %u nfree = %u pfree = %p", *plength, nfree, pfree) -#endif return _ptr; +#endif } bool UFile::memmap(int prot, UString* str, uint32_t offset, uint32_t length) @@ -607,8 +710,8 @@ bool UFile::memmap(int prot, UString* str, uint32_t offset, uint32_t length) U_INTERNAL_DUMP("path_relativ(%u) = %.*S", path_relativ_len, path_relativ_len, path_relativ) - U_INTERNAL_ASSERT_DIFFERS(fd,-1) - U_INTERNAL_ASSERT_MAJOR(st_size,0) + U_INTERNAL_ASSERT_DIFFERS(fd, -1) + U_INTERNAL_ASSERT_MAJOR(st_size, 0) #ifdef _MSWINDOWS_ U_INTERNAL_ASSERT((off_t)length <= st_size) // NB: don't allow mappings beyond EOF since Windows can't handle that POSIX like... @@ -978,33 +1081,32 @@ bool UFile::lock(short l_type, uint32_t start, uint32_t len) const */ #if defined(__NetBSD__) || defined(__UNIKERNEL__) || defined(__OSX__) - /* - struct flock { - off_t l_start; // starting offset - off_t l_len; // len = 0 means until end of file - pid_t l_pid; // lock owner - short l_type; // lock type: read/write, etc. - short l_whence; // type of l_start - }; - */ + /** + * struct flock { + * off_t l_start; // starting offset + * off_t l_len; // len = 0 means until end of file + * pid_t l_pid; // lock owner + * short l_type; // lock type: read/write, etc. + * short l_whence; // type of l_start + * }; + */ struct flock flock = { start, len, u_pid, SEEK_SET, l_type }; #else - /* - struct flock { - short l_type; // Type of lock: F_RDLCK, F_WRLCK, F_UNLCK - short l_whence; // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END - off_t l_start; // Starting offset for lock - off_t l_len; // Number of bytes to lock - pid_t l_pid; // PID of process blocking our lock (F_GETLK only) - }; - */ + /** + * struct flock { + * short l_type; // Type of lock: F_RDLCK, F_WRLCK, F_UNLCK + * short l_whence; // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END + * off_t l_start; // Starting offset for lock + * off_t l_len; // Number of bytes to lock + * pid_t l_pid; // PID of process blocking our lock (F_GETLK only) + * }; + */ struct flock flock = { l_type, SEEK_SET, start, len, u_pid }; #endif /** - * --------------------------------------------------------------------------------------------------------------------- * F_SETLK: Acquire a lock (when l_type is F_RDLCK or F_WRLCK) or release a lock (when l_type is F_UNLCK) on the * bytes specified by the l_whence, l_start, and l_len fields of lock. If a conflicting lock is held by another * process, this call returns -1 and sets errno to EACCES or EAGAIN. @@ -1078,9 +1180,12 @@ bool UFile::fallocate(uint32_t n) U_CHECK_MEMORY U_INTERNAL_ASSERT_DIFFERS(fd, -1) + +#if defined(DEBUG) && !defined(U_LINUX) && !defined(O_TMPFILE) U_INTERNAL_ASSERT_POINTER(path_relativ) U_INTERNAL_DUMP("path_relativ(%u) = %.*S", path_relativ_len, path_relativ_len, path_relativ) +#endif #ifdef U_COVERITY_FALSE_POSITIVE if (fd <= 0) U_RETURN(false); @@ -1229,7 +1334,7 @@ int UFile::setBlocking(int _fd, int flags, bool block) U_INTERNAL_ASSERT_DIFFERS(_fd, -1) - /* ------------------------------------------------------ + /** * #define O_RDONLY 00 * #define O_WRONLY 01 * #define O_RDWR 02 @@ -1302,29 +1407,29 @@ UString UFile::getRealPath(const char* path, bool brelativ) return UString::getStringNull(); } -// ---------------------------------------------------------------------------------------------------------------------- // create a unique temporary file -// ---------------------------------------------------------------------------------------------------------------------- -// char pathname[] = "/tmp/dataXXXXXX" -// The last six characters of template must be XXXXXX and these are replaced with a string that makes the filename unique -// ---------------------------------------------------------------------------------------------------------------------- -bool UFile::mkTemp(char* _template) +bool UFile::mkTemp() { - U_TRACE(1, "UFile::mkTemp(%S)", _template) + U_TRACE(1, "UFile::mkTemp()") -#ifdef O_TMPFILE - fd = U_SYSCALL(open, "%S,%d,%d", "", O_TMPFILE | O_RDWR, PERM_FILE); + /** + * O_TMPFILE is a new open(2)/openat(2) flag that makes easier the creation of secure temporary files. Files opened with the O_TMPFILE + * flag are created but they are not visible in the filesystem. And as soon as they are closed, they get deleted - just as a file you + * would have opened and unlinked + * + * http://kernelnewbies.org/Linux_3.11#head-8be09d59438b31c2a724547838f234cb33c40357 + * + * By default, /tmp on Fedora 18 will be on a tmpfs. Storage of large temporary files should be done in /var/tmp. + * This will reduce the I/O generated on disks, increase SSD lifetime, save power, and improve performance of the /tmp filesystem + */ + +#if defined(U_LINUX) && defined(O_TMPFILE) + fd = U_SYSCALL(open, "%S,%d,%d", "/var/tmp", O_TMPFILE | O_RDWR, PERM_FILE); #else - if (_template) setPath(_template); - else - { - UString path(U_PATH_MAX); + UString path((void*)U_CONSTANT_TO_PARAM("/var/tmp/mapXXXXXX")); - path.snprintf("%s/lockXXXXXX", u_tmpdir); - - setPath(path); - } + setPath(path); U_INTERNAL_DUMP("path_relativ(%u) = %.*S", path_relativ_len, path_relativ_len, path_relativ) @@ -1342,6 +1447,31 @@ bool UFile::mkTemp(char* _template) U_RETURN(false); } +bool UFile::mkTempForLock() +{ + U_TRACE(1, "UFile::mkTempForLock()") + + UString path(U_PATH_MAX); + + path.snprintf("%s/lockXXXXXX", u_tmpdir); // The last six characters of template must be XXXXXX and these are replaced with a string that makes the filename unique + + setPath(path); + + U_INTERNAL_DUMP("path_relativ(%u) = %.*S", path_relativ_len, path_relativ_len, path_relativ) + + fd = U_SYSCALL(mkstemp, "%S", U_PATH_CONV((char*)path_relativ)); + + if (isOpen()) + { + U_ASSERT( lock() && + unlock()) + + U_RETURN(true); + } + + U_RETURN(false); +} + // mkdtemp - create a unique temporary directory bool UFile::mkdtemp(UString& _template) diff --git a/src/ulib/internal/common.cpp b/src/ulib/internal/common.cpp index 67d29f92..eeda8eba 100644 --- a/src/ulib/internal/common.cpp +++ b/src/ulib/internal/common.cpp @@ -40,9 +40,9 @@ void ULib_init_openssl() U_SYSCALL_VOID_NO_PARAM(SSL_load_error_strings); U_SYSCALL_VOID_NO_PARAM(SSL_library_init); -# ifdef HAVE_OPENSSL_97 +# ifdef HAVE_OPENSSL_97 U_SYSCALL_VOID(OPENSSL_config, "%S", 0); -# endif +# endif U_SYSCALL_VOID_NO_PARAM(OpenSSL_add_all_ciphers); U_SYSCALL_VOID_NO_PARAM(OpenSSL_add_all_digests); @@ -50,7 +50,7 @@ void ULib_init_openssl() // the randomness device is used to seed the PRNG transparently. However, on all other systems, the application // is responsible for seeding the PRNG by calling RAND_add(), -# ifdef _MSWINDOWS_ +# ifdef _MSWINDOWS_ U_SYSCALL_VOID(srand, "%ld", u_start_time); // seed with time while (RAND_status() == 0) // Seed PRNG only if needed @@ -61,7 +61,7 @@ void ULib_init_openssl() RAND_seed(&tmp, sizeof(int)); } -# endif +# endif } #endif @@ -107,16 +107,16 @@ void ULib_init() u_err_buffer = (char*) UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(256)); -# ifdef DEBUG +# ifdef DEBUG UMemoryError::pbuffer = (char*) UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(U_MAX_SIZE_PREALLOCATE)); -# endif +# endif #else u_buffer = (char*) U_SYSCALL(malloc, "%u", U_BUFFER_SIZE); u_err_buffer = (char*) U_SYSCALL(malloc, "%u", 256); -# ifdef DEBUG +# ifdef DEBUG UMemoryError::pbuffer = (char*) U_SYSCALL(malloc, "%u", U_MAX_SIZE_PREALLOCATE); -# endif +# endif #endif UString::ptrbuf = @@ -124,9 +124,9 @@ void ULib_init() UFile::cwd_save = (char*)UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(1024)); #if defined(DEBUG) && defined(U_STDCPP_ENABLE) -# ifdef DEBUG +# ifdef DEBUG UMemoryPool::obj_class = UMemoryPool::func_call = 0; -# endif +# endif UObjectIO::init((char*)UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(U_MAX_SIZE_PREALLOCATE)), U_MAX_SIZE_PREALLOCATE); #endif @@ -161,23 +161,21 @@ void ULib_init() U_ERROR("Couldn't find useable Winsock DLL. Must be at least 2.2"); } -# ifdef HAVE_ATEXIT +# ifdef HAVE_ATEXIT (void) U_SYSCALL(atexit, "%p", (vPF)&WSACleanup); -# endif +# endif #endif #if defined(SOLARIS) && (defined(SPARC) || defined(sparc)) && !defined(HAVE_ARCH64) - // make this if there are pointer misalligned - // (because pointers must be always a multiple of 4 (when running 32 bit applications)) - asm("ta 6"); + asm("ta 6"); // make this if there are pointer misalligned (because pointers must be always a multiple of 4 (when running 32 bit applications)) #endif #if defined(DEBUG) && defined(__GNUC__) && defined(U_ENABLE_ALIGNMENT_CHECKING) -# ifdef __i386__ +# ifdef __i386__ __asm__("pushf\norl $0x40000,(%esp)\npopf"); // Enable Alignment Checking on x86 -# elif defined(__x86_64__) +# elif defined(__x86_64__) __asm__("pushf\norl $0x40000,(%rsp)\npopf"); // Enable Alignment Checking on x86_64 -# endif +# endif #endif U_INTERNAL_ASSERT_EQUALS(sizeof(UStringRep), sizeof(ustringrep)) @@ -188,11 +186,12 @@ void ULib_init() U_INTERNAL_DUMP("u_dosmatch = %p u_dosmatch_with_OR = %p u_pfn_match = %p u_pfn_flags = %u", u_dosmatch, u_dosmatch_with_OR, u_pfn_match, u_pfn_flags) -/* NB: there are to many exceptions... -#if defined(_LARGEFILE_SOURCE) && !defined(_MSWINDOWS_) - U_INTERNAL_ASSERT_EQUALS(sizeof(off_t), SIZEOF_OFF_T) -#endif -*/ +/** + * NB: there are to many exceptions... + * #if defined(_LARGEFILE_SOURCE) && !defined(_MSWINDOWS_) + * U_INTERNAL_ASSERT_EQUALS(sizeof(off_t), SIZEOF_OFF_T) + * #endif + */ #ifdef USE_LIBSSL ULib_init_openssl(); diff --git a/src/ulib/internal/memory_pool.cpp b/src/ulib/internal/memory_pool.cpp index 3cf1e930..ac964adc 100644 --- a/src/ulib/internal/memory_pool.cpp +++ b/src/ulib/internal/memory_pool.cpp @@ -178,13 +178,7 @@ public: if (pointer_block < &mem_pointer_block[0] || pointer_block > &mem_pointer_block[U_NUM_STACK_TYPE * U_NUM_ENTRY_MEM_BLOCK * 2]) { - uint32_t size = space * sizeof(void*); - - U_INTERNAL_DUMP("size = %u", size) - - U_INTERNAL_ASSERT_EQUALS(size & U_PAGEMASK, 0) - - UMemoryPool::deallocate(pointer_block, size); + UMemoryPool::deallocate(pointer_block, space * sizeof(void*)); } # endif } @@ -195,12 +189,12 @@ public: U_INTERNAL_ASSERT_MAJOR(index, 0) - // NB: si alloca lo space per numero totale puntatori - // (blocchi allocati precedentemente + un nuovo insieme di blocchi) - // relativi a type 'dimensione' stack corrente... + // NB: si alloca lo space per numero totale puntatori (blocchi allocati precedentemente + un nuovo insieme di blocchi) relativi a type 'dimensione' stack corrente... uint32_t size = new_space * sizeof(void*); - void** new_block = (void**) UFile::mmap(&size, -1, PROT_READ | PROT_WRITE, U_MAP_ANON, 0); + + void** new_block = (void**) UFile::mmap(&size, -1, PROT_READ | PROT_WRITE, MAP_PRIVATE | U_MAP_ANON, 0); + new_space = (size / sizeof(void*)); if (len) U_MEMCPY(new_block, pointer_block, len * sizeof(void*)); @@ -231,7 +225,7 @@ public: { U_INTERNAL_ASSERT_EQUALS(len, 0) - pointer_block = (void**) UFile::mmap(&size, -1, PROT_READ | PROT_WRITE, U_MAP_ANON, 0); + pointer_block = (void**) UFile::mmap(&size, -1, PROT_READ | PROT_WRITE, MAP_PRIVATE | U_MAP_ANON, 0); len = space = (size / type); # if defined(DEBUG) && defined(ENABLE_MEMPOOL) @@ -413,7 +407,7 @@ void UMemoryPool::allocateMemoryBlocks(const char* ptr) U_INTERNAL_ASSERT_POINTER(ptr) -#if defined(ENABLE_MEMPOOL) +#ifdef ENABLE_MEMPOOL int value; void* addr; uint32_t i; @@ -440,7 +434,19 @@ void UMemoryPool::allocateMemoryBlocks(const char* ptr) value = strtol(endptr + 1, &endptr, 10); - if (value) UFile::rlimit_memfree = value; + if (value) + { + UFile::rlimit_memfree = value; + +# if defined(U_LINUX) && MAP_HUGE_2MB + if (value == U_2M) + { + // cat /proc/meminfo | grep Huge + + UFile::nr_hugepages = UFile::setSysParam("/proc/sys/vm/nr_hugepages", U_2M * 64); + } +# endif + } } for (i = 1; i < U_NUM_STACK_TYPE; ++i) @@ -529,9 +535,9 @@ void* UMemoryPool::_malloc(uint32_t num, uint32_t type_size, bool bzero) U_INTERNAL_DUMP("length = %u", length) #if !defined(ENABLE_MEMPOOL) -# ifndef HAVE_ARCH64 +# ifndef HAVE_ARCH64 U_INTERNAL_ASSERT_RANGE(4, length, 1U * 1024U * 1024U * 1024U) // NB: over 1G is very suspect on 32bit... -# endif +# endif ptr = U_SYSCALL(malloc, "%u", length); #else if (length <= U_MAX_SIZE_PREALLOCATE) @@ -543,7 +549,9 @@ void* UMemoryPool::_malloc(uint32_t num, uint32_t type_size, bool bzero) } else { - ptr = UFile::mmap(&length, -1, PROT_READ | PROT_WRITE, U_MAP_ANON, 0); + ptr = UFile::mmap(&length, -1, PROT_READ | PROT_WRITE, MAP_PRIVATE | U_MAP_ANON, 0); + + U_INTERNAL_DUMP("length = %u", length) } #endif @@ -563,23 +571,20 @@ void* UMemoryPool::_malloc(uint32_t* pnum, uint32_t type_size, bool bzero) U_INTERNAL_DUMP("length = %u", length) -#if !defined(ENABLE_MEMPOOL) -# ifndef HAVE_ARCH64 +#ifndef ENABLE_MEMPOOL +# ifndef HAVE_ARCH64 U_INTERNAL_ASSERT_MINOR(length, 1U * 1024U * 1024U * 1024U) // NB: over 1G is very suspect on 32bit... -# endif +# endif ptr = U_SYSCALL(malloc, "%u", length); #else - if (length <= U_MAX_SIZE_PREALLOCATE) + if (length > U_MAX_SIZE_PREALLOCATE) ptr = UFile::mmap(&length, -1, PROT_READ | PROT_WRITE, MAP_PRIVATE | U_MAP_ANON, 0); + else { int stack_index = U_SIZE_TO_STACK_INDEX(length); ptr = pop(stack_index); length = U_STACK_INDEX_TO_SIZE[stack_index]; } - else - { - ptr = UFile::mmap(&length, -1, PROT_READ | PROT_WRITE, U_MAP_ANON, 0); - } *pnum = length / type_size; @@ -604,26 +609,32 @@ void UMemoryPool::deallocate(void* ptr, uint32_t length) UFile::nfree += length; U_INTERNAL_DUMP("UFile::nfree = %u UFile::pfree = %p", UFile::nfree, UFile::pfree) + + return; } - else - { -# ifdef HAVE_ARCH64 - // MADV_DONTNEED causes the kernel to reclaim the indicated pages immediately and drop their contents - (void) U_SYSCALL(madvise, "%p,%lu,%d", (void*)ptr, length, MADV_DONTNEED); -# else - // munmap() is expensive. A series of page table entries must be cleaned up, and the VMA must be unlinked. - // By contrast, madvise(MADV_DONTNEED) only needs to set a flag in the VMA and has the further benefit that - // no system call is required to reallocate the memory. That operation informs the kernel that the pages can - // be (destructively) discarded from memory; if the process tries to access the pages again, they will either - // be faulted in from the underlying file, for a file mapping, or re-created as zero-filled pages, for the - // anonymous mappings that are employed by user-space allocators. Of course, re-creating the pages zero filled - // is normally exactly the desired behavior for a user-space memory allocator. (The only potential downside is - // that process address space is not freed, but this tends not to matter on 64-bit systems) +# if defined(U_LINUX) && defined(HAVE_ARCH64) +# if defined(MAP_HUGE_1GB) || defined(MAP_HUGE_2MB) // (since Linux 3.8) + U_INTERNAL_DUMP("UFile::nr_hugepages = %u", UFile::nr_hugepages) - (void) U_SYSCALL(munmap, "%p,%lu", (void*)ptr, length); + if (UFile::nr_hugepages == 0) // NB: MADV_DONTNEED cannot be applied to locked pages, Huge TLB pages, or VM_PFNMAP pages... # endif - } + { + (void) U_SYSCALL(madvise, "%p,%lu,%d", (void*)ptr, length, MADV_DONTNEED); // MADV_DONTNEED causes the kernel to reclaim the indicated pages immediately and drop their contents + + return; + } +# endif + /** + * munmap() is expensive. A series of page table entries must be cleaned up, and the VMA must be unlinked. By contrast, madvise(MADV_DONTNEED) only needs to set + * a flag in the VMA and has the further benefit that no system call is required to reallocate the memory. That operation informs the kernel that the pages can + * be (destructively) discarded from memory; if the process tries to access the pages again, they will either be faulted in from the underlying file, for a file + * mapping, or re-created as zero-filled pages, for the anonymous mappings that are employed by user-space allocators. Of course, re-creating the pages zero filled + * is normally exactly the desired behavior for a user-space memory allocator. (The only potential downside is that process address space is not freed, but this tends + * not to matter on 64-bit systems) + */ + + (void) U_SYSCALL(munmap, "%p,%lu", (void*)ptr, length); #endif } @@ -639,7 +650,7 @@ void UMemoryPool::_free(void* ptr, uint32_t num, uint32_t type_size) U_INTERNAL_DUMP("length = %u", length) if (length <= U_MAX_SIZE_PREALLOCATE) push(ptr, U_SIZE_TO_STACK_INDEX(length)); - else deallocate(ptr, (length + U_PAGEMASK) & ~U_PAGEMASK); + else deallocate(ptr, UFile::getSizeAligned(length)); #endif } @@ -648,7 +659,7 @@ void UStackMemoryPool::paint(ostream& os) // paint info { U_TRACE(0, "UStackMemoryPool::paint(%p)", &os) -# if defined(ENABLE_MEMPOOL) +# if defined(ENABLE_MEMPOOL) char buffer[256]; uint32_t max_space = 0; UStackMemoryPool* pstack; @@ -737,7 +748,7 @@ void UStackMemoryPool::paint(ostream& os) // paint info os << buffer << endl; */ -# endif +# endif } void UMemoryPool::printInfo(ostream& os) @@ -751,7 +762,7 @@ void UMemoryPool::writeInfoTo(const char* format, ...) { U_TRACE(0+256, "UMemoryPool::writeInfoTo(%S)", format) -# if defined(ENABLE_MEMPOOL) && !defined(_MSWINDOWS_) +# if defined(ENABLE_MEMPOOL) && !defined(_MSWINDOWS_) char name[256]; va_list argp; @@ -766,7 +777,7 @@ void UMemoryPool::writeInfoTo(const char* format, ...) if (!of) return; UStackMemoryPool::paint(of); -# endif +# endif } #endif diff --git a/src/ulib/log.cpp b/src/ulib/log.cpp index f8c0889e..124c6ddc 100644 --- a/src/ulib/log.cpp +++ b/src/ulib/log.cpp @@ -39,6 +39,7 @@ long ULog::tv_sec_old_1; long ULog::tv_sec_old_2; long ULog::tv_sec_old_3; ULog* ULog::pthis; +uint32_t ULog::log_data_sz; const char* ULog::prefix; struct iovec ULog::iov_vec[5]; ULog::log_date ULog::date; @@ -502,11 +503,9 @@ void ULog::setShared(log_data* ptr, uint32_t _size, bool breference) { if (_size == 0) { - log_gzip_sz = sizeof(log_data); + log_data_sz = sizeof(log_data); - uint32_t length = (sizeof(log_data) + U_PAGEMASK) & ~U_PAGEMASK; - - ptr = (log_data*) UFile::mmap(&length); + ptr = (log_data*) UFile::mmap(&log_data_sz); U_INTERNAL_ASSERT_DIFFERS(ptr, MAP_FAILED) } @@ -980,14 +979,7 @@ void ULog::closeLog() UFile::close(); - if (log_gzip_sz == sizeof(log_data)) - { - uint32_t length = (sizeof(log_data) + U_PAGEMASK) & ~U_PAGEMASK; - - U_INTERNAL_ASSERT_EQUALS(length & U_PAGEMASK, 0) - - UFile::munmap(ptr_log_data, length); - } + if (log_gzip_sz == sizeof(log_data)) UFile::munmap(ptr_log_data, log_data_sz); } void ULog::close() diff --git a/src/ulib/net/ipaddress.cpp b/src/ulib/net/ipaddress.cpp index cfe51bc3..2aaeae56 100644 --- a/src/ulib/net/ipaddress.cpp +++ b/src/ulib/net/ipaddress.cpp @@ -904,7 +904,7 @@ bool UIPAllow::getNetworkInterface(UVector& vipallow) family = ifa->ifa_addr->sa_family; -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# ifdef U_LINUX U_INTERNAL_DUMP("%s => family: %d%s", ifa->ifa_name, family, (family == AF_PACKET) ? " (AF_PACKET)" : (family == AF_INET) ? " (AF_INET)" : diff --git a/src/ulib/net/server/server.cpp b/src/ulib/net/server/server.cpp index 8d5be069..da41ed58 100644 --- a/src/ulib/net/server/server.cpp +++ b/src/ulib/net/server/server.cpp @@ -868,7 +868,7 @@ public: } }; -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# ifdef U_LINUX class UTimeThread : public UThread { public: @@ -974,7 +974,7 @@ UOCSPStapling* UServer_Base::pthread_ocsp; #endif #endif -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX static int sysctl_somaxconn, tcp_abort_on_overflow, sysctl_max_syn_backlog, tcp_fin_timeout; #endif @@ -1050,7 +1050,7 @@ UServer_Base::~UServer_Base() } # endif -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# ifdef U_LINUX if (u_pthread_time) { delete (UTimeThread*)u_pthread_time; @@ -1120,7 +1120,7 @@ UServer_Base::~UServer_Base() } #endif -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX if (as_user->empty() && isChild() == false) { @@ -2094,7 +2094,7 @@ void UServer_Base::init() u_need_root(false); -# if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# ifdef U_LINUX /** * timeout_timewait parameter: Determines the time that must elapse before TCP/IP can release a closed connection * and reuse its resources. This interval between closure and release is known as the TIME_WAIT state or twice the @@ -2246,7 +2246,7 @@ void UServer_Base::init() U_INTERNAL_ASSERT_POINTER(ptr_shared_data) U_INTERNAL_ASSERT_DIFFERS(ptr_shared_data, MAP_FAILED) -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) bool bpthread_time = (preforked_num_kids >= 4); // intuitive heuristic... #else bool bpthread_time = false; @@ -2259,7 +2259,7 @@ void UServer_Base::init() #endif ULog::initDate(); -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) if (bpthread_time) { U_INTERNAL_ASSERT_POINTER(ptr_shared_data) @@ -2273,7 +2273,7 @@ void UServer_Base::init() } #endif -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) // NB: we block SIGHUP and SIGTERM; the threads created will inherit a copy of the signal mask... # ifdef sigemptyset sigemptyset(&mask); @@ -2294,7 +2294,7 @@ void UServer_Base::init() flag_loop = true; // NB: UTimeThread loop depend on this setting... -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) if (bpthread_time) { U_INTERNAL_ASSERT_EQUALS(ULog::prwlock, 0) @@ -2552,7 +2552,7 @@ RETSIGTYPE UServer_Base::handlerForSigHUP(int signo) (void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0); -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) if (u_pthread_time) ((UTimeThread*)u_pthread_time)->suspend(); # if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) @@ -2574,7 +2574,7 @@ RETSIGTYPE UServer_Base::handlerForSigHUP(int signo) UInterrupt::insert(SIGTERM, (sighandler_t)UServer_Base::handlerForSigTERM); // async signal #endif -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) if (u_pthread_time) ((UTimeThread*)u_pthread_time)->resume(); # if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) @@ -2601,7 +2601,7 @@ RETSIGTYPE UServer_Base::handlerForSigTERM(int signo) if (proc->parent()) { -# if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +# if defined(U_LINUX) && defined(ENABLE_THREAD) if (u_pthread_time) ((UTimeThread*)u_pthread_time)->suspend(); # endif @@ -3191,7 +3191,7 @@ void UServer_Base::runLoop(const char* user) socket->reusePort(socket_flags); -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX if (bipc == false) { U_ASSERT_EQUALS(socket->isUDP(), false) @@ -3223,7 +3223,7 @@ void UServer_Base::runLoop(const char* user) * NB: Takes an integer value (seconds) */ -# if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && !defined(U_SERVER_CAPTIVE_PORTAL) +# if defined(U_LINUX) && !defined(U_SERVER_CAPTIVE_PORTAL) socket->setTcpFastOpen(); socket->setTcpDeferAccept(); if (bssl == false) socket->setBufferSND(min_size_for_sendfile); @@ -3292,7 +3292,7 @@ void UServer_Base::runLoop(const char* user) # endif #endif -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +#if defined(U_LINUX) && defined(ENABLE_THREAD) (void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_UNBLOCK, &mask, 0); #endif @@ -3493,7 +3493,7 @@ no_monitoring_process: // wait for any children to exit, and then start some more -# if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(ENABLE_THREAD) +# if defined(U_LINUX) && defined(ENABLE_THREAD) (void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_UNBLOCK, &mask, 0); # endif diff --git a/src/ulib/net/socket.cpp b/src/ulib/net/socket.cpp index c92a8273..60f139fd 100644 --- a/src/ulib/net/socket.cpp +++ b/src/ulib/net/socket.cpp @@ -239,7 +239,7 @@ UString USocket::getMacAddress(const char* device) UString result(100U); -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && defined(HAVE_SYS_IOCTL_H) && defined(HAVE_ARPA_INET_H) +#if defined(U_LINUX) && defined(HAVE_SYS_IOCTL_H) && defined(HAVE_ARPA_INET_H) U_INTERNAL_ASSERT(isOpen()) /** @@ -352,7 +352,7 @@ void USocket::setReusePort() * SO_REUSEPORT distributes datagrams evenly across all of the receiving threads */ -#if !defined(U_SERVER_CAPTIVE_PORTAL) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) // && LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0) +#if !defined(U_SERVER_CAPTIVE_PORTAL) && defined(U_LINUX) // && LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0) # ifndef SO_REUSEPORT # define SO_REUSEPORT 15 # endif @@ -389,7 +389,7 @@ void USocket::setTcpKeepAlive() #ifdef SO_KEEPALIVE (void) setSockOpt(SOL_SOCKET, SO_KEEPALIVE, (const int[]){ 1 }, sizeof(int)); -# ifdef __linux__ // Default settings are more or less garbage, with the keepalive time set to 7200 by default on Linux. Modify settings to make the feature actually useful +# ifdef U_LINUX // Default settings are more or less garbage, with the keepalive time set to 7200 by default on Linux. Modify settings to make the feature actually useful (void) setSockOpt(IPPROTO_TCP, TCP_KEEPIDLE, (const int[]){ 15 }, sizeof(int)); // Send first probe after interval @@ -558,7 +558,7 @@ void USocket::reusePort(int _flags) U_CHECK_MEMORY -#if !defined(U_SERVER_CAPTIVE_PORTAL) && (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) +#if !defined(U_SERVER_CAPTIVE_PORTAL) && defined(U_LINUX) U_INTERNAL_DUMP("tcp_reuseport = %b", tcp_reuseport) if (tcp_reuseport) diff --git a/src/ulib/string.cpp b/src/ulib/string.cpp index d94c1c84..dd56e316 100644 --- a/src/ulib/string.cpp +++ b/src/ulib/string.cpp @@ -619,8 +619,13 @@ UStringRep* UStringRep::create(uint32_t length, uint32_t need, const char* ptr) #else if (need > U_CAPACITY) { - _ptr = UFile::mmap(&need, -1, PROT_READ | PROT_WRITE, U_MAP_ANON, 0); + U_INTERNAL_DUMP("UFile::nr_hugepages = %u UFile::rlimit_memfree = %u", UFile::nr_hugepages, UFile::rlimit_memfree) + _ptr = (need >= U_2M && + UFile::nr_hugepages + ? UFile::mmap_anon_huge(&need, MAP_PRIVATE | U_MAP_ANON) + : UFile::mmap(&need, -1, PROT_READ | PROT_WRITE, MAP_PRIVATE | U_MAP_ANON, 0)); + if (_ptr == MAP_FAILED) U_RETURN_POINTER(string_rep_null, UStringRep); r = U_MALLOC_TYPE(UStringRep); @@ -895,12 +900,8 @@ void UStringRep::_release() } else # endif - { - U_INTERNAL_ASSERT_EQUALS(_capacity & U_PAGEMASK, 0) - UMemoryPool::deallocate((void*)str, _capacity); } - } else { ptrdiff_t resto = (ptrdiff_t)str % PAGESIZE; @@ -1236,7 +1237,7 @@ UString::UString(uint32_t len, uint32_t sz, char* ptr) // NB: for UStringExt::de U_TRACE_REGISTER_OBJECT_WITHOUT_CHECK_MEMORY(0, UString, "%u,%u,%p", len, sz, ptr) U_INTERNAL_ASSERT_MAJOR(sz, U_CAPACITY) - U_INTERNAL_ASSERT_EQUALS(sz & U_PAGEMASK, 0) + U_ASSERT(UFile::checkPageAlignment(sz)) rep = U_MALLOC_TYPE(UStringRep); @@ -1371,7 +1372,7 @@ void UString::mmap(const char* map, uint32_t len) rep->_capacity = U_NOT_FOUND; -# if defined(MADV_SEQUENTIAL) +# if defined(U_LINUX) && defined(MADV_SEQUENTIAL) if (len > (64 * PAGESIZE)) (void) U_SYSCALL(madvise, "%p,%u,%d", (void*)map, len, MADV_SEQUENTIAL); # endif } diff --git a/src/ulib/timer.cpp b/src/ulib/timer.cpp index e5ecf574..f5702ae3 100644 --- a/src/ulib/timer.cpp +++ b/src/ulib/timer.cpp @@ -24,7 +24,7 @@ void UTimer::init(Type _mode) if (u_start_time == 0 && u_setStartTime() == false) { - U_ERROR("UTimer::init: system date not updated"); + U_ERROR("UTimer::init(%d): system date not updated", _mode); } mode = _mode; @@ -108,7 +108,7 @@ void UTimer::run() U_INTERNAL_DUMP("u_now = { %ld %6ld } first = %p", u_now->tv_sec, u_now->tv_usec, first) UTimer* item = first; - bool bnosignal = (mode == NOSIGNAL), bexpired; + bool bnosignal = (mode == NOSIGNAL); loop: #ifdef DEBUG @@ -119,10 +119,8 @@ loop: if (item->next) U_INTERNAL_ASSERT(*item <= *(item->next)) #endif - bexpired = (bnosignal ? item->alarm->isExpired() - : item->alarm->isExpiredWithTolerance()); - - if (bexpired) + if (bnosignal ? item->alarm->isExpired() + : item->alarm->isExpiredWithTolerance()) { item = item->next; @@ -154,7 +152,8 @@ void UTimer::setTimer() UInterrupt::timerval.it_value.tv_sec = item->ctime.tv_sec + item->tv_sec - u_now->tv_sec; UInterrupt::timerval.it_value.tv_usec = item->ctime.tv_usec + item->tv_usec - u_now->tv_usec; - UTimeVal::adjust(&(UInterrupt::timerval.it_value.tv_sec), &(UInterrupt::timerval.it_value.tv_usec)); + UTimeVal::adjust(&(UInterrupt::timerval.it_value.tv_sec), + &(UInterrupt::timerval.it_value.tv_usec)); } // NB: it can happen that setitimer() produce immediatly a signal because the interval is very short (< 10ms)... diff --git a/src/ulib/timeval.cpp b/src/ulib/timeval.cpp index 21d12283..2ec4b030 100644 --- a/src/ulib/timeval.cpp +++ b/src/ulib/timeval.cpp @@ -21,7 +21,7 @@ extern "C" { int nanosleep (const struct timespec* requested_time, struct timespec* remaining); } #endif -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__) || defined(_MSWINDOWS_)) && !defined(__suseconds_t_defined) +#if (defined(U_LINUX) || defined(_MSWINDOWS_)) && !defined(__suseconds_t_defined) typedef long suseconds_t; #endif diff --git a/src/ulib/utility/semaphore.cpp b/src/ulib/utility/semaphore.cpp index ec9c414a..e87b8b38 100644 --- a/src/ulib/utility/semaphore.cpp +++ b/src/ulib/utility/semaphore.cpp @@ -16,7 +16,7 @@ #include #include -#if (defined(LINUX) || defined(__LINUX__) || defined(__linux__)) && !defined(__clang__) +#if defined(U_LINUX) && !defined(__clang__) U_DUMP_KERNEL_VERSION(LINUX_VERSION_CODE) #endif @@ -44,7 +44,7 @@ void USemaphore::init(sem_t* ptr, int resource) { U_ERROR_SYSCALL("USemaphore::init() failed"); } -#elif defined(HAVE_SEM_INIT) && ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) +#elif defined(HAVE_SEM_INIT) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) U_INTERNAL_ASSERT_POINTER(ptr) // initialize semaphore object sem to value, share it with other processes @@ -58,7 +58,7 @@ void USemaphore::init(sem_t* ptr, int resource) #else psem = U_NEW(UFile); - if (psem->mkTemp(0) == false) U_ERROR("USemaphore::init(%p,%u) failed", ptr, resource); + if (psem->mkTempForLock() == false) U_ERROR("USemaphore::init(%p,%u) failed", ptr, resource); #endif #if !defined(__MACOSX__) && !defined(__APPLE__) && defined(HAVE_SEM_GETVALUE) @@ -91,11 +91,13 @@ USemaphore::~USemaphore() #if defined(__MACOSX__) || defined(__APPLE__) (void) U_SYSCALL(sem_close, "%p", psem); (void) U_SYSCALL(sem_unlink, "%S", name); -#elif defined(HAVE_SEM_INIT) && ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) +#elif defined(HAVE_SEM_INIT) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) (void) sem_destroy(psem); // Free resources associated with semaphore object sem #elif defined(_MSWINDOWS_) - ::CloseHandle((HANDLE)psem); + (void) ::CloseHandle((HANDLE)psem); #else + (void) (psem->close(), psem->_unlink()); + delete psem; #endif } @@ -117,7 +119,7 @@ void USemaphore::post() #if defined(__MACOSX__) || defined(__APPLE__) (void) U_SYSCALL(sem_post, "%p", psem); // unlock a semaphore -#elif defined(HAVE_SEM_INIT) && ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) +#elif defined(HAVE_SEM_INIT) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) (void) U_SYSCALL(sem_post, "%p", psem); // unlock a semaphore #elif defined(_MSWINDOWS_) ::ReleaseSemaphore((HANDLE)psem, 1, (LPLONG)NULL); @@ -179,7 +181,7 @@ bool USemaphore::wait(time_t timeoutMS) U_INTERNAL_DUMP("value = %d", getValue()) #if defined(__MACOSX__) || defined(__APPLE__) || \ - (defined(HAVE_SEM_INIT) && ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))) + (defined(HAVE_SEM_INIT) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))) // Wait for sem being posted @@ -213,7 +215,7 @@ void USemaphore::lock() #if defined(__MACOSX__) || defined(__APPLE__) (void) U_SYSCALL(sem_wait, "%p", psem); -#elif defined(HAVE_SEM_INIT) && ((!defined(LINUX) && !defined(__LINUX__) && !defined(__linux__)) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) +#elif defined(HAVE_SEM_INIT) && (!defined(U_LINUX) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) /** * sem_wait() decrements (locks) the semaphore pointed to by sem. If the semaphore's value is greater than zero, * then the decrement proceeds, and the function returns, immediately. * If the semaphore currently has the value diff --git a/src/ulib/utility/socket_ext.cpp b/src/ulib/utility/socket_ext.cpp index 6f7ab6fb..0c5778fb 100644 --- a/src/ulib/utility/socket_ext.cpp +++ b/src/ulib/utility/socket_ext.cpp @@ -1138,7 +1138,7 @@ UString USocketExt::getMacAddress(int fd, const char* device) UString result(100U); -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX U_INTERNAL_ASSERT(fd != -1) struct ifreq ifr; @@ -1171,7 +1171,7 @@ UString USocketExt::getIPAddress(int fd, const char* device) UString result(100U); -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX struct ifreq ifr; (void) u__strncpy(ifr.ifr_name, device, IFNAMSIZ-1); @@ -1204,7 +1204,7 @@ UString USocketExt::getNetworkAddress(int fd, const char* device) UString result(100U); -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX struct ifreq ifaddr, ifnetmask; (void) u__strncpy( ifaddr.ifr_name, device, IFNAMSIZ-1); @@ -1326,7 +1326,7 @@ void USocketExt::startResolv(const char* name, int family) } #endif -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX # include # include #endif @@ -1339,7 +1339,7 @@ UString USocketExt::getGatewayAddress(const char* network, uint32_t network_len) // Ex: ip route show to exact 192.168.1.0/24 -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX static int sock; if (sock == 0) sock = USocket::socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); diff --git a/src/ulib/utility/string_ext.cpp b/src/ulib/utility/string_ext.cpp index cf8a93b9..3a25c9c9 100644 --- a/src/ulib/utility/string_ext.cpp +++ b/src/ulib/utility/string_ext.cpp @@ -1414,7 +1414,7 @@ UString UStringExt::deflate(const char* s, uint32_t len, int type) // .gz compre } # endif - sz = (len + U_PAGEMASK) & ~U_PAGEMASK; + sz = UFile::getSizeAligned(len); UString result(len, sz, UFile::pfree); diff --git a/src/ulib/utility/uhttp.cpp b/src/ulib/utility/uhttp.cpp index 3a8ca660..e06850e2 100644 --- a/src/ulib/utility/uhttp.cpp +++ b/src/ulib/utility/uhttp.cpp @@ -54,7 +54,7 @@ #ifdef U_HTTP_INOTIFY_SUPPORT # ifdef SYS_INOTIFY_H_EXISTS_AND_WORKS # include -# elif defined(LINUX) || defined(__LINUX__) || defined(__linux__) +# elif defined(U_LINUX) # ifdef HAVE_SYS_INOTIFY_H # undef HAVE_SYS_INOTIFY_H # endif @@ -1229,7 +1229,7 @@ void UHTTP::init() U_INTERNAL_DUMP("cache size = %u", sz) -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX uint32_t rlim = (sz + UNotifier::max_connection + 100); U_INTERNAL_DUMP("rlim = %u", rlim) @@ -7218,7 +7218,7 @@ U_NO_EXPORT void UHTTP::manageDataForCache() goto end; } -#if defined(LINUX) || defined(__LINUX__) || defined(__linux__) +#ifdef U_LINUX if (rpathname->empty() && // NB: check if we are called from here... (file->lstat(), file->slink())) { diff --git a/tests/.function b/tests/.function index d3ab53e5..a1ebacea 100644 --- a/tests/.function +++ b/tests/.function @@ -17,7 +17,7 @@ UTRACE_SIGNAL="0 30M 0" #VALGRIND=valgrind TZ='CET-1CEST,M3.5.0/2,M10.5.0/3' MUDFLAP_OPTIONS="-ignore-reads -backtrace=8" -UMEMPOOL=802,1025,-30,1512,2052,-12,-10,-26,102:67108864,16384 +UMEMPOOL=0,0,0,0,0,0,0,0,0:20971520,2097152 # core dump # ulimit -c unlimited diff --git a/tests/debug/ok/memerror.ok b/tests/debug/ok/memerror.ok index a878bb2f..5bea8333 100644 --- a/tests/debug/ok/memerror.ok +++ b/tests/debug/ok/memerror.ok @@ -1,21 +1,20 @@ [tid 0]<-- -[tid 32088]--> -test_memerror: WARNING: 28/08/15 15:35:12 (pid 32088) we are going to allocate 64 MB (pid 32088) - address space usage: 130.66 MBytes - rss usage: 8.08 MBytes -{Call main(1,0x7ffccf732938) +[tid 1763]--> +{Call main(1,0x7fff483a07f8) test_memerror: ERROR ON MEMORY ------------------------------------- - pid: 32088 + pid: 1763 file: test_memerror.cpp line: 26 function: UInt::operator int() const - assertion: "((this)->memory.invariant())" [pobj = 0x1762a50 _this = (nil) - FMR] + assertion: "((this)->memory.invariant())" [pobj = 0x23d1e10 _this = (nil) - FMR] ------------------------------------- test_memerror: ERROR ON MEMORY ------------------------------------- - pid: 32088 + pid: 1763 file: ../../include/ulib/debug/error_memory.h line: 28 function: UMemoryError::~UMemoryError() - assertion: "(invariant())" [pobj = 0x7ffccf732020 _this = 0xa1b2c3d000000ff - ABW] + assertion: "(invariant())" [pobj = 0x7fff4839fee0 _this = 0xa1b2c3d000000ff - ABW] ------------------------------------- -}Return main(1,0x7ffccf732938) = 0 +}Return main(1,0x7fff483a07f8) = 0 diff --git a/tests/debug/ok/simerr.ok b/tests/debug/ok/simerr.ok index 513cd933..dc06e89c 100644 --- a/tests/debug/ok/simerr.ok +++ b/tests/debug/ok/simerr.ok @@ -1,11 +1,10 @@ [tid 0]<-- -[tid 32744]--> -test_trace: WARNING: 28/08/15 15:37:35 (pid 32744) we are going to allocate 64 MB (pid 32744) - address space usage: 130.58 MBytes - rss usage: 8.21 MBytes +[tid 1710]--> {Call main(2) {Call routine1(2,3) }Return routine1(2,3) = 6 c = 6 - ::signal(4,0x401660) = (nil) + ::signal(4,0x401800) = (nil) {Call manage_sigpipe(4) ::open("/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp"...,2,438) = -1 - ENOENT (2, No such file or directory) ::open("tmp/prova",66,438) = 5 @@ -13,7 +12,7 @@ test_trace: WARNING: 28/08/15 15:37:35 (pid 32744) we are going to allocate 64 M ::raise(4) = 0 result raise() = 0 test_stat() = 0 - test_stat() = -1 + test_stat() = 0 test_stat() = 0 test_stat() = 0 test_stat() = 0 diff --git a/tests/examples/IR.test b/tests/examples/IR.test index 86d186ee..c613fe04 100755 --- a/tests/examples/IR.test +++ b/tests/examples/IR.test @@ -57,9 +57,12 @@ fi if [ ! -d $DB_DIR ]; then mkdir -p $DB_DIR +#STRACE=$TRUSS +#STRACE=$LTRUSS #export UTRACE="0 50M -1" #export UOBJDUMP="0 5M 1k" start_prg index1 -c index.cfg +#unset STRACE #unset UOBJDUMP UTRACE #exit 0 diff --git a/tests/examples/js/http2.js b/tests/examples/js/http2.js new file mode 100644 index 00000000..3b61fb3a --- /dev/null +++ b/tests/examples/js/http2.js @@ -0,0 +1,20 @@ +

You are currently connected using the protocol: checking....

+

+ diff --git a/tests/ulib/server.test b/tests/ulib/server.test index 4aa8d9b0..2b866058 100755 --- a/tests/ulib/server.test +++ b/tests/ulib/server.test @@ -7,11 +7,13 @@ start_msg server #UTRACE="0 50M 0" -#UTRACE_SIGNAL="0 100M 0" +#UTRACE_SIGNAL="0 10M 0" #UOBJDUMP="0 50M 1000" #USIMERR="error.sim" export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL +UMEMPOOL=0,0,0,0,0,0,0,0,0:20971520,2097152 + if [ "$TERM" != "cygwin" ]; then DIR=../../src/ulib/net/server/plugin/.libs test -d $DIR && diff --git a/tests/ulib/string.test b/tests/ulib/string.test index 58e3539d..4faeccac 100755 --- a/tests/ulib/string.test +++ b/tests/ulib/string.test @@ -6,11 +6,13 @@ start_msg string -#UTRACE="0 50M 0" +#UTRACE="0 50M -1" #UOBJDUMP="0 100k 10" #USIMERR="error.sim" export UTRACE UOBJDUMP USIMERR +UMEMPOOL=0,0,0,0,0,0,0,0,0:20971520,2097152 + start_prg string 10 # Test against expected output diff --git a/tests/ulib/test_file.cpp b/tests/ulib/test_file.cpp index 6d879cfd..400198c0 100644 --- a/tests/ulib/test_file.cpp +++ b/tests/ulib/test_file.cpp @@ -85,6 +85,8 @@ U_EXPORT main (int argc, char* argv[]) x.setPath(tmp); U_ASSERT( x.getPath() == tmp ) + U_ASSERT( x.mkTempForLock() ) + U_ASSERT( x.mkTemp() && (x.close(), x._unlink()) ) #ifndef __MINGW32__ buffer.assign(argv[1]); diff --git a/tests/ulib/test_string.cpp b/tests/ulib/test_string.cpp index c27bf87d..485479f8 100644 --- a/tests/ulib/test_string.cpp +++ b/tests/ulib/test_string.cpp @@ -6,7 +6,7 @@ #include #ifdef __MINGW32__ -#define _GLIBCXX_USE_C99_DYNAMIC 1 +# define _GLIBCXX_USE_C99_DYNAMIC 1 #endif #undef min @@ -1473,6 +1473,47 @@ static void test_stream_09() } #endif +static void check_HugeTLB(char* ptr, uint32_t size) +{ + U_TRACE(5, "check_HugeTLB(%p,%u)", ptr, size) + + for (uint32_t j = 0; j < size; ++j) ptr[j] = 'A'; + for (uint32_t k = 0; k < size; ++k) if (ptr[k] != 'A') U_ERROR("HugeTLB read failed :-( at index %u", k); +} + +void U_EXPORT check_mmap(uint32_t map_size) +{ + U_TRACE(5, "check_mmap(%u)", map_size) + + for (uint32_t i = 0; i < 1; ++i) + { + UString buffer(map_size); + + buffer.size_adjust(U_2M); + + check_HugeTLB(buffer.data(), U_2M); + } + + char* place = UFile::mmap(&map_size); + + check_HugeTLB(place, U_2M); + + for (uint32_t i = 0; i < 21; ++i) + { + UMemoryPool::deallocate(place + i * U_2M, U_2M); + } + + UFile::munmap(place, map_size); + + map_size = U_1G; + + place = UFile::mmap(&map_size); + + check_HugeTLB(place, U_2M); + + UFile::munmap(place, map_size); +} + int U_EXPORT main (int argc, char* argv[]) { @@ -1480,6 +1521,10 @@ U_EXPORT main (int argc, char* argv[]) U_TRACE(5, "main(%d)", argc) + check_mmap(21 * U_2M); + +// return 0; + int year = 0; char sep = 0; UString month(U_CAPACITY); diff --git a/tests/ulib/test_thread.cpp b/tests/ulib/test_thread.cpp index 7d7d8686..6943db2c 100644 --- a/tests/ulib/test_thread.cpp +++ b/tests/ulib/test_thread.cpp @@ -82,7 +82,7 @@ public: if (WaitNValue(2)) // wait for main thread { # ifdef DEBUG - UTrace::suspend(); + u_trace_suspend = 1; # endif while (true) @@ -260,7 +260,7 @@ int U_EXPORT main(int argc, char* argv[]) time_to_sleep = 5000; #ifdef DEBUG - UTrace::resume(); + u_trace_suspend = 0; #endif // Test child thread destroying before father