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