* cygheap.cc (cygheap_fixup_in_child): Use user_heap element in cygheap.
(init_cheap): Ditto for declaration. * fork.cc (fork_parent): Use user_heap element in cygheap. * heap.h (inheap): Ditto. * heap.cc (sbrk): Ditto. (heap_init): Ditto. Reorganize to shrink heap chunk as required and record new value in cygheap. * dcrt0.cc (dll_crt0_1): More "move the cygthread init" games. * shared.cc (open_shared): Rework memory protection to properly deal with relocated shared segment. (shared_info::heap_chunk_size): Rename element to 'heap_chunk'. * shared_info.h (shared_info): Ditto for declaration. * strace.cc (strace::hello): Report on heap chunk size from cygheap since it may shrink.
This commit is contained in:
		
							parent
							
								
									5ec14fe40a
								
							
						
					
					
						commit
						1cc651ecaf
					
				|  | @ -1,3 +1,21 @@ | |||
| 2002-10-22  Christopher Faylor  <cgf@redhat.com> | ||||
| 
 | ||||
| 	* cygheap.cc (cygheap_fixup_in_child): Use user_heap element in | ||||
| 	cygheap. | ||||
| 	(init_cheap): Ditto for declaration. | ||||
| 	* fork.cc (fork_parent): Use user_heap element in cygheap. | ||||
| 	* heap.h (inheap): Ditto. | ||||
| 	* heap.cc (sbrk): Ditto. | ||||
| 	(heap_init): Ditto.  Reorganize to shrink heap chunk as required and | ||||
| 	record new value in cygheap. | ||||
| 	* dcrt0.cc (dll_crt0_1): More "move the cygthread init" games. | ||||
| 	* shared.cc (open_shared): Rework memory protection to properly deal | ||||
| 	with relocated shared segment. | ||||
| 	(shared_info::heap_chunk_size): Rename element to 'heap_chunk'. | ||||
| 	* shared_info.h (shared_info): Ditto for declaration. | ||||
| 	* strace.cc (strace::hello): Report on heap chunk size from cygheap | ||||
| 	since it may shrink. | ||||
| 
 | ||||
| 2002-10-20  Christopher Faylor  <cgf@redhat.com> | ||||
| 
 | ||||
| 	Change _function() to function() throughout. | ||||
|  |  | |||
|  | @ -156,7 +156,7 @@ cygheap_fixup_in_child (bool execed) | |||
| 
 | ||||
|   if (execed) | ||||
|     { | ||||
|       cygheap->heapbase = NULL;		/* We can allocate the heap anywhere */ | ||||
|       cygheap->user_heap.base = NULL;		/* We can allocate the heap anywhere */ | ||||
|       /* Walk the allocated memory chain looking for orphaned memory from
 | ||||
| 	 previous execs */ | ||||
|       for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev) | ||||
|  |  | |||
|  | @ -198,18 +198,21 @@ struct cygheap_debug | |||
| }; | ||||
| #endif | ||||
| 
 | ||||
| struct user_heap_info | ||||
| { | ||||
|   void *base; | ||||
|   void *ptr; | ||||
|   void *top; | ||||
|   unsigned chunk; | ||||
| }; | ||||
| 
 | ||||
