* shared.cc (shared_info::heap_chunk_size): Store info as megabytes. Search HKEY_LOCAL_MACHINE as well as HKEY_CURRENT_USER. * shared_info.h (shared_info::initial_heap_size): Change element name to reflect new functionality. * strace.cc (strace::hello): Report on initial heap size.
		
			
				
	
	
		
			255 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* shared.cc: shared data area support.
 | |
| 
 | |
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 | |
| 
 | |
| This file is part of Cygwin.
 | |
| 
 | |
| This software is a copyrighted work licensed under the terms of the
 | |
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | |
| details. */
 | |
| 
 | |
| #include "winsup.h"
 | |
| #include <unistd.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <grp.h>
 | |
| #include <pwd.h>
 | |
| #include <errno.h>
 | |
| #include "pinfo.h"
 | |
| #include "security.h"
 | |
| #include "fhandler.h"
 | |
| #include "path.h"
 | |
| #include "dtable.h"
 | |
| #include "cygerrno.h"
 | |
| #include "cygheap.h"
 | |
| #include "heap.h"
 | |
| #include "shared_info_magic.h"
 | |
| #include "registry.h"
 | |
| #include "cygwin_version.h"
 | |
| #include "child_info.h"
 | |
| 
 | |
| shared_info NO_COPY *cygwin_shared;
 | |
| mount_info NO_COPY *mount_table;
 | |
| HANDLE NO_COPY cygwin_mount_h;
 | |
| 
 | |
| char * __stdcall
 | |
| shared_name (const char *str, int num)
 | |
| {
 | |
|   static NO_COPY char buf[MAX_PATH] = {0};
 | |
|   extern bool _cygwin_testing;
 | |
| 
 | |
|   __small_sprintf (buf, "%s.%s.%d", cygwin_version.shared_id, str, num);
 | |
|   if (_cygwin_testing)
 | |
|     strcat (buf, cygwin_version.dll_build_date);
 | |
|   return buf;
 | |
| }
 | |
| 
 | |
| #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)
 | |
| {
 | |
|   void *shared;
 | |
|   static char *offsets[] =
 | |
|   {
 | |
|     (char *) cygwin_shared_address,
 | |
|     (char *) cygwin_shared_address
 | |
|       + pround (sizeof (shared_info)),
 | |
|     (char *) cygwin_shared_address
 | |
|       + pround (sizeof (shared_info))
 | |
|       + pround (sizeof (mount_info)),
 | |
|     (char *) cygwin_shared_address
 | |
|       + pround (sizeof (shared_info))
 | |
|       + pround (sizeof (mount_info))
 | |
|       + pround (sizeof (console_state)),
 | |
|     (char *) cygwin_shared_address
 | |
|       + pround (sizeof (shared_info))
 | |
|       + pround (sizeof (mount_info))
 | |
|       + pround (sizeof (console_state))
 | |
|       + pround (sizeof (_pinfo))
 | |
|   };
 | |
| 
 | |
|   void *addr;
 | |
|   if (!wincap.needs_memory_protection ())
 | |
|     addr = NULL;
 | |
|   else
 | |
|     {
 | |
|       addr = offsets[m];
 | |
|       (void) VirtualFree (addr, 0, MEM_RELEASE);
 | |
|     }
 | |
| 
 | |
|   if (!size)
 | |
|     return addr;
 | |
| 
 | |
|   if (!shared_h)
 | |
|     {
 | |
|       char *mapname;
 | |
|       if (!name)
 | |
| 	mapname = NULL;
 | |
|       else
 | |
| 	{
 | |
| 	  mapname = shared_name (name, n);
 | |
| 	  shared_h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE,
 | |
| 				       TRUE, mapname);
 | |
| 	}
 | |
|       if (!shared_h &&
 | |
| 	  !(shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_all,
 | |
| 					  PAGE_READWRITE, 0, size, mapname)))
 | |
| 	api_fatal ("CreateFileMapping, %E.  Terminating.");
 | |
|     }
 | |
| 
 | |
|   shared = (shared_info *)
 | |
|     MapViewOfFileEx (shared_h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, addr);
 | |
| 
 | |
|   if (!shared)
 | |
|     {
 | |
|       /* Probably win95, so try without specifying the address.  */
 | |
|       shared = (shared_info *) MapViewOfFileEx (shared_h,
 | |
| 				       FILE_MAP_READ|FILE_MAP_WRITE,
 | |
| 				       0, 0, 0, 0);
 | |
|     }
 | |
| 
 | |
|   if (!shared)
 | |
|     api_fatal ("MapViewOfFileEx '%s'(%p), %E.  Terminating.", name, shared_h);
 | |
| 
 | |
|   if (m == SH_CYGWIN_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))
 | |
| 	    continue;  /* oh well */
 | |
| 	  offsets[0] = (char *) shared;
 | |
| 	}
 | |
| 
 | |
|       if (!child_proc_info && wincap.needs_memory_protection ())
 | |
| 	for (DWORD s = 0x950000; s <= 0xa40000; s += 0x1000)
 | |
