/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ */ /************ 64 bits in a Cray word 12345678901234567890123456789012 1234567890123456789012345678901234567890123456789012345678901234 ________________________________________________________________ < pid >< word-offset in file (same #) >< pid > 1234567890123456789012345678901234567890123456789012345678901234 ________________________________________________________________ < pid >< offset in file of this word >< pid > 8 bits to a bytes == character NBPW 8 ************/ #include <stdio.h> #include <sys/param.h> #ifdef UNIT_TEST #include <unistd.h> #include <stdlib.h> #endif static char Errmsg[80]; #define LOWER16BITS(X) (X & 0177777) #define LOWER32BITS(X) (X & 0xffffffff) /*** #define HIGHBITS(WRD, bits) ( (-1 << (64-bits)) & WRD) #define LOWBITS(WRD, bits) ( (-1 >> (64-bits)) & WRD) ****/ #define NBPBYTE 8 /* number bits per byte */ #ifndef DEBUG #define DEBUG 0 #endif /*********************************************************************** * * * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 15 bytes * 1234567890123456789012345678901234567890123456789012345678901234 bits * ________________________________________________________________ 1 word * < pid >< offset in file of this word >< pid > * * the words are put together where offset zero is the start. * thus, offset 16 is the start of the second full word * Thus, offset 8 is in middle of word 1 ***********************************************************************/ int datapidgen(int pid, char *buffer, int bsize, int offset) { #if CRAY int cnt; int tmp; char *chr; long *wptr; long word; int woff; /* file offset for the word */ int boff; /* buffer offset or index */ int num_full_words; num_full_words = bsize / NBPW; boff = 0; if (cnt = (offset % NBPW)) { /* partial word */ woff = offset - cnt; #if DEBUG printf("partial at beginning, cnt = %d, woff = %d\n", cnt, woff); #endif word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid)); chr = (char *)&word; for (tmp = 0; tmp < cnt; tmp++) { /* skip unused bytes */ chr++; } for (; boff < (NBPW - cnt) && boff < bsize; boff++, chr++) { buffer[boff] = *chr; } } /* * full words */ num_full_words = (bsize - boff) / NBPW; woff = offset + boff; for (cnt = 0; cnt < num_full_words; woff += NBPW, cnt++) { word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid)); chr = (char *)&word; for (tmp = 0; tmp < NBPW; tmp++, chr++) { buffer[boff++] = *chr; } /****** Only if wptr is a word ellined wptr = (long *)&buffer[boff]; *wptr = word; boff += NBPW; *****/ } /* * partial word at end of buffer */ if (cnt = ((bsize - boff) % NBPW)) { #if DEBUG printf("partial at end\n"); #endif word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid)); chr = (char *)&word; for (tmp = 0; tmp < cnt && boff < bsize; tmp++, chr++) { buffer[boff++] = *chr; } } return bsize; #else return -1; /* not support on non-64 bits word machines */ #endif } /*********************************************************************** * * ***********************************************************************/ int datapidchk(int pid, char *buffer, int bsize, int offset, char **errmsg) { #if CRAY int cnt; int tmp; char *chr; long *wptr; long word; int woff; /* file offset for the word */ int boff; /* buffer offset or index */ int num_full_words; if (errmsg != NULL) { *errmsg = Errmsg; } num_full_words = bsize / NBPW; boff = 0; if (cnt = (offset % NBPW)) { /* partial word */ woff = offset - cnt; word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid)); chr = (char *)&word; for (tmp = 0; tmp < cnt; tmp++) { /* skip unused bytes */ chr++; } for (; boff < (NBPW - cnt) && boff < bsize; boff++, chr++) { if (buffer[boff] != *chr) { sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o", offset + boff, *chr, buffer[boff]); return offset + boff; } } } /* * full words */ num_full_words = (bsize - boff) / NBPW; woff = offset + boff; for (cnt = 0; cnt < num_full_words; woff += NBPW, cnt++) { word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid)); chr = (char *)&word; for (tmp = 0; tmp < NBPW; tmp++, boff++, chr++) { if (buffer[boff] != *chr) { sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o", woff, *chr, buffer[boff]); return woff; } } /****** only if a word elined wptr = (long *)&buffer[boff]; if (*wptr != word) { sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o", woff, word, *wptr); return woff; } boff += NBPW; ******/ } /* * partial word at end of buffer */ if (cnt = ((bsize - boff) % NBPW)) { #if DEBUG printf("partial at end\n"); #endif word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid)); chr = (char *)&word; for (tmp = 0; tmp < cnt && boff < bsize; boff++, tmp++, chr++) { if (buffer[boff] != *chr) { sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o", offset + boff, *chr, buffer[boff]); return offset + boff; } } } sprintf(Errmsg, "all %d bytes match desired pattern", bsize); return -1; /* buffer is ok */ #else if (errmsg != NULL) { *errmsg = Errmsg; } sprintf(Errmsg, "Not supported on this OS."); return 0; #endif } /* end of datapidchk */ #if UNIT_TEST /*********************************************************************** * main for doing unit testing ***********************************************************************/ int main(ac, ag) int ac; char **ag; { int size = 1234; char *buffer; int ret; char *errmsg; if ((buffer = (char *)malloc(size)) == NULL) { perror("malloc"); exit(2); } datapidgen(-1, buffer, size, 3); /*** fwrite(buffer, size, 1, stdout); fwrite("\n", 1, 1, stdout); ****/ printf("datapidgen(-1, buffer, size, 3)\n"); ret = datapidchk(-1, buffer, size, 3, &errmsg); printf("datapidchk(-1, buffer, %d, 3, &errmsg) returned %d %s\n", size, ret, errmsg); ret = datapidchk(-1, &buffer[1], size - 1, 4, &errmsg); printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n", size - 1, ret, errmsg); buffer[25] = 0x0; buffer[26] = 0x0; buffer[27] = 0x0; buffer[28] = 0x0; printf("changing char 25-28\n"); ret = datapidchk(-1, &buffer[1], size - 1, 4, &errmsg); printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n", size - 1, ret, errmsg); printf("------------------------------------------\n"); datapidgen(getpid(), buffer, size, 5); /******* fwrite(buffer, size, 1, stdout); fwrite("\n", 1, 1, stdout); ******/ printf("\ndatapidgen(getpid(), buffer, size, 5)\n"); ret = datapidchk(getpid(), buffer, size, 5, &errmsg); printf("datapidchk(getpid(), buffer, %d, 5, &errmsg) returned %d %s\n", size, ret, errmsg); ret = datapidchk(getpid(), &buffer[1], size - 1, 6, &errmsg); printf ("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n", size - 1, ret, errmsg); buffer[25] = 0x0; printf("changing char 25\n"); ret = datapidchk(getpid(), &buffer[1], size - 1, 6, &errmsg); printf ("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n", size - 1, ret, errmsg); exit(0); } #endif