Home | History | Annotate | Download | only in doio
      1 /*
      2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
      3  *
      4  * This program is free software; you can redistribute it and/or modify it
      5  * under the terms of version 2 of the GNU General Public License as
      6  * published by the Free Software Foundation.
      7  *
      8  * This program is distributed in the hope that it would be useful, but
      9  * WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     11  *
     12  * Further, this software is distributed without any warranty that it is
     13  * free of the rightful claim of any third person regarding infringement
     14  * or the like.  Any license provided herein, whether implied or
     15  * otherwise, applies only to this software file.  Patent licenses, if
     16  * any, provided herein do not apply to combinations of this program with
     17  * other software, or any other product whatsoever.
     18  *
     19  * You should have received a copy of the GNU General Public License along
     20  * with this program; if not, write the Free Software Foundation, Inc.,
     21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     22  *
     23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
     24  * Mountain View, CA  94043, or:
     25  *
     26  * http://www.sgi.com
     27  *
     28  * For further information regarding this notice, see:
     29  *
     30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
     31  */
     32 /************
     33 
     34 64 bits in a Cray word
     35 
     36 				12345678901234567890123456789012
     37 1234567890123456789012345678901234567890123456789012345678901234
     38 ________________________________________________________________
     39 <    pid       >< word-offset in file (same #) ><    pid       >
     40 
     41 1234567890123456789012345678901234567890123456789012345678901234
     42 ________________________________________________________________
     43 <    pid       >< offset in file of this word  ><    pid       >
     44 
     45 8 bits to a bytes == character
     46  NBPW            8
     47 ************/
     48 
     49 #include <stdio.h>
     50 #include <sys/param.h>
     51 #ifdef UNIT_TEST
     52 #include <unistd.h>
     53 #include <stdlib.h>
     54 #endif
     55 
     56 static char Errmsg[80];
     57 
     58 #define LOWER16BITS(X)	(X & 0177777)
     59 #define LOWER32BITS(X)	(X & 0xffffffff)
     60 
     61 /***
     62 #define HIGHBITS(WRD, bits) ( (-1 << (64-bits)) & WRD)
     63 #define LOWBITS(WRD, bits) ( (-1 >> (64-bits)) & WRD)
     64 ****/
     65 
     66 #define NBPBYTE		8	/* number bits per byte */
     67 
     68 #ifndef DEBUG
     69 #define DEBUG	0
     70 #endif
     71 
     72 /***********************************************************************
     73  *
     74  *
     75  * 1   2   3   4   5   6   7   8   9   10  11  12  13  14  14  15	bytes
     76  * 1234567890123456789012345678901234567890123456789012345678901234	bits
     77  * ________________________________________________________________	1 word
     78  * <    pid       >< offset in file of this word  ><    pid       >
     79  *
     80  * the words are put together where offset zero is the start.
     81  * thus, offset 16 is the start of  the second full word
     82  * Thus, offset 8 is in middle of word 1
     83  ***********************************************************************/
     84 int datapidgen(int pid, char *buffer, int bsize, int offset)
     85 {
     86 #if CRAY
     87 
     88 	int cnt;
     89 	int tmp;
     90 	char *chr;
     91 	long *wptr;
     92 	long word;
     93 	int woff;		/* file offset for the word */
     94 	int boff;		/* buffer offset or index */
     95 	int num_full_words;
     96 
     97 	num_full_words = bsize / NBPW;
     98 	boff = 0;
     99 
    100 	if (cnt = (offset % NBPW)) {	/* partial word */
    101 
    102 		woff = offset - cnt;
    103 #if DEBUG
    104 		printf("partial at beginning, cnt = %d, woff = %d\n", cnt,
    105 		       woff);
    106 #endif
    107 
    108 		word =
    109 		    ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) |
    110 		     LOWER16BITS(pid));
    111 
    112 		chr = (char *)&word;
    113 
    114 		for (tmp = 0; tmp < cnt; tmp++) {	/* skip unused bytes */
    115 			chr++;
    116 		}
    117 
    118 		for (; boff < (NBPW - cnt) && boff < bsize; boff++, chr++) {
    119 			buffer[boff] = *chr;
    120 		}
    121 	}
    122 
    123 	/*
    124 	 * full words
    125 	 */
    126 
    127 	num_full_words = (bsize - boff) / NBPW;
    128 
    129 	woff = offset + boff;
    130 
    131 	for (cnt = 0; cnt < num_full_words; woff += NBPW, cnt++) {
    132 
    133 		word =
    134 		    ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) |
    135 		     LOWER16BITS(pid));
    136 
    137 		chr = (char *)&word;
    138 		for (tmp = 0; tmp < NBPW; tmp++, chr++) {
    139 			buffer[boff++] = *chr;
    140 		}
    141 /****** Only if wptr is a word ellined
    142 	wptr = (long *)&buffer[boff];
    143 	*wptr = word;
    144 	boff += NBPW;
    145 *****/
    146 
    147 	}
    148 
    149 	/*
    150 	 * partial word at end of buffer
    151 	 */
    152 
    153 	if (cnt = ((bsize - boff) % NBPW)) {
    154 #if DEBUG
    155 		printf("partial at end\n");
    156 #endif
    157 		word =
    158 		    ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) |
    159 		     LOWER16BITS(pid));
    160 
    161 		chr = (char *)&word;
    162 
    163 		for (tmp = 0; tmp < cnt && boff < bsize; tmp++, chr++) {
    164 			buffer[boff++] = *chr;
    165 		}
    166 	}
    167 
    168 	return bsize;
    169 
    170 #else
    171 	return -1;		/* not support on non-64 bits word machines  */
    172 
    173 #endif
    174 
    175 }
    176 
    177 /***********************************************************************
    178  *
    179  *
    180  ***********************************************************************/
    181 int datapidchk(int pid, char *buffer, int bsize, int offset, char **errmsg)
    182 {
    183 #if CRAY
    184 
    185 	int cnt;
    186 	int tmp;
    187 	char *chr;
    188 	long *wptr;
    189 	long word;
    190 	int woff;		/* file offset for the word */
    191 	int boff;		/* buffer offset or index */
    192 	int num_full_words;
    193 
    194 	if (errmsg != NULL) {
    195 		*errmsg = Errmsg;
    196 	}
    197 
    198 	num_full_words = bsize / NBPW;
    199 	boff = 0;
    200 
    201 	if (cnt = (offset % NBPW)) {	/* partial word */
    202 		woff = offset - cnt;
    203 		word =
    204 		    ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) |
    205 		     LOWER16BITS(pid));
    206 
    207 		chr = (char *)&word;
    208 
    209 		for (tmp = 0; tmp < cnt; tmp++) {	/* skip unused bytes */
    210 			chr++;
    211 		}
    212 
    213 		for (; boff < (NBPW - cnt) && boff < bsize; boff++, chr++) {
    214 			if (buffer[boff] != *chr) {
    215 				sprintf(Errmsg,
    216 					"Data mismatch at offset %d, exp:%#o, act:%#o",
    217 					offset + boff, *chr, buffer[boff]);
    218 				return offset + boff;
    219 			}
    220 		}
    221 	}
    222 
    223 	/*
    224 	 * full words
    225 	 */
    226 
    227 	num_full_words = (bsize - boff) / NBPW;
    228 
    229 	woff = offset + boff;
    230 
    231 	for (cnt = 0; cnt < num_full_words; woff += NBPW, cnt++) {
    232 		word =
    233 		    ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) |
    234 		     LOWER16BITS(pid));
    235 
    236 		chr = (char *)&word;
    237 		for (tmp = 0; tmp < NBPW; tmp++, boff++, chr++) {
    238 			if (buffer[boff] != *chr) {
    239 				sprintf(Errmsg,
    240 					"Data mismatch at offset %d, exp:%#o, act:%#o",
    241 					woff, *chr, buffer[boff]);
    242 				return woff;
    243 			}
    244 		}
    245 
    246 /****** only if a word elined
    247 	wptr = (long *)&buffer[boff];
    248 	if (*wptr != word) {
    249 	    sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
    250 	        woff, word, *wptr);
    251 	    return woff;
    252 	}
    253 	boff += NBPW;
    254 ******/
    255 	}
    256 
    257 	/*
    258 	 * partial word at end of buffer
    259 	 */
    260 
    261 	if (cnt = ((bsize - boff) % NBPW)) {
    262 #if DEBUG
    263 		printf("partial at end\n");
    264 #endif
    265 		word =
    266 		    ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) |
    267 		     LOWER16BITS(pid));
    268 
    269 		chr = (char *)&word;
    270 
    271 		for (tmp = 0; tmp < cnt && boff < bsize; boff++, tmp++, chr++) {
    272 			if (buffer[boff] != *chr) {
    273 				sprintf(Errmsg,
    274 					"Data mismatch at offset %d, exp:%#o, act:%#o",
    275 					offset + boff, *chr, buffer[boff]);
    276 				return offset + boff;
    277 			}
    278 		}
    279 	}
    280 
    281 	sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
    282 	return -1;		/* buffer is ok */
    283 
    284 #else
    285 
    286 	if (errmsg != NULL) {
    287 		*errmsg = Errmsg;
    288 	}
    289 	sprintf(Errmsg, "Not supported on this OS.");
    290 	return 0;
    291 
    292 #endif
    293 
    294 }				/* end of datapidchk */
    295 
    296 #if UNIT_TEST
    297 
    298 /***********************************************************************
    299  * main for doing unit testing
    300  ***********************************************************************/
    301 int main(ac, ag)
    302 int ac;
    303 char **ag;
    304 {
    305 
    306 	int size = 1234;
    307 	char *buffer;
    308 	int ret;
    309 	char *errmsg;
    310 
    311 	if ((buffer = (char *)malloc(size)) == NULL) {
    312 		perror("malloc");
    313 		exit(2);
    314 	}
    315 
    316 	datapidgen(-1, buffer, size, 3);
    317 
    318 /***
    319 fwrite(buffer, size, 1, stdout);
    320 fwrite("\n", 1, 1, stdout);
    321 ****/
    322 
    323 	printf("datapidgen(-1, buffer, size, 3)\n");
    324 
    325 	ret = datapidchk(-1, buffer, size, 3, &errmsg);
    326 	printf("datapidchk(-1, buffer, %d, 3, &errmsg) returned %d %s\n",
    327 	       size, ret, errmsg);
    328 	ret = datapidchk(-1, &buffer[1], size - 1, 4, &errmsg);
    329 	printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n",
    330 	       size - 1, ret, errmsg);
    331 
    332 	buffer[25] = 0x0;
    333 	buffer[26] = 0x0;
    334 	buffer[27] = 0x0;
    335 	buffer[28] = 0x0;
    336 	printf("changing char 25-28\n");
    337 
    338 	ret = datapidchk(-1, &buffer[1], size - 1, 4, &errmsg);
    339 	printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n",
    340 	       size - 1, ret, errmsg);
    341 
    342 	printf("------------------------------------------\n");
    343 
    344 	datapidgen(getpid(), buffer, size, 5);
    345 
    346 /*******
    347 fwrite(buffer, size, 1, stdout);
    348 fwrite("\n", 1, 1, stdout);
    349 ******/
    350 
    351 	printf("\ndatapidgen(getpid(), buffer, size, 5)\n");
    352 
    353 	ret = datapidchk(getpid(), buffer, size, 5, &errmsg);
    354 	printf("datapidchk(getpid(), buffer, %d, 5, &errmsg) returned %d %s\n",
    355 	       size, ret, errmsg);
    356 
    357 	ret = datapidchk(getpid(), &buffer[1], size - 1, 6, &errmsg);
    358 	printf
    359 	    ("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n",
    360 	     size - 1, ret, errmsg);
    361 
    362 	buffer[25] = 0x0;
    363 	printf("changing char 25\n");
    364 
    365 	ret = datapidchk(getpid(), &buffer[1], size - 1, 6, &errmsg);
    366 	printf
    367 	    ("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n",
    368 	     size - 1, ret, errmsg);
    369 
    370 	exit(0);
    371 }
    372 
    373 #endif
    374