Line data Source code
1 : /*
2 : * Copyright (C) 2013 Andrea Mazzoleni
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will 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 :
15 : #include "internal.h"
16 : #include "memory.h"
17 :
18 274 : void *raid_malloc_align(size_t size, void **freeptr)
19 : {
20 : unsigned char *ptr;
21 : uintptr_t offset;
22 :
23 274 : ptr = malloc(size + RAID_MALLOC_ALIGN);
24 274 : if (!ptr) {
25 : /* LCOV_EXCL_START */
26 : return 0;
27 : /* LCOV_EXCL_STOP */
28 : }
29 :
30 274 : *freeptr = ptr;
31 :
32 274 : offset = ((uintptr_t)ptr) % RAID_MALLOC_ALIGN;
33 :
34 274 : if (offset != 0)
35 268 : ptr += RAID_MALLOC_ALIGN - offset;
36 :
37 274 : return ptr;
38 : }
39 :
40 199 : void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr)
41 : {
42 : void **v;
43 : unsigned char *va;
44 : int i;
45 :
46 199 : BUG_ON(n <= 0 || nd < 0);
47 :
48 199 : v = malloc(n * sizeof(void *));
49 199 : if (!v) {
50 : /* LCOV_EXCL_START */
51 : return 0;
52 : /* LCOV_EXCL_STOP */
53 : }
54 :
55 199 : va = raid_malloc_align(n * (size + RAID_MALLOC_DISPLACEMENT), freeptr);
56 199 : if (!va) {
57 : /* LCOV_EXCL_START */
58 : free(v);
59 : return 0;
60 : /* LCOV_EXCL_STOP */
61 : }
62 :
63 3513 : for (i = 0; i < n; ++i) {
64 3314 : v[i] = va;
65 3314 : va += size + RAID_MALLOC_DISPLACEMENT;
66 : }
67 :
68 : /* reverse order of the data blocks */
69 : /* because they are usually accessed from the last one */
70 834 : for (i = 0; i < nd / 2; ++i) {
71 635 : void *ptr = v[i];
72 :
73 635 : v[i] = v[nd - 1 - i];
74 635 : v[nd - 1 - i] = ptr;
75 : }
76 :
77 199 : return v;
78 : }
79 :
80 5 : void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv)
81 : {
82 5 : unsigned char **v = (unsigned char **)vv;
83 : int i;
84 : size_t j;
85 :
86 124 : for (i = 0; i < n; ++i)
87 30583 : for (j = 0; j < size; ++j) {
88 : /* basic C99/C11 linear congruential generator */
89 30464 : seed = seed * 1103515245U + 12345U;
90 :
91 30464 : v[i][j] = seed >> 16;
92 : }
93 5 : }
94 :
95 726 : int raid_mtest_vector(int n, size_t size, void **vv)
96 : {
97 726 : unsigned char **v = (unsigned char **)vv;
98 : int i;
99 : size_t j;
100 : unsigned k;
101 : unsigned char d;
102 : unsigned char p;
103 :
104 : /* fill with 0 */
105 726 : d = 0;
106 1544 : for (i = 0; i < n; ++i)
107 37971706 : for (j = 0; j < size; ++j)
108 37970888 : v[i][j] = d;
109 :
110 : /* test with all the byte patterns */
111 185856 : for (k = 1; k < 256; ++k) {
112 185130 : p = d;
113 185130 : d = k;
114 :
115 : /* forward fill */
116 393720 : for (i = 0; i < n; ++i) {
117 9682785030 : for (j = 0; j < size; ++j) {
118 9682576440 : if (v[i][j] != p) {
119 : /* LCOV_EXCL_START */
120 : return -1;
121 : /* LCOV_EXCL_STOP */
122 : }
123 9682576440 : v[i][j] = d;
124 : }
125 : }
126 :
127 185130 : p = d;
128 185130 : d = ~p;
129 : /* backward fill with complement */
130 393720 : for (i = 0; i < n; ++i) {
131 9682785030 : for (j = size; j > 0; --j) {
132 9682576440 : if (v[i][j - 1] != p) {
133 : /* LCOV_EXCL_START */
134 : return -1;
135 : /* LCOV_EXCL_STOP */
136 : }
137 9682576440 : v[i][j - 1] = d;
138 : }
139 : }
140 : }
141 :
142 726 : return 0;
143 : }
144 :
|