File: alloc.h

package info (click to toggle)
lsp-plugins 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,856 kB
  • sloc: cpp: 427,831; xml: 57,779; makefile: 9,961; php: 1,005; sh: 18
file content (127 lines) | stat: -rw-r--r-- 4,010 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
 *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
 *
 * This file is part of lsp-common-lib
 * Created on: 3 апр. 2020 г.
 *
 * lsp-common-lib is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * lsp-common-lib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with lsp-common-lib. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef LSP_PLUG_IN_COMMON_ALLOC_H_
#define LSP_PLUG_IN_COMMON_ALLOC_H_

#include <lsp-plug.in/common/version.h>
#include <lsp-plug.in/common/types.h>
#include <lsp-plug.in/stdlib/stdlib.h>

namespace lsp
{
    inline size_t align_size(size_t size, size_t align)
    {
        size_t off = size % align;
        return (off) ? (size + align - off) : size;
    }

    template <class T>
        inline T *align_ptr(T *src, size_t align = DEFAULT_ALIGN)
        {
            uintptr_t x     = uintptr_t(src);
            uintptr_t off   = x % align;
            return (off) ?
                reinterpret_cast<T *>(x + align - off) :
                src;
        }

    template <class T>
        inline bool is_ptr_aligned(T *src, size_t align = DEFAULT_ALIGN)
        {
            ptrdiff_t x     = ptrdiff_t(src);
            return !(x % align);
        }

    template <class T>
        inline T *lsp_malloc(size_t count = 1)
        {
            return static_cast<T *>(::malloc(sizeof(T) * count));
        }

    /** Allocate aligned pointer
     *
     * @param ptr reference to pointer to store allocated pointer for future free() operation
     * @param count number of elements to allocate
     * @param align alignment, should be power of 2, by default DEFAULT_ALIGN
     * @return aligned pointer as a result of alignment of ptr to align boundary or NULL if allocation failed
     * @example
     *      void *x = NULL;
     *      float *a = alloc_aligned<float>(x, 1000); // Allocate 1000 floats aligned to DEFAULT_ALIGN boundary
     *      if (a == NULL)
     *          return ERROR;
     *      // Do some stuff
     *      free_aligned(x);
     *      a = NULL;
     */
    template <class T, class P>
        inline T *alloc_aligned(P * &ptr, size_t count, size_t align=DEFAULT_ALIGN)
        {
            // Check for power of 2
            if ((!align) || (align & (align-1)))
                return NULL;

            // Allocate data
            void *p         = ::malloc((count * sizeof(T)) + align);
            if (p == NULL)
                return NULL;

            // Store pointer
            ptr             = reinterpret_cast<P *>(p);

            // Return aligned pointer
            ptrdiff_t x     = ptrdiff_t(p);
            ptrdiff_t mask  = align-1;
            return reinterpret_cast<T *>((x & mask) ? ((x + align)&(~mask)) : x);
        }

    /** Free aligned pointer and write NULL to it
     *
     * @param ptr pointer to free
     */
    template <class P>
        inline void free_aligned(P * &ptr)
        {
            if (ptr == NULL)
                return;
            P *tptr = ptr;
            ptr = NULL;
            ::free(tptr);
        }

    /**
     * Seed the address
     * @param ptr address to seed
     * @return seed value
     */
    inline uint32_t seed_addr(const void *ptr)
    {
    #if defined(ARCH_I386)
        return uint32_t(ptr);
    #elif defined(ARCH_X86_64)
        return uint32_t(ptrdiff_t(ptr)) ^ uint32_t(ptrdiff_t(ptr) >> 32);
    #else
        return uint32_t(ptrdiff_t(ptr));
    #endif
    }
}

#endif /* LSP_PLUG_IN_COMMON_ALLOC_H_ */