mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-07-27 19:10:08 +02:00
55d7b08b7f
1. Fix Garbage Collector to NOT hold its gclock the entire time that it runs. Instead, only hold it for very brief periods when absolutely necessary, and to then release it as soon as possible. 2. The ultimate fix however, was to introduce a new combined Garbage Collector and Dasd Hardener lock that each acquires and holds for the entire time that each of them runs, so as to prevent either of them from running at the same time. I did not bother to figure out where (and with what) the interference between the two was occurring, but simply decided to use the "hammer approach" and prevent them both from running at the same time instead. Besides, neither of them runs for very long. Each usually only runs for less then a second, so any delay in each of their "passes" (cycles) is VERY brief and hardly noticeable.
230 lines
12 KiB
C
230 lines
12 KiB
C
/* CCKD64.H (C) Copyright "Fish" (David B. Trout), 2018-2022 */
|
|
/* CCKD64 dasd struct and type definitions */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
#ifndef _CCKD64_H_
|
|
#define _CCKD64_H_
|
|
|
|
#include "cckd.h" // (need CCKD_MAX_SF, etc)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* IMPORTANT PROGRAMMING NOTE: for whatever reason, base dasd */
|
|
/* image files use a L2_trkoff value of zero in their L1tab entry */
|
|
/* for non-existent tracks, whereas shadow files use a value of -1. */
|
|
/* To ensure we remain 100% compatible with all non-CCKD64 versions */
|
|
/* of Hercules, we MUST enforce this same inconsistent use design. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define CCKD64_NOSIZE ((U64)0)
|
|
#define CCKD64_MAXSIZE ((U64)MAX_OFFSET_T)
|
|
|
|
#define CCKD64_BASE_NO_OFFSET CCKD64_NOSIZE
|
|
#define CCKD64_SHADOW_NO_OFFSET CCKD64_MAXSIZE
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* struct typedefs */
|
|
/*-------------------------------------------------------------------*/
|
|
typedef struct CCKD64_DEVHDR CCKD64_DEVHDR; // Compress device header
|
|
typedef struct CCKD64_L2ENT CCKD64_L2ENT; // Level 2 table entry
|
|
typedef struct CCKD64_FREEBLK CCKD64_FREEBLK; // Free block
|
|
typedef struct CCKD64_IFREEBLK CCKD64_IFREEBLK;// Free block (internal)
|
|
typedef struct CCKD64_EXT CCKD64_EXT; // CCKD Extension block
|
|
typedef struct SPCTAB64 SPCTAB64; // Space table
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Record layouts and sizes */
|
|
/*-------------------------------------------------------------------*/
|
|
#define CKD_R0 CKD_RECHDR /* Record-0 count field */
|
|
#define CKD_EOFREC CKD_RECHDR /* An END-OF-FILE record is \
|
|
a count field with klen \
|
|
of zero and dlen of zero, \
|
|
i.e. a zero length record */
|
|
static
|
|
const CKD_RECHDR CKD_ENDTRK = /* END-OF-TRACK marker is a \
|
|
count field (i.e. record \
|
|
header) consisting of... */ \
|
|
{{0xff,0xff},{0xff,0xff},0xff,0xff,{0xff,0xff}}; /* ...all 0xffs */
|
|
|
|
#define CKD_R0_SIZE ((S64)sizeof(CKD_R0))
|
|
#define CKD_R0_DLEN (8)
|
|
#define CKD_EOF_SIZE ((S64)sizeof(CKD_EOFREC))
|
|
#define CKD_ENDTRK_SIZE ((S64)sizeof(CKD_ENDTRK))
|
|
#define CKD_MIN_TRKSIZE (CKD_TRKHDR_SIZE + CKD_ENDTRK_SIZE)
|
|
#define CKD_NULL_FMT2_DLEN (4096)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Structure definitions for Compressed CCKD64/CFBA64 devices */
|
|
/*-------------------------------------------------------------------*/
|
|
/* NOTE: The num_L1tab, num_L2tab, cyls, cdh_size, cdh_used, */
|
|
/* free_off, free_total, free_largest, free_num, free_imbed, */
|
|
/* and cmp_parm fields are kept in LITTLE endian format. */
|
|
/*-------------------------------------------------------------------*/
|
|
struct CCKD64_DEVHDR /* Compress device header */
|
|
{
|
|
/* 0 */BYTE cdh_vrm[3]; /* Version Release Modifier */
|
|
/* 3 */BYTE cdh_opts; /* Options byte */
|
|
/* 4 */S32 num_L1tab; /* Number of L1tab entries */
|
|
/* 8 */S32 num_L2tab; /* Number of L2tab entries */
|
|
/* 12 */FWORD cdh_cyls; /* CCKD: Cylinders on device
|
|
CFBA: Sectors on device */
|
|
/* 16 */U64 cdh_size; /* File size */
|
|
/* 24 */U64 cdh_used; /* File used */
|
|
/* 32 */U64 free_off; /* Offset to free space */
|
|
/* 40 */U64 free_total; /* Total free space */
|
|
/* 48 */U64 free_largest; /* Largest free space */
|
|
/* 56 */S64 free_num; /* Number free spaces */
|
|
/* 64 */U64 free_imbed; /* Imbedded free space */
|
|
/* 72 */BYTE cdh_nullfmt; /* Null track format */
|
|
/* 73 */BYTE cmp_algo; /* Compression algorithm */
|
|
/* 74 */S16 cmp_parm; /* Compression parameter */
|
|
/* 76 */BYTE resv2[436]; /* Reserved */
|
|
};
|
|
|
|
struct CCKD64_L2ENT { /* Level 2 table entry */
|
|
|
|
/* NOTE: all fields are numeric and always in LITTLE endian format. */
|
|
|
|
U64 L2_trkoff; /* Offset to track image */
|
|
U16 L2_len; /* Track length */
|
|
U16 L2_size; /* Track size (size >= len) */
|
|
U32 L2_pad; /* (padding/reserved) */
|
|
};
|
|
|
|
struct CCKD64_FREEBLK { /* Free block (file) */
|
|
|
|
/* NOTE: all fields are numeric and always in LITTLE endian format. */
|
|
|
|
U64 fb_offnxt; /* Offset to NEXT free blk */
|
|
U64 fb_len; /* Length of THIS free blk */
|
|
};
|
|
|
|
struct CCKD64_IFREEBLK { /* Free block (internal) */
|
|
|
|
/* NOTE: because this control block is an INTERNAL control block */
|
|
/* which does not actually exist in the emulated dasd image file */
|
|
/* (i.e. it is only used internally), all of its fields are always */
|
|
/* in *HOST* endian format (little endian on little endian hosts */
|
|
/* and big endian on big endian hosts). */
|
|
|
|
U64 ifb_offnxt; /* Offset to NEXT free blk */
|
|
U64 ifb_len; /* Length of THIS free blk */
|
|
|
|
int ifb_idxprv; /* Index to prev free blk */
|
|
int ifb_idxnxt; /* Index to next free blk */
|
|
int ifb_pending; /* 1=Free pending (don't use)*/
|
|
int ifb_pad; /* (padding/reserved) */
|
|
};
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* struct sizes, etc. */
|
|
/*-------------------------------------------------------------------*/
|
|
typedef U64 CCKD64_L1ENT; /* Level 1 table entry */
|
|
typedef CCKD64_L1ENT CCKD64_L1TAB[]; /* Level 1 table */
|
|
typedef CCKD64_L2ENT CCKD64_L2TAB[256];/* Level 2 table */
|
|
|
|
#define CCKD_TRACE_SIZE ((S64)sizeof(CCKD_ITRACE))
|
|
#define CCKD64_DEVHDR_SIZE ((S64)sizeof(CCKD64_DEVHDR))
|
|
#define CCKD64_L1ENT_SIZE ((S64)sizeof(CCKD64_L1ENT))
|
|
#define CCKD64_L2ENT_SIZE ((S64)sizeof(CCKD64_L2ENT))
|
|
#define CCKD64_L2TAB_SIZE ((S64)sizeof(CCKD64_L2TAB))
|
|
#define CCKD64_FREEBLK_SIZE ((S64)sizeof(CCKD64_FREEBLK))
|
|
#define CCKD64_IFREEBLK_SIZE ((S64)sizeof(CCKD64_IFREEBLK))
|
|
|
|
#define CCKD64_DEVHDR_POS (CKD_DEVHDR_SIZE)
|
|
#define CCKD64_L1TAB_POS ((CCKD64_DEVHDR_POS)+(CCKD64_DEVHDR_SIZE))
|
|
|
|
#define FBA_SECTOR_SIZE 512
|
|
#define CFBA_BLKS_PER_GRP 120
|
|
#define CFBA_BLKGRP_SIZE (FBA_SECTOR_SIZE * CFBA_BLKS_PER_GRP)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* CCKD Extension Block */
|
|
/*-------------------------------------------------------------------*/
|
|
struct CCKD64_EXT { /* Ext for compressed ckd */
|
|
DEVBLK *devnext; /* cckd device queue */
|
|
|
|
unsigned int ckddasd:1, /* 1=CKD dasd */
|
|
fbadasd:1, /* 1=FBA dasd */
|
|
cckdioact:1, /* 1=Channel program active */
|
|
bufused:1, /* 1=newbuf was used */
|
|
updated:1, /* 1=Update occurred */
|
|
merging:1, /* 1=File merge in progress */
|
|
stopping:1, /* 1=Device is closing */
|
|
notnull:1, /* 1=Device has track images */
|
|
L2ok:1, /* 1=All l2s below bounds */
|
|
sfmerge:1, /* 1=sf-xxxx merge */
|
|
sfforce:1, /* 1=sf-xxxx force */
|
|
needsdh:1; /* 1=written since last harden */
|
|
|
|
int sflevel; /* sfk xxxx level */
|
|
|
|
LOCK filelock; /* File lock */
|
|
LOCK cckdiolock; /* I/O lock */
|
|
COND cckdiocond; /* I/O condition */
|
|
|
|
U64 cckd_maxsize; /* Maximum file size */
|
|
|
|
int cckdwaiters; /* Number I/O waiters */
|
|
int wrpending; /* Number writes pending */
|
|
int ras; /* Number readaheads active */
|
|
int sfn; /* Number active shadow files*/
|
|
|
|
int sfx; /* Active level 2 file index */
|
|
int L1idx; /* Active level 2 table index*/
|
|
CCKD64_L2ENT *L2tab; /* Active level 2 table */
|
|
int L2_active; /* Active level 2 cache entry*/
|
|
U64 L2_bounds; /* L2 tables boundary */
|
|
|
|
int active; /* Active cache entry */
|
|
BYTE *newbuf; /* Uncompressed buffer */
|
|
|
|
CCKD64_IFREEBLK *ifb; /* Internal free space chain */
|
|
int free_count; /* Number of entries in chain*/
|
|
int free_idx1st; /* Index of 1st entry */
|
|
int free_idxlast; /* Index of last entry */
|
|
int free_idxavail; /* Index of available entry */
|
|
unsigned int free_minsize; /* Minimum free space size */
|
|
|
|
int lastsync; /* Time of last sync */
|
|
|
|
int ralkup[CCKD_MAX_RA_SIZE];/* Lookup table */
|
|
|
|
int ratrk; /* Track to readahead */
|
|
unsigned int totreads; /* Total nbr trk reads */
|
|
unsigned int totwrites; /* Total nbr trk writes */
|
|
unsigned int totl2reads; /* Total nbr l2 reads */
|
|
|
|
unsigned int cachehits; /* Cache hits */
|
|
|
|
unsigned int readaheads; /* Number trks read ahead */
|
|
unsigned int switches; /* Number trk switches */
|
|
unsigned int misses; /* Number readahead misses */
|
|
|
|
int fd[CCKD_MAX_SF+1]; /* File descriptors */
|
|
BYTE swapend[CCKD_MAX_SF+1]; /* Swap endian flag */
|
|
BYTE open[CCKD_MAX_SF+1]; /* Open flag */
|
|
int reads[CCKD_MAX_SF+1]; /* Nbr track reads */
|
|
int L2_reads[CCKD_MAX_SF+1];/* Nbr l2 reads */
|
|
int writes[CCKD_MAX_SF+1]; /* Nbr track writes */
|
|
CCKD64_L1ENT *L1tab[CCKD_MAX_SF+1]; /* Level 1 tables */
|
|
CCKD64_DEVHDR cdevhdr[CCKD_MAX_SF+1]; /* cckd device hdr */
|
|
};
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Space table */
|
|
/*-------------------------------------------------------------------*/
|
|
struct SPCTAB64
|
|
{
|
|
BYTE spc_typ; /* Type of space */
|
|
int spc_val; /* Value for space */
|
|
int spc_val2; /* Another value for space */
|
|
U64 spc_off; /* Space offset */
|
|
U64 spc_len; /* Space length */
|
|
U64 spc_siz; /* Space size */
|
|
};
|
|
|
|
#endif // _CCKD64_H_
|