MASTER_OBJECT_SIZE equ 512 LOCALHEAP_SIG EQU 'HL' GLOBALHEAP_SIG EQU 'HG' ife PMODE32 ; Data structure that describes an allocation arena. Both the local ; and global allocators use this structure at the beginning of their ; information structures. ; HeapInfo STRUC hi_check DW ? ; arena check word (non-zero enables heap checking) hi_freeze DW ? ; arena frozen word (non-zero prevents compaction) hi_count DW ? ; #entries in arena hi_first DW ? ; first arena entry (sentinel, always busy) hi_last DW ? ; last arena entry (sentinel, always busy) hi_ncompact DB ? ; #compactions done so far (max of 3) hi_dislevel DB ? ; current discard level hi_distotal DW ? ; total amount discarded so far hi_htable DW ? ; head of handle table list hi_hfree DW ? ; head of free handle table list hi_hdelta DW ? ; #handles to allocate each time hi_hexpand DW ? ; address of near procedure to expand handles for ; this arena hi_pstats DW ? ; address of statistics table or zero HeapInfo ENDS else ; PMODE32 ; Data structure that describes an allocation arena. Both the local ; and global allocators use this structure at the beginning of their ; information structures. ; HeapInfo STRUC hi_check DW ? ; arena check word (non-zero enables heap checking) hi_freeze DW ? ; arena frozen word (non-zero prevents compaction) hi_count DW ? ; #entries in arena hi_first DW ? ; first arena entry (sentinel, always busy) DW ? hi_last DW ? ; last arena entry (sentinel, always busy) DW ? hi_ncompact DB ? ; #compactions done so far (max of 3) hi_dislevel DB ? ; current discard level hi_distotal DD ? ; total amount discarded so far hi_htable DW ? ; head of handle table list hi_hfree DW ? ; head of free handle table list hi_hdelta DW ? ; #handles to allocate each time hi_hexpand DW ? ; address of near procedure to expand handles for ; this arena hi_pstats DW ? ; address of statistics table or zero HeapInfo ENDS phi_first equ dword ptr hi_first phi_last equ dword ptr hi_last endif ; PMODE32 ; Handle table entry. HandleEntry STRUC he_address DW ? ; actual address of object he_flags DB ? ; flags and priority level he_seg_no DB ? ; 0-based segment number for discardable code HandleEntry ENDS he_EMSPID_no equ byte ptr he_seg_no FreeHandleEntry STRUC he_link DW ? he_free DW ? FreeHandleEntry ENDS LocalHandleEntry STRUC lhe_address DW ? ; actual address of object lhe_flags DB ? ; flags and priority level lhe_count DB ? ; lock count LocalHandleEntry ENDS LocalFreeHandleEntry STRUC lhe_link DW ? lhe_free DW ? LocalFreeHandleEntry ENDS he_owner EQU he_address ; Discarded objects contain owner field ; here so we know when to free handle ; table entries of discarded objects. HE_DISCARDABLE EQU 00Fh ; Discard level of this object HE_DISCARDED EQU 040h ; Marks objects that have been discarded. HE_FREEHANDLE EQU 0FFFFh ; Use -1 to mark free handle table entries LHE_DISCARDABLE EQU 00Fh ; Discard level of this object LHE_DISCARDED EQU 040h ; Marks objects that have been discarded. LHE_USERFLAGS EQU 01Fh ; Mask for user setable flags LHE_FREEHANDLE EQU 0FFFFh ; Use -1 to mark free handle table entries HE_ALIGN = 4-1 HE_MASK = NOT HE_ALIGN ; Handles are allocated in blocks of N, where N is the hi_hdelta field ; in the local heap information structure. The last word of each block ; of handles is used to thread the blocks together, allowing all handles ; to be enumerated. The first word of every block is the number of ; handle table entries in the block. Not only does it save us code ; in henum, but it also has the convenient property of placing all ; handle entries on 2 byte boundaries (i.e. 2, 6, 10, 14), since the ; LA_MOVEABLE bit is 02h. Thus the address of the he_address field of ; a handle table entry is also the address of the handle table entry ; itself. HandleTable STRUC ht_count DW ? ; # handletable entries in this block ht_entry DB SIZE HandleEntry DUP (?) HandleTable ENDS LocalHandleTable STRUC lht_count DW ? ; # handletable entries in this block lht_entry DB SIZE LocalHandleEntry DUP (?) LocalHandleTable ENDS ; Local arena objects are kept in a doubly linked list. LocalArena STRUC la_prev DW ? ; previous arena entry (first entry points to self) la_next DW ? ; next arena entry (last entry points to self) la_handle DW ? ; back link to handle table entry LocalArena ENDS la_fixedsize = la_handle ; Fixed arena headers stop here LA_MINBLOCKSIZE = la_fixedsize*4 ;*** This must be larger than LocalArenaFree ; free blocks have these extra items. la_size = la_handle ; size of block (includes header data) LocalArenaFree STRUC DB SIZE LocalArena DUP (?) la_free_prev DW ? ; previous free entry la_free_next DW ? ; next free entry LocalArenaFree ENDS la_freefixedsize = SIZE LocalArenaFree ; Free block header stops here ; Local arena objects are aligned on 4 byte boundaries, leaving the ; low order two bits always zero. LA_ALIGN = 4-1 LA_MASK = NOT LA_ALIGN LA_FREE = 00h LA_BUSY = 01h ; Saved in la_prev field of header errnz ; Flags passed to LocalAlloc (zero is the default case) LA_MOVEABLE EQU 02h ; Saved in la_prev field of header LA_NOCOMPACT EQU 10h LA_ZEROINIT EQU 40h LA_MODIFY EQU 80h ; Data structure that describes the local arena. Allocated as the first ; object in each local heap. _pLocalHeap is a reserved location each ; automatic data segment that contains the pointer to this structure. LocalInfo STRUC DB SIZE HeapInfo DUP (?) li_notify DD ? ; Far proc to call whenever a local block is moved li_lock DW ? ; arena lock word li_extra DW ? ; minimum amount to grow DS by li_minsize DW ? ; minimum size of heap li_sig DW ? ; signature for local heap LocalInfo ENDS ; Notify procedure message codes LN_OUTOFMEM = 0 ; Out of memory - arg1 = #bytes needed LN_MOVE = 1 ; Object moved - arg1 = handle arg2 = old location LN_DISCARD = 2 ; Object discard? - arg1 = handle, arg2 = discard flags ; Returns new discard flags in AX LocalStats STRUC ls_ljoin DW ? ; #calls to ljoin ls_falloc DW ? ; #calls to lalloc with forward search ls_fexamine DW ? ; #arena entries examined by ls_falloc calls ls_fcompact DW ? ; #calls to lcompact by ls_falloc calls ls_ffound DW ? ; #ls_falloc calls that found a block ls_ffoundne DW ? ; #ls_falloc calls that failed to find a block ls_malloc DW ? ; #calls to lalloc with backward search ls_mexamine DW ? ; #arena entries examined by ls_malloc calls ls_mcompact DW ? ; #calls to lcompact by ls_malloc calls ls_mfound DW ? ; #ls_malloc calls that found a block ls_mfoundne DW ? ; #ls_malloc calls that failed to find a block ls_fail DW ? ; #times lalloc failed because unable to grow DS ls_lcompact DW ? ; #calls to lcompact ls_cloop DW ? ; #repeated compacts after discarding ls_cexamine DW ? ; #entries examined in compaction loop ls_cfree DW ? ; #free entries examined in compaction loop ls_cmove DW ? ; #moveable entries moved by compaction LocalStats ENDS IncLocalStat MACRO n if KDEBUG inc ds:[di+SIZE LocalInfo].&n endif ENDM ; Global arena objects are kept in a doubly linked list. ; GlobalArena STRUC ga_count DB ? ; lock count for movable segments ga_owner DW ? ; DOS 2.x 3.x owner field (current task) ga_size DW ? ; DOS 2.x 3.x size, in paragraphs, not incl. header ga_flags DB ? ; 1 byte available for flags ga_prev DW ? ; previous arena entry (first points to self) ga_next DW ? ; next arena entry (last points to self) ga_handle DW ? ; back link to handle table entry ga_lruprev DW ? ; Previous handle in lru chain ga_lrunext DW ? ; Next handle in lru chain GlobalArena ENDS ga_sig = byte ptr ga_count ; DOS =< 3.x signature byte for fixed segs ga_freeprev = word ptr ga_lruprev ; links for free segs ga_freenext = word ptr ga_lrunext ; links for free segs if PMODE32 DEFAULT_ARENA_SIZE equ 8000h ; Initial length of arena array ; ; 32 bit Protect Mode Arena ; GlobalArena32 STRUC pga_next DD ? ; next arena entry (last points to self) pga_prev DD ? ; previous arena entry (first points to self) pga_address DD ? ; 32 bit linear address of memory pga_size DD ? ; 32 bit size in bytes pga_handle DW ? ; back link to handle table entry pga_owner DW ? ; Owner field (current task) pga_count DB ? ; lock count for movable segments pga_pglock DB ? ; # times page locked pga_flags DB ? ; 1 word available for flags pga_selcount DB ? ; Number of selectors allocated pga_lruprev DD ? ; Previous entry in lru chain pga_lrunext DD ? ; Next entry in lru chain GlobalArena32 ENDS .ERRNZ 32-size GlobalArena32 pga_sig = word ptr pga_count pga_freeprev = dword ptr pga_lruprev ; links for free segs pga_freenext = dword ptr pga_lrunext ; links for free segs endif ; PMODE32 GA_SIGNATURE = 04Dh GA_ENDSIG = 05Ah ; there are many special kinds of blocks, marked in the owner word GA_SENTINAL = -1 ; a sentinal block GA_BOGUS_BLOCK = -7 ; a block temporary marked allocated GA_BURGERMASTER = -3 ; the master object GA_NOT_THERE = -4 ; used with EEMS to link out unallocatable ; memory such as the EGA etc. GA_PHANTOM = -5 ; A block that has no EMS banks banked in. GA_WRAITH = -6 ; A block used to hold up partition headers. ; Global arena objects are aligned on 2 para. boundaries, leaving the ; low order bit always zero. GA_ALIGN = 2-1 GA_MASK = NOT GA_ALIGN GA_FIXED = 1 errnz ; Low byte of flags passed to GlobalAlloc (zero is the default case) GA_ALLOCHIGH EQU 01h ; Flag to indicate allocate high GA_MOVEABLE EQU 02h GA_SEGTYPE EQU 0Ch ; These 2 bits stored in he_flags field GA_DGROUP EQU 04h GA_DISCCODE EQU 08h GA_NOCOMPACT EQU 10h GA_NODISCARD EQU 20h GA_ZEROINIT EQU 40h GA_MODIFY EQU 80h GA_NEWEXPANDED EQU 80h ; Use new EMS allocation scheme ; These flags for use by KERNEL only (caller's CS must match) if PMODE GA_INTFLAGS = GA_ALLOCHIGH+GA_SEGTYPE or (GA_CODE_DATA+GA_ALLOC_DOS) shl 8 else GA_INTFLAGS = GA_ALLOCHIGH+GA_SEGTYPE endif ; High byte of flags remembered in handle table (he_flags field) GA_DISCARDABLE EQU 01h ; Boolean flag for global object, not a level. GA_CODE_DATA EQU 02h ; CODE or DATA seg that belongs to a task. ;GA_DGROUP EQU 04h ;GA_DISCCODE EQU 08h GA_ALLOC_LOW EQU 10h ; Alloc in Lower land, overrides GA_ALLOC_EMS GA_SHAREABLE EQU 20h ; Shareable object GA_DDESHARE EQU 20h ; A shared memory object used for DDE. ;HE_DISCARDED EQU 40h ; Marks objects that have been discarded. ;GAH_NOTIFY EQU 40h ife PMODE GA_ALLOC_EMS EQU 80h ; Alloc in EMS land if LIM 4.0 around. else GA_ALLOC_DOS EQU 80h ; Alloc in DOS land if protected mode endif GA_USERFLAGS = GA_SHAREABLE + GA_DISCARDABLE ; Flags stored in the global arena header GAH_PHANTOM EQU 01h ; This block is either a phantom or a wraith GAH_DONT_GROW EQU 02h ; Don't grow this data segment. GAH_DGROUP EQU GA_DGROUP GAH_DISCCODE EQU GA_DISCCODE GAH_NOTIFY EQU 40h ife PMODE GAH_INEMS EQU 80h ; This is out in EMS else GAH_FIXED EQU 80h endif ; Data structure that describes the global arena. Allocated at the end ; of the local heap information structure. DO NOT CHANGE THE ORDER OF ; THE ENTRIES! The alt sequence and normal sequence must match! GlobalInfo STRUC DB SIZE HeapInfo DUP (?) gi_lrulock DW ? ; Lock out access to LRU chain from interrupt level ife PMODE32 gi_lruchain DW ? ; First handle in lru chain (most recently used) else gi_lruchain DD ? ; First handle in lru chain (most recently used) endif gi_lrucount DW ? ; #entries in LRU chain ife PMODE32 gi_reserve DW ? ; #paras to reserve for disc code, 0 => not enabled gi_disfence DW ? ; Fence for discardable code. else gi_reserve DD ? ; #paras to reserve for disc code, 0 => not enabled gi_disfence DD ? ; Fence for discardable code. endif gi_free_count DW ? ; Count of all the free partitions. gi_alt_first DW ? ; first entry in alternate arena gi_alt_last DW ? ; last entry in alternate arena gi_alt_count DW ? ; count of entries in alternate arena gi_alt_lruchain DW ? ; First handle in lru chain (most recently used) gi_alt_lrucount DW ? ; #entries in LRU chain gi_alt_reserve DW ? ; alternate reserve gi_alt_disfence DW ? ; Fence for discardable code. gi_alt_free_count DW ? ; Count of all the free partitions. gi_alt_pPhantom DW ? ; Pointer to the first pPhantom block. gi_disfence_hi DW ? ; High word of fence gi_flags DW ? ; some flags! !!! should merge with freeze and check GlobalInfo ENDS gi_cmpflags = byte ptr hi_dislevel ; Flags to control gcompact gi_disfence_lo = word ptr gi_disfence GIF_INT2 EQU 01h CMP_FLAGS EQU GA_NODISCARD or GA_NOCOMPACT or GA_DISCCODE BOOT_COMPACT EQU 80h COMPACT_ALLOC EQU 40h ; Fast abort in gcompact for allocations ; Notify procedure message codes GN_MOVE = 1 ; Object moved - arg1 = handle arg2 = old location GN_DISCARD = 2 ; Object discard? - arg1 = handle, arg2 = discard flags ; Returns new discard flags in AX SASTRUC STRUC sa_size dw 0 ; size, in bytes, of the alias list sa_allocated dw 0 ; number of allocated entries SASTRUC ENDS SAENTRY STRUC sae_sel dw 0 ; selector of the object sae_alias dw 0 ; alias of the object SAENTRY ENDS fhCacheLen = 14 ; Number of file handles cached ife PMODE CMLEN = 10 ; Number of entries in Cache Map NewEMSLEN = 20 ; Number of entries in EMM Map free_map struc ; Free Map Description fm_start dw ? ; List of used entries fm_free dw ? ; List of free entries fm_compact dw ? ; Routine to compact this map fm_align dw 0 ; Alignment == pagesize - 1 free_map ends fme struc ; Free map entry structure fme_next dw 0 ; Link to next entry fme_start dw ? ; Start of this free block fme_len dw ? ; Length of this block fme ends endif ; PMODE FIRST_HMA_SEG = 0FFF9h ; Segment used to access HMA fhCacheStruc struc Cachefh dw ? ; File handle CacheExe dw ? ; Exe handle fhCacheStruc ends ; NAMETBL is a structure defining a private resource called a name table. ; It is a resource that maps string resource types and names into unique ; ordinal ids - this way all resources identified by name or type with ; a string can actually be loaded by id. This is for OS/2 compatibility ; with named resources. ; ; typedef struct nametbl { /* ntbl */ ; int cbEntry; /* size of structure */ ; int idType; /* type id or string replc if (idType & RSORDID) */ ; int idName; /* name id or string replc if (idName & RSORDID) */ ; char achTypeName[1]; /* 0 term type followed by 0 term name */ ; } NAMETBL; ntbl struc ntbl_cbEntry dw ? ntbl_idType dw ? ntbl_idName dw ? ntbl_achTypeName db ? ntbl ends RT_NAMETABLE equ 15