Line | Branch | Exec | Source |
---|---|---|---|
1 | /* -*- c -*- */ | ||
2 | /* | ||
3 | * Copyright 2014 Free Software Foundation, Inc. | ||
4 | * | ||
5 | * This file is part of VOLK | ||
6 | * | ||
7 | * SPDX-License-Identifier: LGPL-3.0-or-later | ||
8 | */ | ||
9 | |||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <string.h> | ||
13 | |||
14 | #include <volk/volk_malloc.h> | ||
15 | |||
16 | /* | ||
17 | * C11 features: | ||
18 | * see: https://en.cppreference.com/w/c/memory/aligned_alloc | ||
19 | * | ||
20 | * MSVC is broken | ||
21 | * see: | ||
22 | * https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=vs-2019 | ||
23 | * This section: | ||
24 | * C11 The Universal CRT implemented the parts of the | ||
25 | * C11 Standard Library that are required by C++17, | ||
26 | * with the exception of C99 strftime() E/O alternative | ||
27 | * conversion specifiers, C11 fopen() exclusive mode, | ||
28 | * and C11 aligned_alloc(). The latter is unlikely to | ||
29 | * be implemented, because C11 specified aligned_alloc() | ||
30 | * in a way that's incompatible with the Microsoft | ||
31 | * implementation of free(): | ||
32 | * namely, that free() must be able to handle highly aligned allocations. | ||
33 | * | ||
34 | * We must work around this problem because MSVC is non-compliant! | ||
35 | */ | ||
36 | |||
37 | |||
38 | 3536 | void* volk_malloc(size_t size, size_t alignment) | |
39 | { | ||
40 |
2/4✓ Branch 0 taken 3536 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3536 times.
|
3536 | if ((size == 0) || (alignment == 0)) { |
41 | ✗ | fprintf(stderr, "VOLK: Error allocating memory: either size or alignment is 0"); | |
42 | ✗ | return NULL; | |
43 | } | ||
44 | // Tweak size to satisfy ASAN (the GCC address sanitizer). | ||
45 | // Calling 'volk_malloc' might therefor result in the allocation of more memory than | ||
46 | // requested for correct alignment. Any allocation size change here will in general | ||
47 | // not impact the end result since initial size alignment is required either way. | ||
48 |
2/2✓ Branch 0 taken 2446 times.
✓ Branch 1 taken 1090 times.
|
3536 | if (size % alignment) { |
49 | 2446 | size += alignment - (size % alignment); | |
50 | } | ||
51 | #if HAVE_POSIX_MEMALIGN | ||
52 | // quoting posix_memalign() man page: | ||
53 | // "alignment must be a power of two and a multiple of sizeof(void *)" | ||
54 | // volk_get_alignment() could return 1 for some machines (e.g. generic_orc) | ||
55 | if (alignment == 1) { | ||
56 | return malloc(size); | ||
57 | } | ||
58 | void* ptr; | ||
59 | int err = posix_memalign(&ptr, alignment, size); | ||
60 | if (err != 0) { | ||
61 | ptr = NULL; | ||
62 | fprintf(stderr, | ||
63 | "VOLK: Error allocating memory " | ||
64 | "(posix_memalign: error %d: %s)\n", | ||
65 | err, | ||
66 | strerror(err)); | ||
67 | } | ||
68 | #elif defined(_MSC_VER) || defined(__MINGW32__) | ||
69 | void* ptr = _aligned_malloc(size, alignment); | ||
70 | #else | ||
71 | 3536 | void* ptr = aligned_alloc(alignment, size); | |
72 | #endif | ||
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3536 times.
|
3536 | if (ptr == NULL) { |
74 | ✗ | fprintf(stderr, | |
75 | "VOLK: Error allocating memory (aligned_alloc/_aligned_malloc)\n"); | ||
76 | } | ||
77 | 3536 | return ptr; | |
78 | } | ||
79 | |||
80 | 3524 | void volk_free(void* ptr) | |
81 | { | ||
82 | #if defined(_MSC_VER) || defined(__MINGW32__) | ||
83 | _aligned_free(ptr); | ||
84 | #else | ||
85 | 3524 | free(ptr); | |
86 | #endif | ||
87 | 3524 | } | |
88 |