0N/A * reserved comment block 0N/A * DO NOT REMOVE OR ALTER! 0N/A * Copyright (C) 1991-1997, Thomas G. Lane. 0N/A * This file is part of the Independent JPEG Group's software. 0N/A * For conditions of distribution and use, see the accompanying README file. 0N/A * This file contains the JPEG system-independent memory management 0N/A * routines. This code is usable across a wide variety of machines; most 0N/A * of the system dependencies have been isolated in a separate file. 0N/A * The major functions provided here are: 0N/A * * pool-based allocation and freeing of memory; 0N/A * * policy decisions about how to divide available memory among the 0N/A * * control logic for swapping virtual arrays between main memory and 0N/A * The separate system-dependent file provides the actual backing-storage 0N/A * access code, and it contains the policy decision about how much total 0N/A * main memory to use. 0N/A * This file is system-dependent in the sense that some of its functions 0N/A * are unnecessary in some systems. For example, if there is enough virtual 0N/A * memory so that backing storage will never be used, much of the virtual 0N/A * array control logic could be removed. (Of course, if you have that much 0N/A * memory then you shouldn't care about a little bit of unused code...) 0N/A#
include "jmemsys.h" /* import the system-dependent declarations */ 0N/A * Some important notes: 0N/A * The allocation routines provided here must never return NULL. 0N/A * They should exit to error_exit if unsuccessful. 0N/A * It's not a good idea to try to merge the sarray and barray routines, 0N/A * even though they are textually almost the same, because samples are 0N/A * usually stored as bytes while coefficients are shorts or ints. Thus, 0N/A * in machines where byte pointers have a different representation from 0N/A * word pointers, the resulting machine code could not be the same. 0N/A * Many machines require storage alignment: longs must start on 4-byte 0N/A * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() 0N/A * always returns pointers that are multiples of the worst-case alignment 0N/A * requirement, and we had better do so too. 0N/A * There isn't any really portable way to determine the worst-case alignment 0N/A * requirement. This module assumes that the alignment requirement is 0N/A * multiples of sizeof(ALIGN_TYPE). 0N/A * By default, we define ALIGN_TYPE as double. This is necessary on some 0N/A * workstations (where doubles really do need 8-byte alignment) and will work 0N/A * fine on nearly everything. If your machine has lesser alignment needs, 0N/A * you can save a few bytes by making ALIGN_TYPE smaller. 0N/A * The only place I know of where this will NOT work is certain Macintosh 0N/A * 680x0 compilers that define double as a 10-byte IEEE extended float. 0N/A * Doing 10-byte alignment is counterproductive because longwords won't be 0N/A * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have 0N/A * We allocate objects from "pools", where each pool is gotten with a single 0N/A * request to jpeg_get_small() or jpeg_get_large(). There is no per-object 0N/A * overhead within a pool, except for alignment padding. Each pool has a 0N/A * header with a link to the next pool of the same class. 0N/A * Small and large pool headers are identical except that the latter's 0N/A * link pointer must be FAR on 80x86 machines. 0N/A * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE 0N/A * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple 0N/A * of the alignment requirement of ALIGN_TYPE. 0N/A * Here is the full definition of a memory manager object. 0N/A /* Each pool identifier (lifetime class) names a linked list of pools. */ 0N/A /* Since we only have one lifetime class of virtual arrays, only one 0N/A * linked list is necessary (for each datatype). Note that the virtual 0N/A * array control blocks being linked together are actually stored somewhere 0N/A * in the small-pool list. 0N/A /* alloc_sarray and alloc_barray set this value for use by virtual 0N/A * The control blocks for virtual arrays. 0N/A * Note that these blocks are allocated in the "small" pool area. 0N/A * System-dependent info for the associated backing store (if any) is hidden 0N/A * inside the backing_store_info struct. 0N/A /* Since this is only a debugging stub, we can cheat a little by using 0N/A * fprintf directly rather than going through the trace message code. 0N/A * This is helpful because message parm array can't handle longs. 0N/A#
endif /* MEM_STATS */ 0N/A/* Report an out-of-memory error and stop execution */ 0N/A/* If we compiled MEM_STATS support, report alloc requests before dying */ 0N/A * Allocation of "small" objects. 0N/A * For these, we use pooled storage. When a new pool must be created, 0N/A * we try to get enough space for the current request plus a "slop" factor, 0N/A * where the slop will be the amount of leftover space in the new pool. 0N/A * The speed vs. space tradeoff is largely determined by the slop values. 0N/A * A different slop value is provided for each pool class (lifetime), 0N/A * and we also distinguish the first pool of a class from later ones. 0N/A * NOTE: the values given work fairly well on both 16- and 32-bit-int 0N/A * machines, but may be too small if longs are 64 bits or more. 0N/A 1600,
/* first PERMANENT pool */ 0N/A 16000 /* first IMAGE pool */ 0N/A 0,
/* additional PERMANENT pools */ 0N/A 5000 /* additional IMAGE pools */ 0N/A#
define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ 0N/A/* Allocate a "small" object */ 0N/A /* Check for unsatisfiable request (do now to ensure no overflow below) */ 0N/A /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ 0N/A /* See if space is available in any existing pool */ 0N/A break;
/* found pool with enough space */ 0N/A /* Time to make a new pool? */ 0N/A /* min_request is what we need now, slop is what will be leftover */ 0N/A /* Don't ask for more than MAX_ALLOC_CHUNK */ 0N/A /* Try to get space, if fail reduce slop and try again */ 0N/A /* Success, initialize the new pool header and add to end of list */ 0N/A /* OK, allocate the object from the current pool */ 0N/A * Allocation of "large" objects. 0N/A * The external semantics of these are the same as "small" objects, 0N/A * except that FAR pointers are used on 80x86. However the pool 0N/A * management heuristics are quite different. We assume that each 0N/A * request is large enough that it may as well be passed directly to 0N/A * jpeg_get_large; the pool management just links everything together 0N/A * so that we can free it all on demand. 0N/A * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY 0N/A * structures. The routines that create these structures (see below) 0N/A * deliberately bunch rows together to ensure a large request size. 0N/A/* Allocate a "large" object */ 0N/A /* Check for unsatisfiable request (do now to ensure no overflow below) */ 0N/A /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ 0N/A /* Always make a new pool */ 0N/A /* Success, initialize the new pool header and add to list */ 0N/A /* We maintain space counts in each pool header for statistical purposes, 0N/A * even though they are not needed for allocation. 0N/A return (
void FAR *) (
hdr_ptr +
1);
/* point to first data byte in pool */ 0N/A * Creation of 2-D sample arrays. 0N/A * The pointers are in near heap, the samples themselves in FAR heap. 0N/A * To minimize allocation overhead and to allow I/O of large contiguous 0N/A * blocks, we allocate the sample rows in groups of as many rows as possible 0N/A * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. 0N/A * NB: the virtual array control routines, later in this file, know about 0N/A * this chunking of rows. The rowsperchunk value is left in the mem manager 0N/A * object so that it can be saved away if this sarray is the workspace for 0N/A/* Allocate a 2-D sample array */ 0N/A /* Calculate max # of rows allowed in one allocation chunk */ 0N/A /* Get space for row pointers (small object) */ 0N/A /* Get the rows themselves (large objects) */ 0N/A * Creation of 2-D coefficient-block arrays. 0N/A * This is essentially the same as the code for sample arrays, above. 0N/A/* Allocate a 2-D coefficient-block array */ 0N/A /* Calculate max # of rows allowed in one allocation chunk */ 0N/A /* Get space for row pointers (small object) */ 0N/A /* Get the rows themselves (large objects) */ 0N/A * About virtual array management: 0N/A * The above "normal" array routines are only used to allocate strip buffers 0N/A * (as wide as the image, but just a few rows high). Full-image-sized buffers 0N/A * are handled as "virtual" arrays. The array is still accessed a strip at a 0N/A * time, but the memory manager must save the whole array for repeated 0N/A * accesses. The intended implementation is that there is a strip buffer in 0N/A * memory (as high as is possible given the desired memory limit), plus a 0N/A * backing file that holds the rest of the array. 0N/A * The request_virt_array routines are told the total size of the image and 0N/A * the maximum number of rows that will be accessed at once. The in-memory 0N/A * buffer must be at least as large as the maxaccess value. 0N/A * The request routines create control blocks but not the in-memory buffers. 0N/A * That is postponed until realize_virt_arrays is called. At that time the 0N/A * total amount of space needed is known (approximately, anyway), so free 0N/A * memory can be divided up fairly. 0N/A * The access_virt_array routines are responsible for making a specific strip 0N/A * area accessible (after reading or writing the backing file, if necessary). 0N/A * Note that the access routines are told whether the caller intends to modify 0N/A * the accessed strip; during a read-only pass this saves having to rewrite 0N/A * data to disk. The access routines are also responsible for pre-zeroing 0N/A * any newly accessed rows, if pre-zeroing was requested. 0N/A * In current usage, the access requests are usually for nonoverlapping 0N/A * strips; that is, successive access start_row numbers differ by exactly 0N/A * num_rows = maxaccess. This means we can get good performance with simple 0N/A * buffer dump/reload logic, by making the in-memory buffer be a multiple 0N/A * of the access height; then there will never be accesses across bufferload 0N/A * boundaries. The code will still work with overlapping access requests, 0N/A * but it doesn't handle bufferload overlaps very efficiently. 0N/A/* Request a virtual 2-D sample array */ 0N/A /* Only IMAGE-lifetime virtual arrays are currently supported */ 0N/A /* get control block */ 0N/A/* Request a virtual 2-D coefficient-block array */ 0N/A /* Only IMAGE-lifetime virtual arrays are currently supported */ 0N/A /* get control block */ 0N/A/* Allocate the in-memory buffers for any unrealized virtual arrays */ 0N/A /* Compute the minimum space needed (maxaccess rows in each buffer) 0N/A * and the maximum space needed (full image height in each buffer). 0N/A * These may be of use to the system-dependent jpeg_mem_available routine. 0N/A return;
/* no unrealized arrays, no work */ 0N/A /* Determine amount of memory to actually use; this is system-dependent. */ 0N/A /* If the maximum space needed is available, make all the buffers full 0N/A * height; otherwise parcel it out with the same number of minheights 0N/A /* If there doesn't seem to be enough space, try to get the minimum 0N/A * anyway. This allows a "stub" implementation of jpeg_mem_available(). 0N/A /* Allocate the in-memory buffers and initialize backing store as needed. */ 0N/A /* This buffer fits in memory */ 0N/A /* It doesn't fit in memory, create backing store. */ 0N/A /* This buffer fits in memory */ 0N/A /* It doesn't fit in memory, create backing store. */ 0N/A/* Do backing store read or write of a virtual sample array */ 0N/A /* Loop to read or write each allocation chunk in mem_buffer */ 0N/A /* One chunk, but check for short chunk at end of buffer */ 0N/A /* Transfer no more than is currently defined */ 0N/A /* Transfer no more than fits in file */ 0N/A if (
rows <= 0)
/* this chunk might be past end of file! */ 0N/A/* Do backing store read or write of a virtual coefficient-block array */ 0N/A /* Loop to read or write each allocation chunk in mem_buffer */ 0N/A /* One chunk, but check for short chunk at end of buffer */ 0N/A /* Transfer no more than is currently defined */ 0N/A /* Transfer no more than fits in file */ 0N/A if (
rows <= 0)
/* this chunk might be past end of file! */ 0N/A/* Access the part of a virtual sample array starting at start_row */ 0N/A/* and extending for num_rows rows. writable is true if */ 0N/A/* caller intends to modify the accessed area. */ 0N/A /* debugging check */ 0N/A /* Make the desired part of the virtual array accessible */ 0N/A /* Flush old buffer contents if necessary */ 0N/A /* Decide what part of virtual array to access. 0N/A * Algorithm: if target address > current window, assume forward scan, 0N/A * load starting at target address. If target address < current window, 0N/A * assume backward scan, load so that target area is top of window. 0N/A * Note that when switching from forward write to forward read, will have 0N/A * start_row = 0, so the limiting case applies and we load from 0 anyway. 0N/A /* use long arithmetic here to avoid overflow & unsigned problems */ 0N/A ltemp = 0;
/* don't fall off front end of file */ 0N/A /* Read in the selected part of the array. 0N/A * During the initial write pass, we will do no actual read 0N/A * because the selected part is all undefined. 0N/A /* Ensure the accessed part of the array is defined; prezero if needed. 0N/A * To improve locality of access, we only prezero the part of the array 0N/A * that the caller is about to access, not the entire in-memory array. 0N/A if (
writable)
/* writer skipped over a section of array */ 0N/A /* Flag the buffer dirty if caller will write in it */ 0N/A /* Return address of proper part of the buffer */ 0N/A/* Access the part of a virtual block array starting at start_row */ 0N/A/* and extending for num_rows rows. writable is true if */ 0N/A/* caller intends to modify the accessed area. */ 0N/A /* debugging check */ 0N/A /* Make the desired part of the virtual array accessible */ 0N/A /* Flush old buffer contents if necessary */ 0N/A /* Decide what part of virtual array to access. 0N/A * Algorithm: if target address > current window, assume forward scan, 0N/A * load starting at target address. If target address < current window, 0N/A * assume backward scan, load so that target area is top of window. 0N/A * Note that when switching from forward write to forward read, will have 0N/A * start_row = 0, so the limiting case applies and we load from 0 anyway. 0N/A /* use long arithmetic here to avoid overflow & unsigned problems */ 0N/A ltemp = 0;
/* don't fall off front end of file */ 0N/A /* Read in the selected part of the array. 0N/A * During the initial write pass, we will do no actual read 0N/A * because the selected part is all undefined. 0N/A /* Ensure the accessed part of the array is defined; prezero if needed. 0N/A * To improve locality of access, we only prezero the part of the array 0N/A * that the caller is about to access, not the entire in-memory array. 0N/A if (
writable)
/* writer skipped over a section of array */ 0N/A /* Flag the buffer dirty if caller will write in it */ 0N/A /* Return address of proper part of the buffer */ 0N/A * Release all objects belonging to a specified pool. 0N/A /* If freeing IMAGE pool, close any virtual arrays first */ 0N/A /* Release large objects */ 0N/A /* Release small objects */ 0N/A * Close up shop entirely. 0N/A * Note that this cannot be called unless cinfo->mem is non-NULL. 0N/A /* Close all backing store, release all memory. 0N/A * Releasing pools in reverse order might help avoid fragmentation 0N/A * with some (brain-damaged) malloc libraries. 0N/A /* Release the memory manager control block too. */ 0N/A * Memory manager initialization. 0N/A * When this is called, only the error manager pointer is valid in cinfo! 0N/A /* Check for configuration errors. 0N/A * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably 0N/A * doesn't reflect any real hardware alignment requirement. 0N/A * The test is a little tricky: for X>0, X and X-1 have no one-bits 0N/A * in common if and only if X is a power of 2, ie has only one one-bit. 0N/A * Some compilers may give an "unreachable code" warning here; ignore it. 0N/A /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be 0N/A * a multiple of SIZEOF(ALIGN_TYPE). 0N/A * Again, an "unreachable code" warning may be ignored here. 0N/A * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. 0N/A /* Attempt to allocate memory manager's control block */ 0N/A /* OK, fill in the method pointers */ 0N/A /* Make MAX_ALLOC_CHUNK accessible to other modules */ 0N/A /* Initialize working state */ 0N/A /* Declare ourselves open for business */ 0N/A /* Check for an environment variable JPEGMEM; if found, override the 0N/A * default max_memory setting from jpeg_mem_init. Note that the 0N/A * surrounding application may again override this value. 0N/A * If your system doesn't support getenv(), define NO_GETENV to disable