| struct init_cygheap | ||||
| { | ||||
|   _cmalloc_entry *chain; | ||||
|   char *buckets[32]; | ||||
|   struct /* User heap stuff. */ | ||||
|     { | ||||
|       void *heapbase; | ||||
|       void *heapptr; | ||||
|       void *heaptop; | ||||
|     }; | ||||
|   cygheap_root root; | ||||
|   cygheap_user user; | ||||
|   user_heap_info user_heap; | ||||
|   mode_t umask; | ||||
|   HANDLE shared_h; | ||||
|   HANDLE console_h; | ||||
|  |  | |||
|  | @ -585,11 +585,11 @@ dll_crt0_1 () | |||
| 	{ | ||||
| 	  case _PROC_FORK: | ||||
| 	    alloc_stack (fork_info); | ||||
| 	    cygthread::init (); | ||||
| 	    cygheap_fixup_in_child (0); | ||||
| 	    close_ppid_handle = !!child_proc_info->pppid_handle; | ||||
| 	    memory_init (); | ||||
| 	    cygthread::init (); | ||||
| 	    set_myself (mypid); | ||||
| 	    close_ppid_handle = !!child_proc_info->pppid_handle; | ||||
| 	    break; | ||||
| 	  case _PROC_SPAWN: | ||||
| 	    /* Have to delay closes until after cygheap is setup */ | ||||
|  |  | |||
|  | @ -261,8 +261,10 @@ release_upto (const char *name, DWORD here) | |||
|       { | ||||
| 	size = mb.RegionSize; | ||||
| 	if (!(mb.State == MEM_RESERVE && mb.AllocationProtect == PAGE_NOACCESS && | ||||
| 	    (((void *) start < cygheap->heapbase || (void *) start > cygheap->heaptop) && | ||||
| 	     ((void *) start < (void *) cygheap || (void *) start > (void *) ((char *) cygheap + CYGHEAPSIZE))))) | ||||
| 	    (((void *) start < cygheap->user_heap.base | ||||
| 	      || (void *) start > cygheap->user_heap.top) && | ||||
| 	     ((void *) start < (void *) cygheap  | ||||
| 	      | (void *) start > (void *) ((char *) cygheap + CYGHEAPSIZE))))) | ||||
| 	  continue; | ||||
| 	if (!VirtualFree ((void *) start, 0, MEM_RELEASE)) | ||||
| 	  api_fatal ("couldn't release memory %p(%d) for '%s' alignment, %E\n", | ||||
|  |  | |||
|  | @ -551,7 +551,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, | |||
|   rc = fork_copy (pi, "user/cygwin data", | ||||
| 		  user_data->data_start, user_data->data_end, | ||||
| 		  user_data->bss_start, user_data->bss_end, | ||||
| 		  cygheap->heapbase, cygheap->heapptr, | ||||
| 		  cygheap->user_heap.base, cygheap->user_heap.ptr, | ||||
| 		  stack_here, ch.stackbottom, | ||||
| 		  dll_data_start, dll_data_end, | ||||
| 		  dll_bss_start, dll_bss_end, NULL); | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ details. */ | |||
| #include "path.h" | ||||
| #include "dtable.h" | ||||
| #include "cygheap.h" | ||||
| #include "registry.h" | ||||
| #include "cygwin_version.h" | ||||
| 
 | ||||
| #define assert(x) | ||||
| 
 | ||||
|  | @ -27,6 +29,8 @@ static unsigned page_const; | |||
| 
 | ||||
| extern "C" size_t getpagesize (); | ||||
| 
 | ||||
| #define MINHEAP_SIZE (4 * 1024 * 1024) | ||||
| 
 | ||||
| /* Initialize the heap at process start up.  */ | ||||
| 
 | ||||
| void | ||||
|  | @ -36,19 +40,40 @@ heap_init () | |||
|      as our parent.  If not, we don't care where it ends up.  */ | ||||
| 
 | ||||
|   page_const = system_info.dwPageSize; | ||||
|   if (cygheap->heapbase) | ||||
|   if (!cygheap->user_heap.base) | ||||
|     { | ||||
|       DWORD chunk = cygwin_shared->heap_chunk_size ();	/* allocation chunk */ | ||||
|       cygheap->user_heap.chunk = cygwin_shared->heap_chunk_size (); | ||||
|       while (cygheap->user_heap.chunk >= MINHEAP_SIZE) | ||||
| 	{ | ||||
| 	  /* Initialize page mask and default heap size.  Preallocate a heap
 | ||||
| 	   * to assure contiguous memory.  */ | ||||
| 	  cygheap->user_heap.ptr = cygheap->user_heap.top = | ||||
| 	  cygheap->user_heap.base = | ||||
| 	    VirtualAlloc (NULL, cygheap->user_heap.chunk, MEM_RESERVE, PAGE_NOACCESS); | ||||
| 	  if (cygheap->user_heap.base) | ||||
| 	    break; | ||||
| 	  cygheap->user_heap.chunk -= 1 * 1024 * 1024; | ||||
| 	} | ||||
|       if (cygheap->user_heap.base == NULL) | ||||
| 	api_fatal ("unable to allocate heap, heap_chunk_size %d, %E", | ||||
| 		   cygheap->user_heap.chunk); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       DWORD chunk = cygheap->user_heap.chunk;	/* allocation chunk */ | ||||
|       /* total size commited in parent */ | ||||
|       DWORD allocsize = (char *) cygheap->heaptop - (char *) cygheap->heapbase; | ||||
|       DWORD allocsize = (char *) cygheap->user_heap.top - | ||||
| 			(char *) cygheap->user_heap.base; | ||||
|       /* round up by chunk size */ | ||||
|       DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk); | ||||
| 
 | ||||
|       /* Loop until we've managed to reserve an adequate amount of memory. */ | ||||
|       char *p; | ||||
| MEMORY_BASIC_INFORMATION m; | ||||
| (void) VirtualQuery (cygheap->user_heap.base, &m, sizeof (m)); | ||||
|       for (;;) | ||||
| 	{ | ||||
| 	  p = (char *) VirtualAlloc (cygheap->heapbase, reserve_size, | ||||
| 	  p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size, | ||||
| 				     MEM_RESERVE, PAGE_READWRITE); | ||||
| 	  if (p) | ||||
| 	    break; | ||||
|  | @ -56,27 +81,25 @@ heap_init () | |||
| 	    break; | ||||
| 	} | ||||
|       if (p == NULL) | ||||
| 	api_fatal ("1. unable to allocate heap %p, heap_chunk_size %d, pid %d, %E", | ||||
| 		   cygheap->heapbase, cygwin_shared->heap_chunk_size (), myself->pid); | ||||
|       if (p != cygheap->heapbase) | ||||
| 	api_fatal ("heap allocated but not at %p", cygheap->heapbase); | ||||
|       if (!VirtualAlloc (cygheap->heapbase, allocsize, MEM_COMMIT, PAGE_READWRITE)) | ||||
| { | ||||
| system_printf ("unable to allocate heap %p, chunk %u, reserve %u, alloc %u, %E", | ||||
| cygheap->user_heap.base, cygheap->user_heap.chunk, | ||||
| reserve_size, allocsize); | ||||
| system_printf ("base %p mem alloc base %p, state %p, size %d, %E", | ||||
| cygheap->user_heap.base, m.AllocationBase, m.State, m.RegionSize); | ||||
| error_start_init ("h:/gdbtest/gdb.exe < con > con"); try_to_debug (); | ||||
| 	api_fatal ("unable to allocate heap %p, chunk %u, reserve %u, alloc %u, %E", | ||||
| 		   cygheap->user_heap.base, cygheap->user_heap.chunk, | ||||
| 		   reserve_size, allocsize); | ||||
| } | ||||
|       if (p != cygheap->user_heap.base) | ||||
| 	api_fatal ("heap allocated but not at %p", cygheap->user_heap.base); | ||||
|       if (!VirtualAlloc (cygheap->user_heap.base, allocsize, MEM_COMMIT, PAGE_READWRITE)) | ||||
| 	api_fatal ("MEM_COMMIT failed, %E"); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* Initialize page mask and default heap size.  Preallocate a heap
 | ||||
|        * to assure contiguous memory.  */ | ||||
|       cygheap->heapptr = cygheap->heaptop = cygheap->heapbase = | ||||
| 	VirtualAlloc (NULL, cygwin_shared->heap_chunk_size (), MEM_RESERVE, | ||||
| 		     PAGE_NOACCESS); | ||||
|       if (cygheap->heapbase == NULL) | ||||
| 	api_fatal ("2. unable to allocate heap, heap_chunk_size %d, %E", | ||||
| 		   cygwin_shared->heap_chunk_size ()); | ||||
|     } | ||||
| 
 | ||||
|   debug_printf ("heap base %p, heap top %p", cygheap->heapbase, | ||||
| 		cygheap->heaptop); | ||||
|   debug_printf ("heap base %p, heap top %p", cygheap->user_heap.base, | ||||
| 		cygheap->user_heap.top); | ||||
|   page_const--; | ||||
|   malloc_init (); | ||||
| } | ||||
|  | @ -93,43 +116,43 @@ sbrk (int n) | |||
|   unsigned commitbytes, newbrksize; | ||||
| 
 | ||||
