stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: STD_BAD_ALLOC.cpp test problem on Windows
Date Tue, 19 Jun 2007 03:52:26 GMT
I think this will work.

Just as a side-note (I think you're handling this case safely)
there is a potential problem here since headers aren't checked
for dependencies on config macros and so testing their value
in them is unsafe unless it has been first tested in the .cpp
file that #includes the header. The duplication can lead to
hard to find errors.

So while your changes are safe (AFAICT) I would suggest
a comment just before the #include directive for proclimits.h
mentioning this caveat and a similar one in the header itself.

Martin

Farid Zaripov wrote:
>  > -----Original Message-----
>  > From: Martin Sebor [mailto:sebor@roguewave.com]
>  > Sent: Thursday, June 07, 2007 6:32 PM
>  > To: stdcxx-dev@incubator.apache.org
>  > Subject: Re: STD_BAD_ALLOC.cpp test problem on Windows
>  >
>  > Farid Zaripov wrote:
>  > >> -----Original Message-----
>  > >> From: Martin Sebor [mailto:sebor@roguewave.com]
>  > >> Sent: Wednesday, June 06, 2007 9:45 PM
>  > >> To: stdcxx-dev@incubator.apache.org
>  > >> Subject: Re: STD_BAD_ALLOC.cpp test problem on Windows
>  > >>
>  > >> Still, are you aware of any Windows API that lets programs
>  > limit the
>  > >> amount of dynamic memory available to them, like
>  > >> setrusage() does on UNIX? I ask because allocating so much storage
>  > >> can put a big stress on the system, even if for just a few seconds.
>  > >
>  > >   The process memory (and/or user-mode time) can be limited
>  > using job
>  > > object, but this possibility available on Windows 2000 and
>  > later (not
>  > > available on Windows NT).
>  >
>  > That's better than nothing. Would it be pretty easy to do in the test?
> 
>  The proposed patch is attached.
> 
> Farid.
> 
> 
> ------------------------------------------------------------------------
> 
> Index: etc/config/src/GLOBAL_BAD_ALLOC.cpp
> ===================================================================
> --- etc/config/src/GLOBAL_BAD_ALLOC.cpp	(revision 548260)
> +++ etc/config/src/GLOBAL_BAD_ALLOC.cpp	(working copy)
> @@ -7,9 +7,11 @@
>  #endif   // !_RWSTD_NO_NEW_THROWS && !_RWSTD_NO_NEW_OFLOW_SAFE
>  
>  #ifndef _RWSTD_NO_SETRLIMIT
> -#  include <sys/resource.h>   // for setrlimit()
> +// test for setrlimit() presence before compiling current file
>  #endif
>  
> +#include "proclim.h"
> +
>  #ifndef _RWSTD_NO_HONOR_STD
>  #  ifdef _RWSTD_NO_STD_TERMINATE
>  
> @@ -74,13 +76,8 @@
>  
>  #  else   // if defined (_RWSTD_NO_NEW_OFLOW_SAFE)
>  
> -#ifndef _RWSTD_NO_SETRLIMIT
> +        limit_memory (0);
>  
> -        struct rlimit rl = { 0, 0 };
> -        setrlimit (RLIMIT_DATA, &rl);
> -
> -#endif   // _RWSTD_NO_SETRLIMIT
> -
>          for (unsigned long n = 1UL << (sizeof (long) * 8 - 1);
>               0 != n; n |= (n >> 1)) {
>  
> Index: etc/config/src/NEW_THROWS.cpp
> ===================================================================
> --- etc/config/src/NEW_THROWS.cpp	(revision 548260)
> +++ etc/config/src/NEW_THROWS.cpp	(working copy)
> @@ -5,9 +5,10 @@
>  #include <stdio.h>
>  
>  #ifndef _RWSTD_NO_SETRLIMIT
> -#  include <sys/resource.h>   // for setrlimit()
> +// test for setrlimit() presence before compiling current file
>  #endif   // _RWSTD_NO_SETRLIMIT
>  
> +#include "proclim.h"
>  
>  #if 2 == __GNUG__
>  #  ifndef _RWSTD_NO_HONOR_STD
> @@ -84,16 +85,10 @@
>      // by passing it a smaller argument
>      printf ("#define _RWSTD_NO_NEW_OFLOW_SAFE\n");
>  
> -#ifndef _RWSTD_NO_SETRLIMIT
> -
>      // decrease resource limit to a minimum to induce a failure
>      // without unreasonably stressing the system
> +    limit_memory (0);
>  
> -    struct rlimit rl = { 0, 0 };
> -    setrlimit (RLIMIT_DATA, &rl);
> -
> -#endif   // _RWSTD_NO_SETRLIMIT
> -
>      p = (void*)1;
>  
>      try {
> Index: etc/config/src/proclim.h
> ===================================================================
> --- etc/config/src/proclim.h	(revision 0)
> +++ etc/config/src/proclim.h	(revision 0)
> @@ -0,0 +1,54 @@
> +#if !defined (_RWSTD_NO_SETRLIMIT)
> +
> +#  include <sys/resource.h>   // for setrlimit()
> +
> +void limit_memory (unsigned long limit)
> +{
> +    struct rlimit rl = { limit, limit };
> +    setrlimit (RLIMIT_DATA, &rl);
> +}
> +
> +#elif defined (_WIN32)
> +
> +#  ifndef _WIN32_WINNT
> +#    define _WIN32_WINNT 0x0500
> +#  endif
> +
> +#  if _WIN32_WINNT >= 0x0500
> +
> +// Job Objects available only in Windows 2000 and later
> +
> +#    include <windows.h>
> +
> +void limit_memory (unsigned long limit)
> +{
> +    SYSTEM_INFO info;
> +    GetSystemInfo (&info);
> +
> +    HANDLE hJob = CreateJobObject (NULL, NULL);
> +    if (hJob) {
> +        if (AssignProcessToJobObject (hJob, GetCurrentProcess ())) {
> +            JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = { 0 };
> +            job_info.BasicLimitInformation.LimitFlags =
> +                JOB_OBJECT_LIMIT_PROCESS_MEMORY;
> +            job_info.ProcessMemoryLimit =
> +                limit > info.dwPageSize ? limit : info.dwPageSize;
> +            SetInformationJobObject (hJob,
> +                                     JobObjectExtendedLimitInformation,
> +                                     &job_info, sizeof (job_info));
> +        }
> +        CloseHandle (hJob);
> +    }
> +}
> +
> +#  else   // _WIN32_WINNT < 0x0500
> +
> +void limit_memory (unsigned long) { /* no-op */ }
> +
> +#  endif  // _WIN32_WINNT
> +
> +#else   // _RWSTD_NO_SETRLIMIT && !_WIN32
> +
> +void limit_memory (unsigned long) { /* no-op */ }
> +
> +#endif  // _RWSTD_NO_SETRLIMIT
> 
> Property changes on: etc\config\src\proclim.h
> ___________________________________________________________________
> Name: svn:keywords
>    + Id
> Name: svn:eol-style
>    + native
> 
> Index: etc/config/src/STD_BAD_ALLOC.cpp
> ===================================================================
> --- etc/config/src/STD_BAD_ALLOC.cpp	(revision 548260)
> +++ etc/config/src/STD_BAD_ALLOC.cpp	(working copy)
> @@ -7,9 +7,11 @@
>  #endif   // !_RWSTD_NO_NEW_THROWS && !_RWSTD_NO_NEW_OFLOW_SAFE
>  
>  #ifndef _RWSTD_NO_SETRLIMIT
> -#  include <sys/resource.h>   // for setrlimit()
> +// test for setrlimit() presence before compiling current file
>  #endif
>  
> +#include "proclim.h"
> +
>  #ifndef _RWSTD_NO_HONOR_STD
>  #  ifdef _RWSTD_NO_STD_TERMINATE
>  
> @@ -81,13 +83,8 @@
>  
>  #  else   // if defined (_RWSTD_NO_NEW_OFLOW_SAFE)
>  
> -#ifndef _RWSTD_NO_SETRLIMIT
> +        limit_memory (0);
>  
> -        struct rlimit rl = { 0, 0 };
> -        setrlimit (RLIMIT_DATA, &rl);
> -
> -#endif   // _RWSTD_NO_SETRLIMIT
> -
>          for (unsigned long n = 1UL << (sizeof (long) * 8 - 1);
>               0 != n; n |= (n >> 1)) {
>  


Mime
View raw message