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