tholm@uvicctr.UUCP (Terrence W. Holm) (09/14/88)
EFTH MINIX report #40 - September 1988 - memcpy(3) & friends There follows an implementation of memcpy(3), memccpy(3), memchr(3), memcmp(3) and memset(3) for MINIX. Please consider this public domain software. "man" pages are included. ---------------------------------------------------------- echo x - memccpy.3 gres '^X' '' > memccpy.3 << '/' XSUBROUTINES X memccpy(3) - memory copy, until specified character X XINVOCATION X #include <memory.h> X X char *memccpy( to, from, chr, count ) X char *to; X char *from; X int chr; X int count; X XEXPLANATION X <count> characters are copied from the memory pointed to by X <from> to the memory pointed to by <to>. If the character <chr> X is encountered then the copy stops, after <chr> is copied. X XRESULTS X NULL : <chr> was not found. X o/w : Points to the character after <chr> in <from> vector. / echo x - memccpy.c gres '^X' '' > memccpy.c << '/' X/* memccpy(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X#define NULL (char *) 0 X X Xchar *memccpy( to, from, chr, count ) X char *to; X char *from; X int chr; X int count; X X { X while( --count >= 0 ) X if ( (*to++ = *from++) == chr ) X return( from ); X X return( NULL ); X } / echo x - memchr.3 gres '^X' '' > memchr.3 << '/' XSUBROUTINES X memchr(3) - memory search X XINVOCATION X #include <memory.h> X X char *memchr( vector, chr, count ) X char *vector; X int chr; X int count; X XEXPLANATION X Memchr(3) looks for the character <chr> within the first X <count> characters of <vector>. X XRESULTS X NULL : <chr> was not found. X o/w : Points to <chr> in <vector>. X XREFERENCES X strchr(3) / echo x - memchr.c gres '^X' '' > memchr.c << '/' X/* memchr(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X#define NULL (char *) 0 X X Xchar *memchr( vector, chr, count ) X char *vector; X int chr; X int count; X X { X while( --count >= 0 ) X if ( *vector++ == chr ) X return( vector - 1 ); X X return( NULL ); X } / echo x - memcmp.3 gres '^X' '' > memcmp.3 << '/' XSUBROUTINES X memcmp(3) - memory compare X XINVOCATION X int memcmp( vector1, vector2, count ) X char *vector1; X char *vector2; X int count; X XEXPLANATION X Memcmp(3) uses character comparison to determine if X the data pointed to by <vector1> is less, equal or X greater than the data pointed to by <vector2>. Up to X <count> characters are compared. X XRESULTS X <0 : <vector1> is less than <vector2> X =0 : <vector1> is equal to <vector2> X >0 : <vector1> is greater than <vector2> X XREFERENCES X bcmp(3), strcmp(3) / echo x - memcmp.c gres '^X' '' > memcmp.c << '/' X/* memcmp(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xint memcmp( vector1, vector2, count ) X char *vector1; X char *vector2; X int count; X X { X register int cmp; X X if ( vector1 == vector2 ) X return( 0 ); X X while( --count >= 0 ) X if ( cmp = *vector1++ - *vector2++ ) X return( cmp ); X X return( 0 ); X } / echo x - memcpy.3 gres '^X' '' > memcpy.3 << '/' XSUBROUTINES X memcpy(3) - memory copy X XINVOCATION X #include <memory.h> X X char *memcpy( to, from, count ) X char *to; X char *from; X int count; X XEXPLANATION X <count> characters are copied from the memory pointed X to by <from> to the memory pointed to by <to>. If the X location <to> is within the <from> vector, then X the copy is done backwards to save the <from> vector X from being trampled. X XRESULTS X Returns <to>. X XREFERENCES X bcopy(3), strcpy(3) / echo x - memcpy.c gres '^X' '' > memcpy.c << '/' X/* memcpy(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xchar *memcpy( to, from, count ) X char *to; X char *from; X int count; X X { X int word_count = count / sizeof(int); X int byte_count = count & ( sizeof(int) - 1 ); X char *temp_to = to; X X if ( to > from && to < from + count ) X { X /* Must copy backwards */ X from += count; X to += count; X X while( --byte_count >= 0 ) X *--to = *--from; X X while( --word_count >= 0 ) X *--((int *) to) = *--((int *) from); X } X else X { X while( --word_count >= 0 ) X *((int *) to)++ = *((int *) from)++; X X while( --byte_count >= 0 ) X *to++ = *from++; X } X X return( temp_to ); X } / echo x - memory.h gres '^X' '' > memory.h << '/' X/* memory.h */ X Xchar *memcpy(); Xchar *memccpy(); Xchar *memchr(); Xchar *memset(); Xint memcmp(); / echo x - memset.3 gres '^X' '' > memset.3 << '/' XSUBROUTINES X memset(3) - memory initialize X XINVOCATION X #include <memory.h> X X char *memset( vector, chr, count ) X char *vector; X int chr; X int count; X XEXPLANATION X The first <count> characters of <vector> are set to <chr>. X XRESULTS X Returns <vector>. X XREFERENCES X bzero(3) / echo x - memset.c gres '^X' '' > memset.c << '/' X/* memset(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xchar *memset( vector, chr, count ) X char *vector; X int chr; X int count; X X { X register char *memory = vector; X X while( --count >= 0 ) X *memory++ = chr; X X return( vector ); X } / ---------------------------------------------------------- Edwin L. Froese uw-beaver!ubc-cs!mprg!handel!froese Terrence W. Holm uw-beaver!uvicctr!tholm
chip@vector.UUCP (Chip Rosenthal) (09/15/88)
In article <496@uvicctr.UUCP> tholm@uvicctr.UUCP (Terrence W. Holm) writes: >There follows an implementation of memcpy(3), memccpy(3), >memchr(3), memcmp(3) and memset(3) for MINIX. Please consider >this public domain software. "man" pages are included. It might worth playing some games with these. I would think that memcpy() is one of the cases where you are willing to give a little ugliness for performance. There was a recent discussion in comp.lang.c about using "Duff's Device" for loop-unrolling in a portable way. Tom Duff himself talked about the origins of this in <8144@alice.UUCP>. It might be interesting to look at this way of doing memcpy(). (I've archived a copy of Tom's message in case anybody is interested.) -- Chip Rosenthal chip@vector.UUCP | I've been a wizard since my childhood. Dallas Semiconductor 214-450-0486 | And I've earned some respect for my art.
tholm@uvicctr.UUCP (Terrence W. Holm) (09/19/88)
> From: chip@vector.UUCP (Chip Rosenthal) > > In article <496@uvicctr.UUCP> tholm@uvicctr.UUCP (Terrence W. Holm) writes: > >There follows an implementation of memcpy(3), memccpy(3), > >memchr(3), memcmp(3) and memset(3) for MINIX. Please consider > > It might worth playing some games with these. I would think that memcpy() > is one of the cases where you are willing to give a little ugliness for > performance. Yes, I agree. But you must have noticed that my mission is to supply MINIX with a useful, documented library, not to waste time with small performance details - which are mute once we consider the whole picture. If you want to really help the MINIX community, I can supply you with a list of more important topics. > > There was a recent discussion in comp.lang.c about using "Duff's Device" Yes, I teach all my 1st years to write code this way :-) :-) Terrence W. Holm
tholm@uvicctr.UUCP (Terrence W. Holm) (11/23/88)
EFTH MINIX report #59 - November 1988 - memcpy(3), etc. for MINIX-ST My previous posting of memcpy(3), etc. could copy int's at an odd address. This does not work on an MC68000 system. The following fixes the problem, (and also runs faster on 80286 machines when the data is word aligned). ---------------------------------------------------------- echo x - bcmp.c gres '^X' '' > bcmp.c << '/' X/* bcmp(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xint bcmp( vector1, vector2, count ) X register char *vector1; X register char *vector2; X int count; X X { X register int long_count; X register int byte_count; X X if ( vector1 == vector2 ) X return( 0 ); X X /* Only compare longs if both are on an */ X /* even byte boundary. */ X X if ( ((int) vector1 & 1) || ((int) vector2 & 1) ) X { X long_count = 0; X byte_count = count; X } X else X { X long_count = count >> 2; /* Assumes sizeof(long) is 4 */ X byte_count = count & 03; X } X X X while( --long_count >= 0 ) X if ( *((long *) vector1)++ != *((long *) vector2)++ ) X return( 1 ); X X while( --byte_count >= 0 ) X if ( *vector1++ != *vector2++ ) X return( 1 ); X X return( 0 ); X } / echo x - bcopy.c gres '^X' '' > bcopy.c << '/' X/* bcopy(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xbcopy( from, to, count ) X register char *from; X register char *to; X int count; X X { X register int long_count; X register int byte_count; X X /* Only copy longs if both source and destination */ X /* are on an even byte boundary. */ X X if ( ((int) to & 1) || ((int) from & 1) ) X { X long_count = 0; X byte_count = count; X } X else X { X long_count = count >> 2; /* Assumes sizeof(long) is 4 */ X byte_count = count & 03; X } X X X if ( to > from && to < from + count ) X { X /* Must copy backwards */ X from += count; X to += count; X X while( --byte_count >= 0 ) X *--to = *--from; X X while( --long_count >= 0 ) X *--((long *) to) = *--((long *) from); X } X else X { X while( --long_count >= 0 ) X *((long *) to)++ = *((long *) from)++; X X while( --byte_count >= 0 ) X *to++ = *from++; X } X } / echo x - bzero.c gres '^X' '' > bzero.c << '/' X/* bzero(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xbzero( vector, count ) X register char *vector; X int count; X X { X register int long_count; X register int byte_count; X X /* Only use longs if on an even byte boundary */ X X if ( (int) vector & 1 ) X { X long_count = 0; X byte_count = count; X } X else X { X long_count = count >> 2; /* Assumes sizeof(long) is 4 */ X byte_count = count & 03; X } X X while( --long_count >= 0 ) X *((long *) vector)++ = 0L; X X while( --byte_count >= 0 ) X *vector++ = 0; X } / echo x - memcpy.c gres '^X' '' > memcpy.c << '/' X/* memcpy(3) X * X * Author: Terrence W. Holm Sep. 1988 X */ X X Xchar *memcpy( to, from, count ) X register char *to; X register char *from; X int count; X X { X char *temp_to = to; X register int long_count; X register int byte_count; X X /* Only copy longs if both source and destination */ X /* are on an even byte boundary. */ X X if ( ((int) to & 1) || ((int) from & 1) ) X { X long_count = 0; X byte_count = count; X } X else X { X long_count = count >> 2; /* Assumes sizeof(long) is 4 */ X byte_count = count & 03; X } X X X if ( to > from && to < from + count ) X { X /* Must copy backwards */ X from += count; X to += count; X X while( --byte_count >= 0 ) X *--to = *--from; X X while( --long_count >= 0 ) X *--((long *) to) = *--((long *) from); X } X else X { X while( --long_count >= 0 ) X *((long *) to)++ = *((long *) from)++; X X while( --byte_count >= 0 ) X *to++ = *from++; X } X X return( temp_to ); X } / ---------------------------------------------------------- Terrence W. Holm uunet!uw-beaver!uvicctr!tholm tholm%uvunix.bitnet tholm%sirius.UVic.ca@relay.ubc.ca