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 12558 : void *raid_malloc_align(size_t size, size_t align_size, void **freeptr)
19 : {
20 : unsigned char *ptr;
21 : uintptr_t offset;
22 :
23 12558 : ptr = malloc(size + align_size);
24 12558 : if (!ptr) {
25 : /* LCOV_EXCL_START */
26 : return 0;
27 : /* LCOV_EXCL_STOP */
28 : }
29 :
30 12558 : *freeptr = ptr;
31 :
32 12558 : offset = ((uintptr_t)ptr) % align_size;
33 :
34 12558 : if (offset != 0)
35 11750 : ptr += align_size - offset;
36 :
37 12558 : return ptr;
38 : }
39 :
40 179 : void *raid_malloc(size_t size, void **freeptr)
41 : {
42 179 : return raid_malloc_align(size, RAID_MALLOC_ALIGN, freeptr);
43 : }
44 :
45 12372 : void **raid_malloc_vector_align(int nd, int n, size_t size, size_t align_size, size_t displacement_size, void **freeptr)
46 : {
47 : void **v;
48 : unsigned char *va;
49 : int i;
50 :
51 12372 : BUG_ON(n <= 0 || nd < 0);
52 :
53 12372 : v = malloc(n * sizeof(void *));
54 12372 : if (!v) {
55 : /* LCOV_EXCL_START */
56 : return 0;
57 : /* LCOV_EXCL_STOP */
58 : }
59 :
60 12372 : va = raid_malloc_align(n * (size + displacement_size), align_size, freeptr);
61 12372 : if (!va) {
62 : /* LCOV_EXCL_START */
63 : free(v);
64 : return 0;
65 : /* LCOV_EXCL_STOP */
66 : }
67 :
68 166935 : for (i = 0; i < n; ++i) {
69 154563 : v[i] = va;
70 154563 : va += size + displacement_size;
71 : }
72 :
73 : /* reverse order of the data blocks */
74 : /* because they are usually accessed from the last one */
75 49526 : for (i = 0; i < nd / 2; ++i) {
76 37154 : void *ptr = v[i];
77 :
78 37154 : v[i] = v[nd - 1 - i];
79 37154 : v[nd - 1 - i] = ptr;
80 : }
81 :
82 12372 : return v;
83 : }
84 :
85 12372 : void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr)
86 : {
87 12372 : return raid_malloc_vector_align(nd, n, size, RAID_MALLOC_ALIGN, RAID_MALLOC_DISPLACEMENT, freeptr);
88 : }
89 :
90 5 : void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv)
91 : {
92 5 : unsigned char **v = (unsigned char **)vv;
93 : int i;
94 : size_t j;
95 :
96 124 : for (i = 0; i < n; ++i)
97 30583 : for (j = 0; j < size; ++j) {
98 : /* basic C99/C11 linear congruential generator */
99 30464 : seed = seed * 1103515245U + 12345U;
100 :
101 30464 : v[i][j] = seed >> 16;
102 : }
103 5 : }
104 :
105 3 : int raid_mtest_vector(int n, size_t size, void **vv)
106 : {
107 3 : unsigned char **v = (unsigned char **)vv;
108 : int i;
109 : size_t j;
110 : unsigned k;
111 : unsigned char d;
112 : unsigned char p;
113 :
114 : /* fill with 0 */
115 3 : d = 0;
116 98 : for (i = 0; i < n; ++i)
117 24415 : for (j = 0; j < size; ++j)
118 24320 : v[i][j] = d;
119 :
120 : /* test with all the byte patterns */
121 768 : for (k = 1; k < 256; ++k) {
122 765 : p = d;
123 765 : d = k;
124 :
125 : /* forward fill */
126 24990 : for (i = 0; i < n; ++i) {
127 6225825 : for (j = 0; j < size; ++j) {
128 6201600 : if (v[i][j] != p) {
129 : /* LCOV_EXCL_START */
130 : return -1;
131 : /* LCOV_EXCL_STOP */
132 : }
133 6201600 : v[i][j] = d;
134 : }
135 : }
136 :
137 765 : p = d;
138 765 : d = ~p;
139 : /* backward fill with complement */
140 24990 : for (i = 0; i < n; ++i) {
141 6225825 : for (j = size; j > 0; --j) {
142 6201600 : if (v[i][j - 1] != p) {
143 : /* LCOV_EXCL_START */
144 : return -1;
145 : /* LCOV_EXCL_STOP */
146 : }
147 6201600 : v[i][j - 1] = d;
148 : }
149 : }
150 : }
151 :
152 3 : return 0;
153 : }
154 :
|