|   if (n == 0) | ||||
|     return cygheap->heapptr;			/* Just wanted to find current cygheap->heapptr address */ | ||||
|     return cygheap->user_heap.ptr;			/* Just wanted to find current cygheap->user_heap.ptr address */ | ||||
| 
 | ||||
|   newbrk = (char *) cygheap->heapptr + n;	/* Where new cygheap->heapptr will be */ | ||||
|   newbrk = (char *) cygheap->user_heap.ptr + n;	/* Where new cygheap->user_heap.ptr will be */ | ||||
|   newtop = (char *) pround (newbrk);		/* Actual top of allocated memory -
 | ||||
| 						   on page boundary */ | ||||
| 
 | ||||
|   if (newtop == cygheap->heaptop) | ||||
|   if (newtop == cygheap->user_heap.top) | ||||
|     goto good; | ||||
| 
 | ||||
|   if (n < 0) | ||||
|     {						/* Freeing memory */ | ||||
|       assert (newtop < cygheap->heaptop); | ||||
|       n = (char *) cygheap->heaptop - newtop; | ||||
|       assert (newtop < cygheap->user_heap.top); | ||||
|       n = (char *) cygheap->user_heap.top - newtop; | ||||
|       if (VirtualFree (newtop, n, MEM_DECOMMIT)) /* Give it back to OS */ | ||||
| 	goto good;				/*  Didn't take */ | ||||
|       else | ||||
| 	goto err; | ||||
|     } | ||||
| 
 | ||||
