Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:docs:win16:modules:local_heap [2026/02/24 07:40] – [MAKEINTATOM Macro] prokushev | en:docs:win16:modules:local_heap [2026/02/24 08:12] (current) – [References] prokushev | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Win16 Local Heap Functions | + | ===== Local Heap and Atom Table ===== |
| ===== Overview ===== | ===== Overview ===== | ||
| Line 149: | Line 149: | ||
| ===== Heap Operations ===== | ===== Heap Operations ===== | ||
| - | * **Allocation (LocalAlloc)** walks the free list, splitting blocks if necessary, and sets up the appropriate arena. For MOVEABLE blocks, it also allocates a handle table entry. | + | |
| - | * **Compaction (LocalCompact)** coalesces adjacent free blocks and may move or discard unlocked MOVEABLE blocks. When a block is moved, its lhe_address is updated. | + | * **Compaction (LocalCompact)** coalesces adjacent free blocks and may move or discard unlocked MOVEABLE blocks. When a block is moved, its lhe_address is updated. |
| - | * **Locking (LocalLock/ | + | * **Locking (LocalLock/ |
| - | * **Discarding (LocalDiscard)** frees the memory of a MOVEABLE block but keeps the handle entry alive with the LHE_DISCARDED flag set. | + | * **Discarding (LocalDiscard)** frees the memory of a MOVEABLE block but keeps the handle entry alive with the LHE_DISCARDED flag set. |
| ===== Atom Tables ===== | ===== Atom Tables ===== | ||
| Line 199: | Line 199: | ||
| Integer atoms are created by passing a string of the form `"# | Integer atoms are created by passing a string of the form `"# | ||
| - | * **Range**: `0x0001` to `0xBFFF` . | + | |
| - | * **Storage**: | + | * **Storage**: |
| - | * **Reference count**: Not applicable. | + | * **Reference count**: Not applicable. |
| - | * **String representation**: | + | * **String representation**: |
| - | * **Creation**: | + | * **Creation**: |
| **How it works:** When a string of the form '# | **How it works:** When a string of the form '# | ||
| Line 224: | Line 224: | ||
| ==== Local vs. Global Atom Tables ==== | ==== Local vs. Global Atom Tables ==== | ||
| - | * **Local atom tables**: Bound to a specific data segment (e.g., an application' | + | |
| - | * **Global atom table**: A system-wide table accessible to all applications via `GlobalAddAtom`, | + | * **Global atom table**: A system-wide table accessible to all applications via `GlobalAddAtom`, |
| ==== Creating Custom Atom Tables (outside DGROUP) ==== | ==== Creating Custom Atom Tables (outside DGROUP) ==== | ||
| Line 231: | Line 231: | ||
| Since all atom operations work with the current segment pointed to by DS, you can create and use an atom table in any arbitrary data segment by following three steps: | Since all atom operations work with the current segment pointed to by DS, you can create and use an atom table in any arbitrary data segment by following three steps: | ||
| - | 1. **Create a local heap** in the target segment using `LocalInit(Selector, | + | - |
| - | 2. **Switch the DS register** to that segment. | + | |
| - | 3. Call `InitAtomTable(size)` to initialize the atom table in the newly created heap. | + | |
| After that, any subsequent call to `AddAtom`, `FindAtom`, etc., will operate on the custom table if DS is temporarily set to the correct segment. | After that, any subsequent call to `AddAtom`, `FindAtom`, etc., will operate on the custom table if DS is temporarily set to the correct segment. | ||
| Line 261: | Line 261: | ||
| </ | </ | ||
| - | * `wSegment` – Selector of the segment where the heap will be created. | + | |
| - | * `pStart` – Offset of the first byte of the heap area (must be paragraph‑aligned, | + | * `pStart` – Offset of the first byte of the heap area (must be paragraph‑aligned, |
| - | * `pEnd` – Offset of the last byte of the heap area (inclusive). The heap will manage memory from `pStart` to `pEnd`. | + | * `pEnd` – Offset of the last byte of the heap area (inclusive). The heap will manage memory from `pStart` to `pEnd`. |
| If successful, `LocalInit()` returns a non‑zero value. It sets up the `HeapInfo` and `LocalInfo` structures at the beginning of the heap area (starting at `pStart`) and updates the segment’s instance data at offset **06h** (`pLocalHeap`) to point to that `HeapInfo` structure. However, if the segment is not a default data segment (i.e., not DGROUP), the instance data at offset 0 must also contain a zero word to indicate that the NULL segment structure is present; otherwise, the heap may not be recognized by some routines. | If successful, `LocalInit()` returns a non‑zero value. It sets up the `HeapInfo` and `LocalInfo` structures at the beginning of the heap area (starting at `pStart`) and updates the segment’s instance data at offset **06h** (`pLocalHeap`) to point to that `HeapInfo` structure. However, if the segment is not a default data segment (i.e., not DGROUP), the instance data at offset 0 must also contain a zero word to indicate that the NULL segment structure is present; otherwise, the heap may not be recognized by some routines. | ||
| Line 306: | Line 306: | ||
| **Important Considerations: | **Important Considerations: | ||
| - | * The heap structures themselves occupy space at the beginning of the heap area. The first block (sentinel) resides at `pStart + size of (LocalInfo)`. | + | |
| - | * The segment’s instance data (at offset 0) must be properly set up, especially the zero word at offset 0, to avoid confusion with other structures. | + | |
| - | * Custom local heaps are not automatically enlarged if they run out of space; they are limited to the range specified in `LocalInit`. | + | * The segment’s instance data (at offset 0) must be properly set up, especially the zero word at offset 0, to avoid confusion with other structures. |
| - | * The `HEAPSIZE` setting in the module’s .DEF file only affects the default DGROUP heap. | + | * Custom local heaps are not automatically enlarged if they run out of space; they are limited to the range specified in `LocalInit`. |
| + | * The `HEAPSIZE` setting in the module’s .DEF file only affects the default DGROUP heap. | ||
| ==== Creating Atom Tables Outside DGROUP ==== | ==== Creating Atom Tables Outside DGROUP ==== | ||
| Line 317: | Line 318: | ||
| ==== Summary of Custom Heap and Atom Table Creation ==== | ==== Summary of Custom Heap and Atom Table Creation ==== | ||
| - | * Use `LocalInit` on a segment to establish a local heap anywhere in memory. | + | |
| - | * The segment must have a valid NULL segment structure (zero word at offset 0) for the heap to be recognized. | + | * The segment must have a valid NULL segment structure (zero word at offset 0) for the heap to be recognized. |
| - | * After `LocalInit`, | + | * After `LocalInit`, |
| - | * To create an atom table in a custom heap, switch DS to that segment and call `InitAtomTable`. | + | * To create an atom table in a custom heap, switch DS to that segment and call `InitAtomTable`. |
| - | * All subsequent atom operations must be performed with DS set appropriately (or via wrapper functions). | + | * All subsequent atom operations must be performed with DS set appropriately (or via wrapper functions). |
| - | * Custom heaps and atom tables are useful for isolating memory pools, implementing resource managers, or working with large data structures without polluting the default DGROUP. | + | * Custom heaps and atom tables are useful for isolating memory pools, implementing resource managers, or working with large data structures without polluting the default DGROUP. |
| ===== References ===== | ===== References ===== | ||
| - | 1. Schulman, A., Maxey, D., Pietrek, M. // | + | - Schulman, A., Maxey, D., Pietrek, M. // |
| - | 2. Pietrek, M. //Windows Internals// | + | |
| - | 3. Chen, R. //The Old New Thing// (blog). Microsoft Developer Blogs. | + | |
| - | 4. Microsoft OS/2 Version 1.1 Programmer' | + | |




