Subject: Re: bcopy
To: Chris G Demetriou <Chris_G_Demetriou@BALVENIE.PDL.CS.CMU.EDU>
From: Trevor Blackwell <tlb@eecs.harvard.edu>
List: port-alpha
Date: 08/13/1995 09:56:52
Here's my bcopy regression test. I ran it for a good long time on the
one I submitted. It uses random inputs, with a skew toward lots of
misaligned overlapping regions.
Sorry for claiming your bcopy was wrong. It's confusing to us casual
kernel hackers to have kernel & libc functions with different
semantics but the same name. Maybe someday someone will write some
man(3k) library pages, that describe general-purpose functions in the
kernel.
/*
Regression test for bcopy.
Could be easily adapted to bzero.
Will print a big error message if there is a difference.
bcopies regions around in buffers - prints error message
if any differences between tested bcopies.
Author: Trevor Blackwell.
*/
#include <stdio.h>
#define MAXLEN 32768
#define PAD 128
extern int bcopy_naive(char *from, char *to, long len);
extern int bcopy_test(char *from, char *to, long len);
extern int bcopy(char *from, char *to, long len);
/*
You can just add bcopy functions here to have them tested.
Make the first one be the canonical bcopy that you are sure is
correct. bcopy_naive below is good.
*/
int (*routines[])(char *from, char *to, long len)= {
bcopy_naive,
bcopy_test,
bcopy
};
#define NUM_ROUTINES (sizeof(routines)/sizeof(void *))
char b[NUM_ROUTINES][MAXLEN+PAD];
int
initb()
{
int i,j;
for (i=0; i<MAXLEN+PAD; i++) {
int r=random()&0xff;
for (j=0; j<NUM_ROUTINES; j++) {
b[j][i]=r;
}
}
}
int
bcopy_naive(char *from, char *to, long len)
{
int i;
if (to>from) {
for (i=len-1; i>=0; i--) {
to[i]=from[i];
}
} else {
for (i=0; i<len; i++) {
to[i]=from[i];
}
}
}
int
tbc()
{
int i,j;
int s,d,l;
int ret=0;
int mlen;
int mask;
int n;
unsigned int t1,t2,tt;
mlen=32;
while (mlen<MAXLEN && (random()%2==0)) mlen*=2;
s=random()%(mlen/2);
l=random()%(mlen/2);
d=random()%(mlen/2);
mask=(1<<NUM_ROUTINES)-1;
while (mask) {
n=random()%NUM_ROUTINES;
if (!(mask & (1<<n))) continue;
mask &= ~(1<<n);
(*routines[n])(b[n]+s,b[n]+d,l);
}
for (i=1; i<NUM_ROUTINES; i++) {
if (bcmp(b[0],b[i],mlen+PAD)) {
printf("difference 0-%d\n",i);
ret=1;
}
}
if (ret) {
printf(" s=%x d=%x l=%x\n",s,d,l);
printf(" s+l=%x d+l=%x\n",s+l,d+l);
printf(" s&7=%x d&7=%x l&7=%x\n",s&7,d&7,l&7);
printf(" s^d&7=%x (s+l)^(d+l)&7=%x\n",(s^d)&7,((s+l)^(d+l))&7);
for (i=0; i<MAXLEN; i++) {
int f=0;
for (j=1; j<NUM_ROUTINES; j++) {
if (b[0][j] != b[i][j]) f=1;
}
printf("%08x: ");
for (j=0; j<NUM_ROUTINES; j++) {
printf("%02x ",b[j][i]);
}
printf("\n");
}
}
return ret;
}
main()
{
int i;
printf("Testing %d routines\n",NUM_ROUTINES);
while(1) {
initb();
for (i=0; i<10000; i++) {
if (tbc()) break;
}
fprintf(stderr,".");
}
}