|   assert (newtop > cygheap->heaptop); | ||||
|   assert (newtop > cygheap->user_heap.top); | ||||
| 
 | ||||
|   /* Need to grab more pages from the OS.  If this fails it may be because
 | ||||
|    * we have used up previously reserved memory.  Or, we're just plumb out | ||||
|    * of memory.  */ | ||||
|   commitbytes = pround (newtop - (char *) cygheap->heaptop); | ||||
|   if (VirtualAlloc (cygheap->heaptop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL) | ||||
|   commitbytes = pround (newtop - (char *) cygheap->user_heap.top); | ||||
|   if (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL) | ||||
|     goto good; | ||||
| 
 | ||||
|   /* Couldn't allocate memory.  Maybe we can reserve some more.
 | ||||
|      Reserve either the maximum of the standard cygwin_shared->heap_chunk_size () or the requested | ||||
|      amount.  Then attempt to actually allocate it.  */ | ||||
| 
 | ||||
|   if ((newbrksize = cygwin_shared->heap_chunk_size ()) < commitbytes) | ||||
|   if ((newbrksize = cygheap->user_heap.chunk) < commitbytes) | ||||
|     newbrksize = commitbytes; | ||||
| 
 | ||||
|   if ((VirtualAlloc (cygheap->heaptop, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) && | ||||
|       (VirtualAlloc (cygheap->heaptop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)) | ||||
|   if ((VirtualAlloc (cygheap->user_heap.top, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) && | ||||
|       (VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)) | ||||
|     goto good; | ||||
| 
 | ||||
| err: | ||||
|  | @ -137,8 +160,8 @@ err: | |||
|   return (void *) -1; | ||||
| 
 | ||||
| good: | ||||
|   void *oldbrk = cygheap->heapptr; | ||||
|   cygheap->heapptr = newbrk; | ||||
|   cygheap->heaptop = newtop; | ||||
|   void *oldbrk = cygheap->user_heap.ptr; | ||||
|   cygheap->user_heap.ptr = newbrk; | ||||
|   cygheap->user_heap.top = newtop; | ||||
|   return oldbrk; | ||||
| } | ||||
|  |  | |||
|  | @ -15,5 +15,6 @@ void heap_init (); | |||
| void malloc_init (); | ||||
| 
 | ||||
| #define inheap(s) \ | ||||
|   (cygheap->heapptr && s && ((char *) (s) >= (char *) cygheap->heapbase) \ | ||||
|    && ((char *) (s) <= (char *) cygheap->heaptop)) | ||||
|   (cygheap->user_heap.ptr && s \ | ||||
|    && ((char *) (s) >= (char *) cygheap->user_heap.base) \ | ||||
|    && ((char *) (s) <= (char *) cygheap->user_heap.top)) | ||||
|  |  | |||
|  | @ -47,12 +47,8 @@ shared_name (const char *str, int num) | |||
| #define page_const (65535) | ||||
| #define pround(n) (((size_t) (n) + page_const) & ~page_const) | ||||
| 
 | ||||
| void * __stdcall | ||||
| open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m) | ||||
| static char *offsets[] = | ||||
| { | ||||
|   void *shared; | ||||
|   static char *offsets[] = | ||||
|   { | ||||
|   (char *) cygwin_shared_address, | ||||
|   (char *) cygwin_shared_address | ||||
|     + pround (sizeof (shared_info)), | ||||
|  | @ -68,7 +64,12 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat | |||
|     + pround (sizeof (mount_info)) | ||||
|     + pround (sizeof (console_state)) | ||||
|     + pround (sizeof (_pinfo)) | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| void * __stdcall | ||||
| open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m) | ||||
| { | ||||
|   void *shared; | ||||
| 
 | ||||
|   void *addr; | ||||
|   if (!wincap.needs_memory_protection ()) | ||||
|  | @ -117,16 +118,18 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat | |||
|   if (!shared) | ||||
|     api_fatal ("MapViewOfFileEx '%s'(%p), %E.  Terminating.", name, shared_h); | ||||
| 
 | ||||
|   if (m == SH_CYGWIN_SHARED) | ||||
|   if (m == SH_CYGWIN_SHARED && wincap.needs_memory_protection ()) | ||||
|     { | ||||
|       unsigned delta = (char *) shared - offsets[0]; | ||||
|       offsets[0] = (char *) shared; | ||||
|       for (int i = SH_CYGWIN_SHARED + 1; i < SH_TOTAL_SIZE; i++) | ||||
| 	{ | ||||
| 	  offsets[i] += (char *) shared - offsets[0]; | ||||
| 	  if (!VirtualAlloc (offsets[i], offsets[i + 1] - offsets[i], | ||||
| 			     MEM_RESERVE, PAGE_NOACCESS)) | ||||
| 	  unsigned size = offsets[i + 1] - offsets[i]; | ||||
| 	  offsets[i] += delta; | ||||
| 	  if (!VirtualAlloc (offsets[i], size, MEM_RESERVE, PAGE_NOACCESS)) | ||||
| 	    continue;  /* oh well */ | ||||
| 	  offsets[0] = (char *) shared; | ||||
| 	} | ||||
|       offsets[SH_TOTAL_SIZE] += delta; | ||||
| 
 | ||||
| #if 0 | ||||
|       if (!child_proc_info && wincap.needs_memory_protection ()) | ||||
|  | @ -137,9 +140,6 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat | |||
| 
 | ||||
|   debug_printf ("name %s, shared %p (wanted %p), h %p", name, shared, addr, shared_h); | ||||
| 
 | ||||
|   /* FIXME: I couldn't find anywhere in the documentation a note about
 | ||||
|      whether the memory is initialized to zero.  The code assumes it does | ||||
|      and since this part seems to be working, we'll leave it as is.  */ | ||||
|   return shared; | ||||
| } | ||||
| 
 | ||||
|  | @ -229,7 +229,7 @@ memory_init () | |||
| unsigned | ||||
| shared_info::heap_chunk_size () | ||||
| { | ||||
|   if (!initial_heap_size) | ||||
|   if (!heap_chunk) | ||||
|     { | ||||
|       /* Fetch misc. registry entries.  */ | ||||
| 
 | ||||
|  | @ -240,20 +240,20 @@ shared_info::heap_chunk_size () | |||
|       /* FIXME: We should not be restricted to a fixed size heap no matter
 | ||||
|       what the fixed size is. */ | ||||
| 
 | ||||
|       initial_heap_size = reg.get_int ("heap_chunk_in_mb", 0); | ||||
|       if (!initial_heap_size) { | ||||
|       heap_chunk = reg.get_int ("heap_chunk_in_mb", 0); | ||||
|       if (!heap_chunk) { | ||||
| 	reg_key r1 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE", | ||||
| 		    CYGWIN_INFO_CYGNUS_REGISTRY_NAME, | ||||
| 		    CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL); | ||||
|         initial_heap_size = reg.get_int ("heap_chunk_in_mb", 384); | ||||
|         heap_chunk = reg.get_int ("heap_chunk_in_mb", 384); | ||||
|       } | ||||
| 
 | ||||
|       if (initial_heap_size < 4) | ||||
| 	initial_heap_size = 4 * 1024 * 1024; | ||||
|       if (heap_chunk < 4) | ||||
| 	heap_chunk = 4 * 1024 * 1024; | ||||
|       else | ||||
| 	initial_heap_size <<= 20; | ||||
|       debug_printf ("fixed heap size is %u", initial_heap_size); | ||||
| 	heap_chunk <<= 20; | ||||
|       debug_printf ("fixed heap size is %u", heap_chunk); | ||||
|     } | ||||
| 
 | ||||
|   return initial_heap_size; | ||||
|   return heap_chunk; | ||||
| } | ||||
|  |  | |||
|  | @ -138,7 +138,7 @@ public: | |||
| 
 | ||||
| #define SHARED_INFO_CB 47112 | ||||
| 
 | ||||
| #define CURR_SHARED_MAGIC 0xd9e0bc22U | ||||
| #define CURR_SHARED_MAGIC 0x359218a2U | ||||
| 
 | ||||
| /* NOTE: Do not make gratuitous changes to the names or organization of the
 | ||||
|    below class.  The layout is checksummed to determine compatibility between | ||||
|  | @ -148,7 +148,7 @@ class shared_info | |||
|   DWORD version; | ||||
|   DWORD cb; | ||||
|  public: | ||||
|   unsigned initial_heap_size; | ||||
|   unsigned heap_chunk; | ||||
|   DWORD sys_mount_table_counter; | ||||
| 
 | ||||
|   tty_list tty; | ||||
|  |  | |||
|  | @ -14,12 +14,18 @@ details. */ | |||
| #include <wingdi.h> | ||||
| #include <winuser.h> | ||||
| #include <ctype.h> | ||||
| #include <errno.h> | ||||
| #include "pinfo.h" | ||||
| #include "perprocess.h" | ||||
| #include "cygwin_version.h" | ||||
| #include "hires.h" | ||||
| #include "security.h" | ||||
| #include "cygthread.h" | ||||
| #include "shared_info.h" | ||||
| #include "fhandler.h" | ||||
| #include "path.h" | ||||
| #include "dtable.h" | ||||
| #include "cygerrno.h" | ||||
| #include "cygheap.h" | ||||
| 
 | ||||
| #define PROTECT(x) x[sizeof (x)-1] = 0 | ||||
| #define CHECK(x) if (x[sizeof (x)-1] != 0) { small_printf ("array bound exceeded %d\n", __LINE__); ExitProcess (1); } | ||||
|  | @ -58,7 +64,7 @@ strace::hello () | |||
| 	     cygwin_version.api_major, cygwin_version.api_minor); | ||||
|       prntf (1, NULL, "DLL build:    %s", cygwin_version.dll_build_date); | ||||
|       prntf (1, NULL, "OS version:   Windows %s", wincap.osname ()); | ||||
|       prntf (1, NULL, "Heap size:    %u", cygwin_shared->heap_chunk_size ()); | ||||
|       prntf (1, NULL, "Heap size:    %u", cygheap->user_heap.chunk); | ||||
|       prntf (1, NULL, "**********************************************"); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue