tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal shipping tomwalters@0: charge). Anyone wanting to incorporate all or part of this software in a tomwalters@0: commercial product must obtain a license from the Medical Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or implied tomwalters@0: warranty. tomwalters@0: tomwalters@0: THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING tomwalters@0: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE tomwalters@0: A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY tomwalters@0: DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN tomwalters@0: AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF tomwalters@0: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: ========== tomwalters@0: stitch.c tomwalters@0: ========== tomwalters@0: tomwalters@0: tomwalters@0: Copyright (c), 1989 John Holdsworth, Medical Research Council, Applied Psychology Unit. tomwalters@0: tomwalters@0: tomwalters@0: Author : John Holdsworth tomwalters@0: Written : 22th March, 1989. tomwalters@0: tomwalters@0: Edited : tomwalters@0: tomwalters@0: tomwalters@0: provides an unvarying interface for allocation and copying operations. tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: #include tomwalters@0: tomwalters@0: #include tomwalters@0: #if defined( NeXT ) tomwalters@0: #include tomwalters@0: #else tomwalters@0: #include tomwalters@0: #endif tomwalters@0: tomwalters@0: #ifndef _STITCH_H_ tomwalters@0: #include "stitch.h" tomwalters@0: #endif tomwalters@0: tomwalters@0: #if defined( sun ) tomwalters@0: extern bcopy(), bzero(), exit() ; tomwalters@0: #else tomwalters@0: #ifndef NeXT tomwalters@0: extern void bcopy(), bzero(), free(), exit() ; tomwalters@0: #endif tomwalters@0: #endif tomwalters@0: tomwalters@0: #ifndef lint tomwalters@0: static char *stitch_sccs_id = "@(#)stitch.c 1.19 J. Holdsworth (MRC-APU) 6/6/91" ; tomwalters@0: #endif tomwalters@0: tomwalters@0: #ifndef WRAPPING tomwalters@0: #define WRAPPING 0 tomwalters@0: #endif tomwalters@0: tomwalters@0: #if WRAPPING tomwalters@0: tomwalters@0: #include "wrap.h" tomwalters@0: tomwalters@0: Pointer wrap_malloc( size, where ) tomwalters@0: unsigned size ; tomwalters@0: char where[] ; tomwalters@0: { tomwalters@0: return ( wrap( malloc( WRAPPED_SIZE( size ) ), size, where ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Pointer wrap_realloc( old, size, where ) tomwalters@0: char *old ; tomwalters@0: unsigned size ; tomwalters@0: char where[] ; tomwalters@0: { tomwalters@0: return ( wrap( realloc( unwrap( old ), WRAPPED_SIZE( size ) ), where ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: void wrap_free( ptr ) tomwalters@0: Pointer ptr ; tomwalters@0: { tomwalters@0: free( (char *) unwrap( ptr ) ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: #else tomwalters@0: Pointer wrap_malloc( size, where ) tomwalters@0: unsigned size ; tomwalters@0: char where[] ; tomwalters@0: { tomwalters@0: #ifdef lint tomwalters@0: where ; tomwalters@0: #endif tomwalters@0: return ( malloc( size ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Pointer wrap_realloc( old, size, where ) tomwalters@0: char *old ; tomwalters@0: unsigned size ; tomwalters@0: char where[] ; tomwalters@0: { tomwalters@0: #ifdef lint tomwalters@0: where ; tomwalters@0: #endif tomwalters@0: #ifdef DSP32 tomwalters@0: stitch_error( "realloc called" ) ; tomwalters@0: #else tomwalters@0: return ( realloc( old, size ) ) ; tomwalters@0: #endif tomwalters@0: } tomwalters@0: tomwalters@0: void wrap_free( ptr ) tomwalters@0: Pointer ptr ; tomwalters@0: { tomwalters@0: free( ptr ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: #endif tomwalters@0: tomwalters@0: #ifdef DSP32 tomwalters@0: extern char _EAdata[], _EUdata[] ; tomwalters@0: char *freemem = _EUdata ; tomwalters@0: char errstr[200] ; tomwalters@0: tomwalters@0: int abs( n ) tomwalters@0: int n ; tomwalters@0: { tomwalters@0: if( n >= 0 ) tomwalters@0: return n ; tomwalters@0: else tomwalters@0: return -n ; tomwalters@0: } tomwalters@0: tomwalters@0: #endif tomwalters@0: tomwalters@0: void stitch_error( string, thing ) tomwalters@0: char *string ; tomwalters@0: char *thing ; tomwalters@0: { tomwalters@0: int i ; tomwalters@0: #ifdef DSP32 tomwalters@0: extern int errno ; tomwalters@0: tomwalters@0: (void) strcpy( errstr, string ) ; tomwalters@0: errno = thing - (char *) 0 ; tomwalters@0: #else tomwalters@0: (void) fprintf( stderr, string, thing ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: #ifdef PC tomwalters@0: /* put in delay to be able to read message if any */ tomwalters@0: tomwalters@0: for(i=0 ; i<3000 ; i++ ) tomwalters@0: (void) sqrt( 2. ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: stitch_exit( 1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: static void failed( bytes, where ) tomwalters@0: unsigned bytes ; tomwalters@0: char *where ; tomwalters@0: { tomwalters@0: static char msg[200] = "Memory allocation error, allocating %u bytes in " ; tomwalters@0: tomwalters@0: stitch_error( strcat( msg, where ), ( Pointer ) 0 + bytes ) ; tomwalters@0: } tomwalters@0: tomwalters@0: char stitchStructStr[] = "allocating a structure somewhere" ; tomwalters@0: tomwalters@0: /* memory usage indicators */ tomwalters@0: tomwalters@0: static long sused ; tomwalters@0: static long bused ; tomwalters@0: tomwalters@0: Pointer stitch_malloc( bytes, where ) tomwalters@0: unsigned bytes ; tomwalters@0: char *where ; tomwalters@0: { tomwalters@0: Pointer ptr ; tomwalters@0: tomwalters@0: if( where == stitchStructStr ) tomwalters@0: sused += bytes ; tomwalters@0: else tomwalters@0: bused += bytes ; tomwalters@0: tomwalters@0: #ifdef NOT_DSP32_ANYMORE tomwalters@0: int size = bytes + 3 >> 2 << 2 ; tomwalters@0: tomwalters@0: ptr = freemem ; tomwalters@0: tomwalters@0: if( ( freemem += size ) > _EAdata ) tomwalters@0: #else tomwalters@0: if( ( ptr = wrap_malloc( bytes, where ) ) == ( Pointer ) 0 ) tomwalters@0: #endif tomwalters@0: failed( bytes, where ) ; tomwalters@0: tomwalters@0: return ( ptr ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Pointer stitch_ralloc( bytes, where ) tomwalters@0: unsigned bytes ; tomwalters@0: char *where ; tomwalters@0: { tomwalters@0: #ifdef DSP32 tomwalters@0: extern char _EAram2[], _EUram2[] ; tomwalters@0: static char *mempt = _EUram2 ; tomwalters@0: int size ; tomwalters@0: tomwalters@0: size = bytes + 3 >> 2 << 2 ; tomwalters@0: tomwalters@0: if( mempt + size <= _EAram2 ) tomwalters@0: return ( ( mempt += size ) - size ) ; tomwalters@0: #endif tomwalters@0: #ifdef NICHE tomwalters@0: tomwalters@0: #ifdef NICHEE tomwalters@0: #include tomwalters@0: #else tomwalters@0: #define ONCHIP 2 tomwalters@0: #endif tomwalters@0: tomwalters@0: Pointer ptr ; tomwalters@0: tomwalters@0: if( ( ptr = valloc( items * size, ONCHIP, size ) ) == ( char * ) 0 ) tomwalters@0: return ( ptr ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: return ( stitch_malloc( bytes, where ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Pointer stitch_calloc( number, size, where ) tomwalters@0: unsigned number, size ; tomwalters@0: char *where ; tomwalters@0: { tomwalters@0: Pointer ptr ; tomwalters@0: #if defined( NICHE ) || defined( DSP32 ) tomwalters@0: if( ( ptr = stitch_malloc( number * size ) ) == ( char * ) 0 ) tomwalters@0: failed( number * size, where ) ; tomwalters@0: tomwalters@0: stitch_bzero( ptr, ( int ) number * size ) ; tomwalters@0: tomwalters@0: #else tomwalters@0: if( ( ptr = ( char * ) calloc( number, size ) ) == ( char * ) 0 ) tomwalters@0: failed( number * size, where ) ; tomwalters@0: #endif tomwalters@0: return ( ptr ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Pointer stitch_zeroed_malloc( size, where ) tomwalters@0: unsigned size ; tomwalters@0: char *where ; tomwalters@0: { tomwalters@0: Pointer ptr = stitch_malloc( size, where ) ; tomwalters@0: tomwalters@0: stitch_bzero( ptr, size ) ; tomwalters@0: tomwalters@0: return ( ptr ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Pointer stitch_copied_malloc( size, model, where ) tomwalters@0: unsigned size ; tomwalters@0: Pointer model ; tomwalters@0: char *where ; tomwalters@0: { tomwalters@0: Pointer ptr = stitch_malloc( size, where ) ; tomwalters@0: tomwalters@0: stitch_bcopy( model, ptr, size ) ; tomwalters@0: tomwalters@0: return ( ptr ) ; tomwalters@0: } tomwalters@0: tomwalters@0: void stitch_free( pointer ) tomwalters@0: Pointer pointer ; tomwalters@0: { tomwalters@0: if( pointer == (Pointer) 0 ) tomwalters@0: stitch_error( "attempt to free null pointer" ) ; tomwalters@0: tomwalters@0: #ifndef DSP32 tomwalters@0: wrap_free( pointer ) ; tomwalters@0: #endif tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: void stitch_exit( status ) tomwalters@0: int status ; tomwalters@0: { tomwalters@0: #if 00 tomwalters@0: (void) fprintf( stderr, "memory usage: %d for structures, %d for buffers\n", sused, bused ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: #ifdef NICHE tomwalters@0: kexit( status ) ; tomwalters@0: #else tomwalters@0: exit( status ) ; tomwalters@0: #endif tomwalters@0: } tomwalters@0: tomwalters@0: /* beware these defintions - they make stitch.h mandatory */ tomwalters@0: tomwalters@0: #if defined( vax ) || defined( mips ) || defined( sun ) tomwalters@0: tomwalters@0: void (*stitch_bcopy)() = ( void ( * ) () ) bcopy ; tomwalters@0: tomwalters@0: #else tomwalters@0: tomwalters@0: #ifdef PC tomwalters@0: tomwalters@0: /* memmove must be able to cope with overlapping buffers */ tomwalters@0: tomwalters@0: static void call_memmove( from, to, bytes ) tomwalters@0: char *from, *to ; tomwalters@0: unsigned bytes ; tomwalters@0: { tomwalters@0: ( void ) memmove( to, from, bytes ) ; tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: void (*stitch_bcopy)() = call_memmove ; tomwalters@0: tomwalters@0: #else tomwalters@0: tomwalters@0: static void reserve_bcopy( from, to, number ) tomwalters@0: Pointer from, to ; tomwalters@0: int number ; tomwalters@0: { tomwalters@0: register char *i, *j, *end ; tomwalters@0: tomwalters@0: if( from > to ) { tomwalters@0: for( i = from, j = to, end = from + number ; ( end - i ) % 4 > 0 ; ) tomwalters@0: *j++ = *i++ ; tomwalters@0: tomwalters@0: if( i < end ) tomwalters@0: do tomwalters@0: { tomwalters@0: *j++ = *i++ ; tomwalters@0: *j++ = *i++ ; tomwalters@0: *j++ = *i++ ; tomwalters@0: *j++ = *i++ ; tomwalters@0: } tomwalters@0: while( i < end ) ; tomwalters@0: } tomwalters@0: else if( from < to ) { tomwalters@0: for( i = from + number, j = to + number, end = from ; ( i - end ) % 4 > 0 ; ) tomwalters@0: *--j = *--i ; tomwalters@0: tomwalters@0: if( i > end ) tomwalters@0: do tomwalters@0: { tomwalters@0: *--j = *--i ; tomwalters@0: *--j = *--i ; tomwalters@0: *--j = *--i ; tomwalters@0: *--j = *--i ; tomwalters@0: } tomwalters@0: while( i > end ) ; tomwalters@0: } tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: void (*stitch_bcopy)() = reserve_bcopy ; tomwalters@0: tomwalters@0: #endif tomwalters@0: tomwalters@0: #endif tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: #if defined( vax ) || defined( mips ) || defined( sun ) tomwalters@0: tomwalters@0: void (*stitch_bzero)() = ( void ( * ) () ) bzero ; tomwalters@0: tomwalters@0: #else tomwalters@0: tomwalters@0: #if defined( PC ) || defined( DSP32 ) tomwalters@0: tomwalters@0: static void call_memset( to, bytes ) tomwalters@0: char *to ; tomwalters@0: int bytes ; tomwalters@0: { tomwalters@0: (void) memset( to, '\000', bytes ) ; tomwalters@0: } tomwalters@0: tomwalters@0: void (*stitch_bzero)() = call_memset ; tomwalters@0: tomwalters@0: #else tomwalters@0: tomwalters@0: static void reserve_bzero( to, bytes ) tomwalters@0: char *to ; tomwalters@0: int bytes ; tomwalters@0: { tomwalters@0: register char *ptr = to ; tomwalters@0: register char *end = to + bytes ; tomwalters@0: tomwalters@0: while( ptr < end ) tomwalters@0: *ptr++ = 0 ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: void (*stitch_bzero)() = reserve_bzero ; tomwalters@0: tomwalters@0: #endif tomwalters@0: tomwalters@0: #endif tomwalters@0: