mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-27 07:41:28 -08:00
Merge vman design into vm; add designs for vmix and vmw3.
Link to POSIX and Windows documentation from thread-manager design. Copied from Perforce Change: 187357 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
0d75f05cd3
commit
dc314c2100
4 changed files with 130 additions and 20 deletions
|
|
@ -180,7 +180,6 @@ writef_ The WriteF function
|
|||
.. _version-library: version-library
|
||||
.. _version: version
|
||||
.. _vm: vm
|
||||
.. _vman: vman
|
||||
.. _vmo1: vmo1
|
||||
.. _vmso: vmso
|
||||
.. _writef: writef
|
||||
|
|
|
|||
|
|
@ -164,7 +164,10 @@ design.mps.pthreadext_.
|
|||
_`.impl.ix.multi`: Supports multiple threads.
|
||||
|
||||
_`.impl.ix.register`: ``ThreadRegister()`` records the thread id
|
||||
the current thread by calling ``pthread_self()``.
|
||||
the current thread by calling |pthread_self|_.
|
||||
|
||||
.. |pthread_self| replace:: ``pthread_self()``
|
||||
.. _pthread_self: http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html
|
||||
|
||||
_`.impl.ix.register.multi`: Multiply-registered threads are handled
|
||||
specially by the POSIX thread extensions. See
|
||||
|
|
@ -210,27 +213,38 @@ information for the current thread:
|
|||
|
||||
- A ``HANDLE`` to the process, with access flags
|
||||
``THREAD_SUSPEND_RESUME`` and ``THREAD_GET_CONTEXT``. This handle
|
||||
is needed as parameter to ``SuspendThread()`` and
|
||||
``ResumeThread()``.
|
||||
- The result of ``GetCurrentThreadId()``, so that the current thread
|
||||
is needed as parameter to |SuspendThread|_ and
|
||||
|ResumeThread|_.
|
||||
|
||||
- The result of |GetCurrentThreadId|_, so that the current thread
|
||||
may be identified in the ring of threads.
|
||||
|
||||
.. |SuspendThread| replace:: ``SuspendThread()``
|
||||
.. _SuspendThread: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686345.aspx
|
||||
.. |ResumeThread| replace:: ``ResumeThread()``
|
||||
.. _ResumeThread: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685086.aspx
|
||||
.. |GetCurrentThreadId| replace:: ``GetCurrentThreadId()``
|
||||
.. _GetCurrentThreadId: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683183.aspx
|
||||
|
||||
_`.impl.w3.register.multi`: There is no need for any special treatment
|
||||
of multiple threads, because Windows maintains a suspend count that is
|
||||
incremented on ``SuspendThread()`` and decremented on
|
||||
``ResumeThread()``.
|
||||
incremented on |SuspendThread|_ and decremented on
|
||||
|ResumeThread|_.
|
||||
|
||||
_`.impl.w3.suspend`: ``ThreadRingSuspend()`` calls ``SuspendThread()``.
|
||||
_`.impl.w3.suspend`: ``ThreadRingSuspend()`` calls |SuspendThread|_.
|
||||
|
||||
_`.impl.w3.resume`: ``ThreadRingResume()`` calls ``ResumeThread()``.
|
||||
_`.impl.w3.resume`: ``ThreadRingResume()`` calls |ResumeThread|_.
|
||||
|
||||
_`.impl.w3.scan.current`: ``ThreadScan()`` calls ``StackScan()`` if
|
||||
the thread is current. This is because ``GetThreadContext()`` doesn't
|
||||
the thread is current. This is because |GetThreadContext|_ doesn't
|
||||
work on the current thread: the context would not necessarily have the
|
||||
values which were in the saved registers on entry to the MPS.
|
||||
|
||||
.. |GetThreadContext| replace:: ``GetThreadContext()``
|
||||
.. _GetThreadContext: http://msdn.microsoft.com/en-us/library/windows/desktop/ms679362.aspx
|
||||
|
||||
_`.impl.w3.scan.suspended`: Otherwise, ``ThreadScan()`` calls
|
||||
``GetThreadContext()`` to get the root registers and the stack
|
||||
|GetThreadContext|_ to get the root registers and the stack
|
||||
pointer. The thread's registers are dumped into a ``CONTEXT``
|
||||
structure and fixed in memory. The stack pointer is obtained from
|
||||
``CONTEXT.Rsp`` (on IA-32) or ``CONTEXT.Rsp`` (on x86-64) and then the
|
||||
|
|
@ -245,28 +259,39 @@ _`.impl.xc`: In ``thxc.c``.
|
|||
_`.impl.xc.multi`: Supports multiple threads.
|
||||
|
||||
_`.impl.xc.register`: ``ThreadRegister()`` records the Mach port of
|
||||
the current thread by calling ``mach_thread_self()``.
|
||||
the current thread by calling |mach_thread_self|_.
|
||||
|
||||
.. |mach_thread_self| replace:: ``mach_thread_self()``
|
||||
.. _mach_thread_self: http://www.gnu.org/software/hurd/gnumach-doc/Thread-Information.html
|
||||
|
||||
_`.impl.xc.register.multi`: There is no need for any special treatment
|
||||
of multiple threads, because Mach maintains a suspend count that is
|
||||
incremented on ``thread_suspend()`` and decremented on
|
||||
``thread_resume()``.
|
||||
incremented on |thread_suspend|_ and decremented on
|
||||
|thread_resume|_.
|
||||
|
||||
.. |thread_suspend| replace:: ``thread_suspend()``
|
||||
.. _thread_suspend: http://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html
|
||||
.. |thread_resume| replace:: ``thread_resume()``
|
||||
.. _thread_resume: http://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html
|
||||
|
||||
_`.impl.xc.suspend`: ``ThreadRingSuspend()`` calls
|
||||
``thread_suspend()``.
|
||||
|thread_suspend|_.
|
||||
|
||||
_`.impl.xc.resume`: ``ThreadRingResume()`` calls ``thread_resume()``.
|
||||
_`.impl.xc.resume`: ``ThreadRingResume()`` calls |thread_resume|_.
|
||||
|
||||
_`.impl.xc.scan.current`: ``ThreadScan()`` calls ``StackScan()`` if
|
||||
the thread is current.
|
||||
|
||||
_`.impl.xc.scan.suspended`: Otherwise, ``ThreadScan()`` calls
|
||||
``thread_get_state()`` to get the root registers and the stack
|
||||
pointer. The thread's registers are dumped into a ``THREAD_STATE_S``
|
||||
structure and fixed in memory. The stack pointer is obtained from
|
||||
|thread_get_state|_ to get the root registers and the stack pointer.
|
||||
The thread's registers are dumped into a ``THREAD_STATE_S`` structure
|
||||
and fixed in memory. The stack pointer is obtained from
|
||||
``THREAD_STATE_S.__esp`` (on IA-32) or ``THREAD_STATE_S.__rsp`` (on
|
||||
x86-64) and then the stack is scanned.
|
||||
|
||||
.. |thread_get_state| replace:: ``thread_get_state()``
|
||||
.. _thread_get_state: http://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html
|
||||
|
||||
|
||||
Document History
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -229,6 +229,93 @@ mapped into memory by the VM.
|
|||
_`.if.copy`: Copy the VM descriptor from ``src`` to ``dest``.
|
||||
|
||||
|
||||
Implementations
|
||||
---------------
|
||||
|
||||
|
||||
Generic implementation
|
||||
......................
|
||||
|
||||
_`.impl.an`: In ``vman.c``.
|
||||
|
||||
_`.impl.an.page.size`: The generic VM uses a fake page size, given by
|
||||
the constant ``VMAN_PAGE_SIZE`` in ``config.h``.
|
||||
|
||||
_`.impl.an.reserve`: Address space is "reserved" by calling
|
||||
``malloc()``.
|
||||
|
||||
_`.impl.an.release`: Address space is "released" by calling
|
||||
``free()``.
|
||||
|
||||
_`.impl.an.map`: Mapping (and unmapping) just fills the mapped region
|
||||
with copies of ``VMJunkBYTE`` to emulate the erasure of freshly mapped
|
||||
pages by virtual memory systems.
|
||||
|
||||
|
||||
POSIX implementation
|
||||
....................
|
||||
|
||||
_`.impl.ix`: In ``vmix.c``.
|
||||
|
||||
_`.impl.ix.page.size`: The page size is given by ``getpagesize()``.
|
||||
|
||||
_`.impl.ix.reserve`: Address space is reserved by calling |mmap|_,
|
||||
passing ``PROT_NONE`` and ``MAP_PRIVATE | MAP_ANON``.
|
||||
|
||||
.. |mmap| replace:: ``mmap()``
|
||||
.. _mmap: http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html
|
||||
|
||||
_`.impl.ix.anon.trans`: Note that ``MAP_ANON`` ("map anonymous
|
||||
memory not associated with any specific file") is an extension to
|
||||
POSIX, but it is supported by FreeBSD, Linux, and OS X. A work-around
|
||||
that was formerly used on systems lacking ``MAP_ANON`` was to map
|
||||
the file ``/dev/zero``.
|
||||
|
||||
_`.impl.ix.release`: Address space is released by calling |munmap|_.
|
||||
|
||||
.. |munmap| replace:: ``munmap()``
|
||||
.. _munmap: http://pubs.opengroup.org/onlinepubs/9699919799/functions/munmap.html
|
||||
|
||||
_`.impl.ix.map`: Address space is mapped to main memory by calling
|
||||
|mmap|_, passing ``PROT_READ | PROT_WRITE | PROT_EXEC`` and
|
||||
``MAP_ANON | MAP_PRIVATE | MAP_FIXED``.
|
||||
|
||||
_`.impl.ix.unmap`: Address space is unmapped from main memory by
|
||||
calling |mmap|_, passing ``PROT_NONE`` and ``MAP_ANON | MAP_PRIVATE |
|
||||
MAP_FIXED``.
|
||||
|
||||
|
||||
Windows implementation
|
||||
......................
|
||||
|
||||
_`.impl.w3`: In ``vmw3.c``.
|
||||
|
||||
_`.impl.w3.page.size`: The page size is retrieved by calling
|
||||
|GetSystemInfo|_ and consulting ``SYSTEMINFO.dwPageSize``.
|
||||
|
||||
.. |GetSystemInfo| replace:: ``GetSystemInfo()``
|
||||
.. _GetSystemInfo: http://msdn.microsoft.com/en-gb/library/windows/desktop/ms724381.aspx
|
||||
|
||||
_`.impl.w3.reserve`: Address space is reserved by calling
|
||||
|VirtualAlloc|_, passing ``PAGE_NOACCESS``.
|
||||
|
||||
.. |VirtualAlloc| replace:: ``VirtualAlloc()``
|
||||
.. _VirtualAlloc: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887.aspx
|
||||
|
||||
_`.impl.w3.release`: Address space is released by calling
|
||||
|VirtualFree|_, passing ``MEM_RELEASE``.
|
||||
|
||||
.. |VirtualFree| replace:: ``VirtualFree()``
|
||||
.. _VirtualFree: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366892.aspx
|
||||
|
||||
_`.impl.w3.map`: Address space is mapped to main memory by calling
|
||||
|VirtualAlloc|_, passing ``MEM_COMMIT`` and
|
||||
``PAGE_EXECUTE_READWRITE``.
|
||||
|
||||
_`.impl.w3.unmap`: Address space is unmapped from main memory by
|
||||
calling |VirtualFree|_, passing ``MEM_DECOMMIT``.
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
|
|
|
|||
|
|
@ -28,4 +28,3 @@ Design
|
|||
thread-manager
|
||||
type
|
||||
vm
|
||||
vman
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue