⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 how-cygheap-works.txt

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 TXT
字号:
Copyright 2001 Red Hat Inc., Christopher FaylorCygwin has recently adopted something called the "cygwin heap".  This isan internal heap that is inherited by forked/execed children.  Itconsists of process specific information that should be inherited.  Sothings like the file descriptor table, the current working directory,and the chroot value live there.The cygheap is also used to pass argv information to a child process.There is a problem here, though.  If you allocate space for argv on theheap and then exec a process the child process (1) will happily use thespace in the heap.  But what happens when that process execs anotherprocess (2)?  The space used by child process (1) still is being used inchild process (2) but it is basically just a memory leak.To rectify this problem, memory used by child process 1 is tagged insuch a way that child process 2 will know to delete it.  This is incygheap_fixup_in_child.The cygheap memory allocation functions are adapted from memoryallocators developed by DJ Delorie.  They are similar to early BSDmalloc and are intended to be relatively lightweight and relativelyfast.How is the cygheap propagated to the child?Well, it depends if you are running on Windows 9x or Windows NT.On NT and 9x, just before CreateProcess is about to be called infork or exec, a shared memory region is prepared for copying of thecygwin heap.  This is in cygheap_setup_for_child.  The handle to thisshared memory region is passed to the new process in the 'child_info'structure.If there are no handles that need "fixing up" prior to starting anotherprocess, cygheap_setup_for_child will also copy the contents of thecygwin heap to the shared memory region.If there are any handles that need "fixing up" prior to invokinganother process (i.e., sockets) then the creation of the sharedmemory region and copying of the current cygwin heap is a twostep process.First the shared memory region is created and the process is startedin a "CREATE_SUSPENDED" state, inheriting the handle.  After theprocess is created, the fixup_before_*() functions are called.  Theseset information in the heap and duplicate handles in the child, essentiallyensuring that the child's fd table is correct.(Note that it is vital that the cygwin heap should not grow during thisprocess.  Currently, there is no guard against this happening so thisoperation is not thread safe.)Meanwhile, back in fork_parent, the functioncygheap_setup_for_child_cleanup is called.  In the simple "one step"case above, all that happens is that the shared memory is ummapped andthe handle referring to it is closed.In the two step process, the cygheap is now copied to the shared memoryregion, complete with new fdtab info (the child process will see theupdated information as soon as it starts).  Then the memory is unmapped,the handle is closed, and upon return the child process is started.It is in the child process that the difference between Windows 9x andWindows NT becomes evident.Under Windows NT, the operation is simple.  The shared memory handle isused to map the information that the parent has set up into the cygheaplocation in the child.  This means that the child has a copy of thecygwin heap existing in "shared memory" but the only process with a viewto this "shared memory" is the child.Under Windows 9x, due to address limitations, we can't just map theshared memory region into the cygheap position.  So, instead, the memoryis mapped whereever Windows wants to put it, a new heap region isallocated at the same place as in the parent, the contents of the sharedmemory is *copied* to the new heap, and the shared memory is unmapped.Simple, huh?Why do we go to these contortions?  Previous versions (<1.3.3) of cygwinused to block when creating a child so that the child could copy theparent's cygheap.  The problem with this was that when a cygwin processinvoked a non-cygwin child, it would block forever waiting for the childto let it know that it was done copying the heap.  That causedunderstandable complaints from people who wanted to run non-cygwinapplications "in the background".In Cygwin 1.3.3 (and presumably beyond) the location of the cygwin heaphas been fixed to be at the end of the cygwin1.dll address space.Previously, we let the "OS" choose where to allocate the cygwin heap inthe initial cygwin process and attempted to use this same location insubsequent cygwin processes started from this parent.The reason for putting cygheap at a fixed, known location is that weneed to put this information at a fixed location since it incorporatespointers to entities within itself.  So, when a process forks or execs,the memory referred to by the pointers has to exist at the same place inboth the parent or the child.(It "might be nice" to used something like Microsoft's "based pointers"for the cygheap.  Unfortunately gcc does not support that feature, as ofthis writing.)The reason for choosing a fixed, arbitrary location is to accommodateWindows XP, although there were sporadic complaints of cygwin heapfailures in other pathological situations with both NT and 9x.  InWindows XP, Microsoft made the allocation of memory less deterministic.This is certainly their right.  Cygwin was previously relying onundocumented and "iffy" behavior before.  So, now we always allocatespace immediately after the dll in the theory that there is not goingto be anything else living there.Recent (2001-09-20) cygwin email threads have indicated that we're notexactly on completely firm ground now, though.  We are assuming thatthere is sufficient space after the cygwin DLL for the allocation of thecygwin heap.  Unfortunately the ld option '--enable-auto-image-base'has a tendency to allocate DLLs immediately after cygwin1.dll.  Thiscauses the dreaded "Couldn't reserve space for cygwin's heap" message.Solutions for this behavior are currently in the musing state.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -