1 /* -*- C++ -*-
2  * File: libraw_alloc.h
3  * Copyright 2008-2018 LibRaw LLC (info@libraw.org)
4  * Created: Sat Mar  22, 2008
5  *
6  * LibRaw C++ interface
7  *
8 LibRaw is free software; you can redistribute it and/or modify
9 it under the terms of the one of two licenses as you choose:
10 
11 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13 
14 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16 
17  */
18 
19 #ifndef __LIBRAW_ALLOC_H
20 #define __LIBRAW_ALLOC_H
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include "libraw_const.h"
25 
26 #ifdef __cplusplus
27 
28 #define LIBRAW_MSIZE 512
29 
30 class DllDef libraw_memmgr
31 {
32 public:
libraw_memmgr(unsigned ee)33   libraw_memmgr(unsigned ee) : extra_bytes(ee)
34   {
35     size_t alloc_sz = LIBRAW_MSIZE * sizeof(void *);
36     mems = (void **)::malloc(alloc_sz);
37     memset(mems, 0, alloc_sz);
38     alloc_cnt = 0;
39   }
~libraw_memmgr()40   ~libraw_memmgr()
41   {
42     cleanup();
43     ::free(mems);
44   }
malloc(size_t sz)45   void *malloc(size_t sz)
46   {
47 #ifdef LIBRAW_MEMPOOL_CHECK
48     if(alloc_cnt >= LIBRAW_MSIZE)
49        throw LIBRAW_EXCEPTION_ALLOC;
50 #endif
51 #ifdef LIBRAW_USE_CALLOC_INSTEAD_OF_MALLOC
52     void *ptr = ::calloc(sz + extra_bytes,1);
53 #else
54     void *ptr = ::malloc(sz + extra_bytes);
55 #endif
56     mem_ptr(ptr);
57     return ptr;
58   }
calloc(size_t n,size_t sz)59   void *calloc(size_t n, size_t sz)
60   {
61 #ifdef LIBRAW_MEMPOOL_CHECK
62     if(alloc_cnt >= LIBRAW_MSIZE)
63        throw LIBRAW_EXCEPTION_ALLOC;
64 #endif
65     void *ptr = ::calloc(n + (extra_bytes + sz - 1) / (sz ? sz : 1), sz);
66     mem_ptr(ptr);
67     return ptr;
68   }
realloc(void * ptr,size_t newsz)69   void *realloc(void *ptr, size_t newsz)
70   {
71 #ifdef LIBRAW_MEMPOOL_CHECK
72     if(alloc_cnt >= LIBRAW_MSIZE)
73        throw LIBRAW_EXCEPTION_ALLOC;
74 #endif
75     void *ret = ::realloc(ptr, newsz + extra_bytes);
76     forget_ptr(ptr);
77     mem_ptr(ret);
78     return ret;
79   }
free(void * ptr)80   void free(void *ptr)
81   {
82     forget_ptr(ptr);
83     ::free(ptr);
84   }
cleanup(void)85   void cleanup(void)
86   {
87     for (int i = 0; i < LIBRAW_MSIZE; i++)
88       if (mems[i])
89       {
90         ::free(mems[i]);
91         alloc_cnt--;
92         mems[i] = NULL;
93       }
94   }
95 
96 private:
97   void **mems;
98   unsigned alloc_cnt;
99   unsigned extra_bytes;
mem_ptr(void * ptr)100   void mem_ptr(void *ptr)
101   {
102     if (ptr)
103       for (int i = 0; i < LIBRAW_MSIZE; i++)
104         if (!mems[i])
105         {
106           mems[i] = ptr;
107           alloc_cnt++;
108           break;
109         }
110   }
forget_ptr(void * ptr)111   void forget_ptr(void *ptr)
112   {
113     if (ptr)
114       for (int i = 0; i < LIBRAW_MSIZE; i++)
115         if (mems[i] == ptr)
116         {
117           mems[i] = NULL;
118           alloc_cnt--;
119           break;
120         }
121   }
122 };
123 
124 #endif /* C++ */
125 
126 #endif
127