Loading...
Searching...
No Matches
ojph_mem.h
Go to the documentation of this file.
//***************************************************************************/
// This software is released under the 2-Clause BSD license, included
// below.
//
// Copyright (c) 2019, Aous Naman
// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
// Copyright (c) 2019, The University of New South Wales, Australia
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//***************************************************************************/
// This file is part of the OpenJPH software implementation.
// File: ojph_mem.h
// Author: Aous Naman
// Date: 28 August 2019
//***************************************************************************/
#ifndef OJPH_MEM_H
#define OJPH_MEM_H
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <type_traits>
#include "ojph_arch.h"
#include "ojph_message.h"
namespace ojph {
extern "C" {
void* ojph_aligned_malloc(size_t alignment, size_t size);
void ojph_aligned_free(void* pointer);
}
class mem_fixed_allocator
{
public:
mem_fixed_allocator()
{
store = NULL; allocated_data = 0;
restart();
}
~mem_fixed_allocator()
{
if (store) free(store);
}
template<typename T>
void pre_alloc_data(size_t num_ele, ui32 pre_size)
{
pre_alloc_local<T, byte_alignment>(num_ele, pre_size, size_data);
}
template<typename T>
void pre_alloc_obj(size_t num_ele)
{
pre_alloc_local<T, object_alignment>(num_ele, 0, size_obj);
}
void alloc()
{
assert(preallocation);
if (size_data + size_obj > allocated_data)
{
// We should be here once only, because, in subsequent, calls we
// should have size_data + size_obj <= allocated_data
free(store);
allocated_data = size_data + size_obj;
allocated_data = allocated_data + (allocated_data + 19) / 20; // 5%
store = malloc(allocated_data);
if (store == NULL)
OJPH_ERROR(0x00090001, "malloc failed");
}
avail_obj = store;
avail_data = (ui8*)store + size_obj;
avail_size_obj = size_obj;
avail_size_data = size_data;
preallocation = false;
}
void restart()
{
avail_obj = avail_data = NULL;
avail_size_obj = avail_size_data = size_obj = size_data = 0;
preallocation = true;
}
template<typename T>
T* post_alloc_data(size_t num_ele, ui32 pre_size)
{
return post_alloc_local<T, byte_alignment>
(num_ele, pre_size, avail_size_data, avail_data);
}
template<typename T>
T* post_alloc_obj(size_t num_ele)
{
return post_alloc_local<T, object_alignment>
(num_ele, 0, avail_size_obj, avail_obj);
}
private:
template<typename T, int N>
void pre_alloc_local(size_t num_ele, ui32 pre_size, size_t& sz)
{
assert(preallocation);
num_ele = calc_aligned_size<T, N>(num_ele);
size_t total = (num_ele + pre_size) * sizeof(T);
total += 2*N - 1;
sz += total;
}
template<typename T, int N>
T* post_alloc_local(size_t num_ele, ui32 pre_size,
size_t& avail_sz, void*& avail_p)
{
assert(!preallocation);
num_ele = calc_aligned_size<T, N>(num_ele);
size_t total = (num_ele + pre_size) * sizeof(T);
total += 2*N - 1;
T* p = align_ptr<T, N>((T*)avail_p + pre_size);
avail_p = (ui8*)avail_p + total;
avail_sz -= total;
assert((avail_sz & 0x8000000000000000llu) == 0);
return p;
}
void *store, *avail_data, *avail_obj;
size_t size_data, size_obj, avail_size_obj, avail_size_data;
size_t allocated_data;
bool preallocation;
};
class line_buf
{
public:
enum : ui32 {
LFT_UNDEFINED = 0x00, // Type is undefined/uninitialized
// These flags reflects data size in bytes
LFT_BYTE = 0x01, // Set when data is 1 byte (not used)
LFT_16BIT = 0x02, // Set when data is 2 bytes (not used)
LFT_32BIT = 0x04, // Set when data is 4 bytes
LFT_64BIT = 0x08, // Set when data is 8 bytes
LFT_INTEGER = 0x10, // Set when data is an integer, in other words
// 32bit integer, not 32bit float
LFT_SIZE_MASK = 0x0F, // To extract data size
};
public:
line_buf() : size(0), pre_size(0), flags(LFT_UNDEFINED), i32(0) {}
template<typename T>
void wrap(T *buffer, size_t num_ele, ui32 pre_size);
size_t size;
ui32 pre_size;
ui32 flags;
union {
si32* i32; // 32bit integer type, used for lossless compression
si64* i64; // 64bit integer type, used for lossless compression
float* f32; // float type, used for lossy compression
void* p; // no type is associated with the pointer
};
};
struct lifting_buf
{
lifting_buf() { line = NULL; active = false; }
line_buf *line;
bool active;
};
struct coded_lists
{
coded_lists(ui32 size)
{
next_list = NULL;
avail_size = buf_size = size;
this->buf = (ui8*)this + sizeof(coded_lists);
}
coded_lists* next_list;
ui32 buf_size;
ui32 avail_size;
ui8* buf;
};
class mem_elastic_allocator
{
/*
advantage: allocate large chunks of memory
*/
public:
mem_elastic_allocator(ui32 chunk_size)
: chunk_size(chunk_size)
{ cur_store = store = avail = NULL; total_allocated = 0; }
~mem_elastic_allocator()
{
while (store) { // stores in use
stores_list* t = store->next_store;
free(store);
store = t;
}
while (avail) { // available stores
stores_list* t = avail->next_store;
free(avail);
avail = t;
}
}
void get_buffer(ui32 needed_bytes, coded_lists*& p);
void restart();
private:
struct stores_list
{
// Payload (coded_lists + bitstream) must start at a multiple of 16 bytes.
// Otherwise coded_lists::buf can be 4 mod 8, which causes misalignment
// on 32-bit architectures. So round sizeof(stores_list) to next
// multiple of 16.
static constexpr ui32 stores_list_size16()
{
return (ui32) ((sizeof (stores_list) + 15u) & ~15u);
}
stores_list(ui32 available_bytes)
{
this->next_store = NULL;
this->orig_size = this->available = available_bytes;
this->orig_data = this->data = (ui8*)this + stores_list_size16();
}
void restart()
{
this->next_store = NULL;
this->available = this->orig_size;
this->data = this->orig_data;
}
static ui32 eval_store_bytes(ui32 available_bytes)
{ // calculates how many bytes need to be allocated
return available_bytes + stores_list_size16();
}
stores_list *next_store;
ui8 *orig_data, *data;
ui32 orig_size, available;
};
stores_list* allocate(stores_list** list, ui32 extended_bytes);
stores_list *store;
stores_list *cur_store;
stores_list *avail;
size_t total_allocated;
const ui32 chunk_size;
};
}
#endif // !OJPH_MEM_H
ojph::line_buf
Definition ojph_mem.h:161
ojph::line_buf::i64
si64 * i64
Definition ojph_mem.h:186
ojph::line_buf::size
size_t size
Definition ojph_mem.h:181
ojph::line_buf::p
void * p
Definition ojph_mem.h:188
ojph::line_buf::flags
ui32 flags
Definition ojph_mem.h:183
ojph::line_buf::f32
float * f32
Definition ojph_mem.h:187
ojph::line_buf::line_buf
line_buf()
Definition ojph_mem.h:176
ojph::line_buf::pre_size
ui32 pre_size
Definition ojph_mem.h:182
ojph::line_buf::wrap
void wrap(T *buffer, size_t num_ele, ui32 pre_size)
ojph::line_buf::LFT_INTEGER
@ LFT_INTEGER
Definition ojph_mem.h:170
ojph::line_buf::LFT_UNDEFINED
@ LFT_UNDEFINED
Definition ojph_mem.h:164
ojph::line_buf::LFT_SIZE_MASK
@ LFT_SIZE_MASK
Definition ojph_mem.h:172
ojph::line_buf::LFT_32BIT
@ LFT_32BIT
Definition ojph_mem.h:168
ojph::line_buf::LFT_BYTE
@ LFT_BYTE
Definition ojph_mem.h:166
ojph::line_buf::LFT_64BIT
@ LFT_64BIT
Definition ojph_mem.h:169
ojph::line_buf::LFT_16BIT
@ LFT_16BIT
Definition ojph_mem.h:167
ojph::line_buf::i32
si32 * i32
Definition ojph_mem.h:185
ojph::mem_elastic_allocator::chunk_size
const ui32 chunk_size
Definition ojph_mem.h:283
ojph::mem_elastic_allocator::get_buffer
void get_buffer(ui32 needed_bytes, coded_lists *&p)
Definition ojph_mem.cpp:113
ojph::mem_elastic_allocator::store
stores_list * store
Definition ojph_mem.h:279
ojph::mem_elastic_allocator::restart
void restart()
Definition ojph_mem.cpp:133
ojph::mem_elastic_allocator::allocate
stores_list * allocate(stores_list **list, ui32 extended_bytes)
Definition ojph_mem.cpp:92
ojph::mem_elastic_allocator::~mem_elastic_allocator
~mem_elastic_allocator()
Definition ojph_mem.h:228
ojph::mem_elastic_allocator::mem_elastic_allocator
mem_elastic_allocator(ui32 chunk_size)
Definition ojph_mem.h:224
ojph::mem_elastic_allocator::avail
stores_list * avail
Definition ojph_mem.h:281
ojph::mem_elastic_allocator::cur_store
stores_list * cur_store
Definition ojph_mem.h:280
ojph::mem_elastic_allocator::total_allocated
size_t total_allocated
Definition ojph_mem.h:282
ojph::mem_fixed_allocator::pre_alloc_data
void pre_alloc_data(size_t num_ele, ui32 pre_size)
Definition ojph_mem.h:72
ojph::mem_fixed_allocator::preallocation
bool preallocation
Definition ojph_mem.h:156
ojph::mem_fixed_allocator::restart
void restart()
Definition ojph_mem.h:104
ojph::mem_fixed_allocator::alloc
void alloc()
Definition ojph_mem.h:83
ojph::mem_fixed_allocator::pre_alloc_obj
void pre_alloc_obj(size_t num_ele)
Definition ojph_mem.h:78
ojph::mem_fixed_allocator::avail_obj
void * avail_obj
Definition ojph_mem.h:153
ojph::mem_fixed_allocator::store
void * store
Definition ojph_mem.h:153
ojph::mem_fixed_allocator::pre_alloc_local
void pre_alloc_local(size_t num_ele, ui32 pre_size, size_t &sz)
Definition ojph_mem.h:127
ojph::mem_fixed_allocator::size_data
size_t size_data
Definition ojph_mem.h:154
ojph::mem_fixed_allocator::post_alloc_data
T * post_alloc_data(size_t num_ele, ui32 pre_size)
Definition ojph_mem.h:112
ojph::mem_fixed_allocator::avail_data
void * avail_data
Definition ojph_mem.h:153
ojph::mem_fixed_allocator::avail_size_data
size_t avail_size_data
Definition ojph_mem.h:154
ojph::mem_fixed_allocator::avail_size_obj
size_t avail_size_obj
Definition ojph_mem.h:154
ojph::mem_fixed_allocator::allocated_data
size_t allocated_data
Definition ojph_mem.h:155
ojph::mem_fixed_allocator::~mem_fixed_allocator
~mem_fixed_allocator()
Definition ojph_mem.h:66
ojph::mem_fixed_allocator::mem_fixed_allocator
mem_fixed_allocator()
Definition ojph_mem.h:61
ojph::mem_fixed_allocator::size_obj
size_t size_obj
Definition ojph_mem.h:154
ojph::mem_fixed_allocator::post_alloc_obj
T * post_alloc_obj(size_t num_ele)
Definition ojph_mem.h:119
ojph::mem_fixed_allocator::post_alloc_local
T * post_alloc_local(size_t num_ele, ui32 pre_size, size_t &avail_sz, void *&avail_p)
Definition ojph_mem.h:138
ojph
Definition ojph_img_io.h:52
ojph::ojph_aligned_malloc
void * ojph_aligned_malloc(size_t alignment, size_t size)
ojph::si64
int64_t si64
Definition ojph_defs.h:57
ojph::calc_aligned_size
size_t calc_aligned_size(size_t size)
Definition ojph_arch.h:343
ojph::align_ptr
T * align_ptr(T *ptr)
Definition ojph_arch.h:353
ojph::si32
int32_t si32
Definition ojph_defs.h:55
ojph::ui32
uint32_t ui32
Definition ojph_defs.h:54
ojph::ui8
uint8_t ui8
Definition ojph_defs.h:50
ojph::ojph_aligned_free
void ojph_aligned_free(void *pointer)
ojph_arch.h
ojph_message.h
OJPH_ERROR
#define OJPH_ERROR(t,...)
Definition ojph_message.h:288
ojph::coded_lists
Definition ojph_mem.h:202
ojph::coded_lists::buf_size
ui32 buf_size
Definition ojph_mem.h:211
ojph::coded_lists::coded_lists
coded_lists(ui32 size)
Definition ojph_mem.h:203
ojph::coded_lists::buf
ui8 * buf
Definition ojph_mem.h:213
ojph::coded_lists::next_list
coded_lists * next_list
Definition ojph_mem.h:210
ojph::coded_lists::avail_size
ui32 avail_size
Definition ojph_mem.h:212
ojph::lifting_buf::lifting_buf
lifting_buf()
Definition ojph_mem.h:195
ojph::lifting_buf::line
line_buf * line
Definition ojph_mem.h:196
ojph::lifting_buf::active
bool active
Definition ojph_mem.h:197
ojph::mem_elastic_allocator::stores_list
Definition ojph_mem.h:247
ojph::mem_elastic_allocator::stores_list::eval_store_bytes
static ui32 eval_store_bytes(ui32 available_bytes)
Definition ojph_mem.h:268
ojph::mem_elastic_allocator::stores_list::available
ui32 available
Definition ojph_mem.h:274
ojph::mem_elastic_allocator::stores_list::data
ui8 * data
Definition ojph_mem.h:273
ojph::mem_elastic_allocator::stores_list::stores_list
stores_list(ui32 available_bytes)
Definition ojph_mem.h:256
ojph::mem_elastic_allocator::stores_list::restart
void restart()
Definition ojph_mem.h:262
ojph::mem_elastic_allocator::stores_list::orig_data
ui8 * orig_data
Definition ojph_mem.h:273
ojph::mem_elastic_allocator::stores_list::next_store
stores_list * next_store
Definition ojph_mem.h:272
ojph::mem_elastic_allocator::stores_list::orig_size
ui32 orig_size
Definition ojph_mem.h:274
ojph::mem_elastic_allocator::stores_list::stores_list_size16
static constexpr ui32 stores_list_size16()
Definition ojph_mem.h:252
ojph::size
Definition ojph_base.h:48