| 	  VirtualAlloc ((void *) s, 4, MEM_RESERVE, PAGE_NOACCESS);
 | |
|     }
 | |
| 
 | |
|   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;
 | |
| }
 | |
| 
 | |
| void
 | |
| shared_info::initialize ()
 | |
| {
 | |
|   if (version)
 | |
|     {
 | |
|       if (version != SHARED_VERSION_MAGIC)
 | |
| 	multiple_cygwin_problem ("shared", version, SHARED_VERSION);
 | |
|       else if (cb != SHARED_INFO_CB)
 | |
| 	multiple_cygwin_problem ("shared size", cb, SHARED_INFO_CB);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|   /* Initialize the queue of deleted files.  */
 | |
|   delqueue.init ();
 | |
| 
 | |
|   /* Initialize tty table.  */
 | |
|   tty.init ();
 | |
|   version = SHARED_VERSION_MAGIC;
 | |
|   cb = sizeof (*this);
 | |
|   if (cb != SHARED_INFO_CB)
 | |
|     system_printf ("size of shared memory region changed from %u to %u",
 | |
| 		   SHARED_INFO_CB, cb);
 | |
| }
 | |
| 
 | |
| void __stdcall
 | |
| memory_init ()
 | |
| {
 | |
|   getpagesize ();
 | |
|   /* Initialize general shared memory */
 | |
|   HANDLE shared_h = cygheap ? cygheap->shared_h : NULL;
 | |
|   cygwin_shared = (shared_info *) open_shared ("shared",
 | |
| 					       CYGWIN_VERSION_SHARED_DATA,
 | |
| 					       shared_h,
 | |
| 					       sizeof (*cygwin_shared),
 | |
| 					       SH_CYGWIN_SHARED);
 | |
| 
 | |
|   cygwin_shared->initialize ();
 | |
| 
 | |
|   /* Allocate memory for the per-user mount table */
 | |
|   char user_name[UNLEN + 1];
 | |
|   DWORD user_name_len = UNLEN + 1;
 | |
| 
 | |
|   if (!GetUserName (user_name, &user_name_len))
 | |
|     strcpy (user_name, "unknown");
 | |
| 
 | |
|   /* Initialize the Cygwin heap, if necessary */
 | |
|   if (!cygheap)
 | |
|     {
 | |
|       cygheap_init ();
 | |
|       cygheap->user.set_name (user_name);
 | |
|     }
 | |
| 
 | |
|   cygheap->shared_h = shared_h;
 | |
|   ProtectHandleINH (cygheap->shared_h);
 | |
| 
 | |
|   heap_init ();
 | |
| 
 | |
|   mount_table = (mount_info *) open_shared (user_name, MOUNT_VERSION,
 | |
| 					    cygwin_mount_h, sizeof (mount_info),
 | |
| 					    SH_MOUNT_TABLE);
 | |
|   debug_printf ("opening mount table for '%s' at %p", cygheap->user.name (),
 | |
| 		mount_table);
 | |
|   ProtectHandleINH (cygwin_mount_h);
 | |
|   debug_printf ("mount table version %x at %p", mount_table->version, mount_table);
 | |
| 
 | |
|   /* Initialize the Cygwin per-user mount table, if necessary */
 | |
|   if (!mount_table->version)
 | |
|     {
 | |
|       mount_table->version = MOUNT_VERSION_MAGIC;
 | |
|       debug_printf ("initializing mount table");
 | |
|       mount_table->cb = sizeof (*mount_table);
 | |
|       if (mount_table->cb != MOUNT_INFO_CB)
 | |
| 	system_printf ("size of mount table region changed from %u to %u",
 | |
| 		       MOUNT_INFO_CB, mount_table->cb);
 | |
|       mount_table->init ();	/* Initialize the mount table.  */
 | |
|     }
 | |
|   else if (mount_table->version != MOUNT_VERSION_MAGIC)
 | |
|     multiple_cygwin_problem ("mount", mount_table->version, MOUNT_VERSION);
 | |
|   else if (mount_table->cb !=  MOUNT_INFO_CB)
 | |
|     multiple_cygwin_problem ("mount table size", mount_table->cb, MOUNT_INFO_CB);
 | |
| 
 | |
| }
 | |
| 
 | |
| unsigned
 | |
| shared_info::heap_chunk_size ()
 | |
| {
 | |
|   unsigned val;
 | |
|   if (!initial_heap_size)
 | |
|     {
 | |
|       /* Fetch misc. registry entries.  */
 | |
| 
 | |
|       reg_key reg (KEY_READ, NULL);
 | |
| 
 | |
|       /* Note that reserving a huge amount of heap space does not result in
 | |
|       the use of swap since we are not committing it. */
 | |
|       /* 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) {
 | |
| 	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);
 | |
|       }
 | |
| 
 | |
|       if (initial_heap_size < 4)
 | |
| 	initial_heap_size = 4 * 1024 * 1024;
 | |
|       else
 | |
| 	initial_heap_size <<= 20;
 | |
|       debug_printf ("fixed heap size is %u", initial_heap_size);
 | |
|     }
 | |
| 
 | |
|   return initial_heap_size;
 | |
| }
 |