snapraid/raid/memory.c

144 lines
2.6 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-or-later
2026-04-02 16:25:49 +02:00
// Copyright (C) 2013 Andrea Mazzoleni
2013-12-29 22:13:08 +01:00
#include "internal.h"
#include "memory.h"
2016-05-15 14:18:44 +02:00
void *raid_malloc_align(size_t size, size_t align_size, void **freeptr)
2013-12-29 22:13:08 +01:00
{
unsigned char *ptr;
uintptr_t offset;
2016-05-15 14:18:44 +02:00
ptr = malloc(size + align_size);
2015-03-18 19:19:32 +01:00
if (!ptr) {
/* LCOV_EXCL_START */
2013-12-29 22:13:08 +01:00
return 0;
2015-03-18 19:19:32 +01:00
/* LCOV_EXCL_STOP */
}
2013-12-29 22:13:08 +01:00
*freeptr = ptr;
2016-05-15 14:18:44 +02:00
offset = ((uintptr_t)ptr) % align_size;
2013-12-29 22:13:08 +01:00
if (offset != 0)
2016-05-15 14:18:44 +02:00
ptr += align_size - offset;
2013-12-29 22:13:08 +01:00
return ptr;
}
2016-05-15 14:18:44 +02:00
void *raid_malloc(size_t size, void **freeptr)
{
return raid_malloc_align(size, RAID_MALLOC_ALIGN, freeptr);
}
void **raid_malloc_vector_align(int nd, int n, size_t size, size_t align_size, size_t displacement_size, void **freeptr)
2013-12-29 22:13:08 +01:00
{
void **v;
unsigned char *va;
2014-01-02 17:51:50 +01:00
int i;
2013-12-29 22:13:08 +01:00
2014-09-17 21:49:37 +02:00
BUG_ON(n <= 0 || nd < 0);
2014-01-02 17:51:50 +01:00
v = malloc(n * sizeof(void *));
2015-03-18 19:19:32 +01:00
if (!v) {
/* LCOV_EXCL_START */
2013-12-29 22:13:08 +01:00
return 0;
2015-03-18 19:19:32 +01:00
/* LCOV_EXCL_STOP */
}
2013-12-29 22:13:08 +01:00
2016-05-15 14:18:44 +02:00
va = raid_malloc_align(n * (size + displacement_size), align_size, freeptr);
2013-12-29 22:13:08 +01:00
if (!va) {
2015-03-18 19:19:32 +01:00
/* LCOV_EXCL_START */
2013-12-29 22:13:08 +01:00
free(v);
return 0;
2015-03-18 19:19:32 +01:00
/* LCOV_EXCL_STOP */
2013-12-29 22:13:08 +01:00
}
2014-01-02 17:51:50 +01:00
for (i = 0; i < n; ++i) {
v[i] = va;
2016-05-15 14:18:44 +02:00
va += size + displacement_size;
2014-01-02 17:51:50 +01:00
}
2013-12-29 22:13:08 +01:00
2014-01-02 17:51:50 +01:00
/* reverse order of the data blocks */
/* because they are usually accessed from the last one */
2014-11-12 20:41:00 +01:00
for (i = 0; i < nd / 2; ++i) {
2013-12-29 22:13:08 +01:00
void *ptr = v[i];
2014-01-02 17:51:50 +01:00
v[i] = v[nd - 1 - i];
v[nd - 1 - i] = ptr;
2013-12-29 22:13:08 +01:00
}
return v;
}
2016-05-15 14:18:44 +02:00
void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr)
{
return raid_malloc_vector_align(nd, n, size, RAID_MALLOC_ALIGN, RAID_MALLOC_DISPLACEMENT, freeptr);
}
void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv)
2014-01-02 17:51:50 +01:00
{
2015-03-18 08:21:28 +01:00
unsigned char **v = (unsigned char **)vv;
2014-01-02 17:51:50 +01:00
int i;
size_t j;
for (i = 0; i < n; ++i)
for (j = 0; j < size; ++j) {
/* basic C99/C11 linear congruential generator */
seed = seed * 1103515245U + 12345U;
v[i][j] = seed >> 16;
}
2014-01-02 17:51:50 +01:00
}
int raid_mtest_vector(int n, size_t size, void **vv)
2013-12-29 22:13:08 +01:00
{
2015-03-18 08:21:28 +01:00
unsigned char **v = (unsigned char **)vv;
2014-01-02 17:51:50 +01:00
int i;
2013-12-29 22:13:08 +01:00
size_t j;
unsigned k;
unsigned char d;
unsigned char p;
/* fill with 0 */
d = 0;
2014-01-02 17:51:50 +01:00
for (i = 0; i < n; ++i)
2013-12-29 22:13:08 +01:00
for (j = 0; j < size; ++j)
v[i][j] = d;
/* test with all the byte patterns */
for (k = 1; k < 256; ++k) {
p = d;
d = k;
/* forward fill */
2014-01-02 17:51:50 +01:00
for (i = 0; i < n; ++i) {
2013-12-29 22:13:08 +01:00
for (j = 0; j < size; ++j) {
2015-03-18 19:19:32 +01:00
if (v[i][j] != p) {
/* LCOV_EXCL_START */
2013-12-29 22:13:08 +01:00
return -1;
2015-03-18 19:19:32 +01:00
/* LCOV_EXCL_STOP */
}
2013-12-29 22:13:08 +01:00
v[i][j] = d;
}
}
p = d;
d = ~p;
/* backward fill with complement */
2014-01-02 17:51:50 +01:00
for (i = 0; i < n; ++i) {
2013-12-29 22:13:08 +01:00
for (j = size; j > 0; --j) {
2015-03-18 19:19:32 +01:00
if (v[i][j - 1] != p) {
/* LCOV_EXCL_START */
2013-12-29 22:13:08 +01:00
return -1;
2015-03-18 19:19:32 +01:00
/* LCOV_EXCL_STOP */
}
2014-11-12 20:41:00 +01:00
v[i][j - 1] = d;
2013-12-29 22:13:08 +01:00
}
}
}
return 0;
}