1 //------------------------------------------------------------------------------
2 // GB_malloc_memory: wrapper for malloc
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 // A wrapper for malloc. Space is not initialized.
11
12 #include "GB.h"
13
14 //------------------------------------------------------------------------------
15 // GB_malloc_helper: use malloc to allocate an uninitialized memory block
16 //------------------------------------------------------------------------------
17
GB_malloc_helper(size_t * size,bool malloc_tracking)18 static inline void *GB_malloc_helper
19 (
20 // input/output:
21 size_t *size, // on input: # of bytes requested
22 // on output: # of bytes actually allocated
23 // input:
24 bool malloc_tracking
25 )
26 {
27 void *p = NULL ;
28
29 // determine the next higher power of 2
30 (*size) = GB_IMAX (*size, 8) ;
31 int k = GB_CEIL_LOG2 (*size) ;
32
33 // if available, get the block from the pool
34 if (GB_Global_free_pool_limit_get (k) > 0)
35 {
36 // round up the size to the nearest power of two
37 (*size) = ((size_t) 1) << k ;
38 p = GB_Global_free_pool_get (k) ;
39 // if (p != NULL) printf ("malloc from pool: %p %ld\n", p, *size) ;
40 }
41
42 if (p == NULL)
43 {
44 // no block in the free_pool, so allocate it
45
46 // if (GB_Global_rmm_get ( ))
47 // {
48 // p = GB_rmm_alloc (size) ;
49 // }
50 // else
51 {
52 p = GB_Global_malloc_function (*size) ;
53 }
54
55 if (p != NULL && malloc_tracking)
56 {
57 // success
58 GB_Global_nmalloc_increment ( ) ;
59 }
60 // printf ("hard malloc %p %ld\n", p, *size) ;
61 }
62 // GB_Global_free_pool_dump (2) ; GB_Global_memtable_dump ( ) ;
63
64 return (p) ;
65 }
66
67 //------------------------------------------------------------------------------
68 // GB_malloc_memory
69 //------------------------------------------------------------------------------
70
71 GB_PUBLIC // accessed by the MATLAB tests in GraphBLAS/Test only
GB_malloc_memory(size_t nitems,size_t size_of_item,size_t * size_allocated)72 void *GB_malloc_memory // pointer to allocated block of memory
73 (
74 size_t nitems, // number of items to allocate
75 size_t size_of_item, // sizeof each item
76 // output
77 size_t *size_allocated // # of bytes actually allocated
78 )
79 {
80
81 //--------------------------------------------------------------------------
82 // check inputs
83 //--------------------------------------------------------------------------
84
85 ASSERT (size_allocated != NULL) ;
86
87 void *p ;
88 size_t size ;
89
90 // make sure at least one item is allocated
91 nitems = GB_IMAX (1, nitems) ;
92
93 // make sure at least one byte is allocated
94 size_of_item = GB_IMAX (1, size_of_item) ;
95
96 bool ok = GB_size_t_multiply (&size, nitems, size_of_item) ;
97 if (!ok || nitems > GxB_INDEX_MAX || size_of_item > GxB_INDEX_MAX)
98 {
99 // overflow
100 (*size_allocated) = 0 ;
101 return (NULL) ;
102 }
103
104 //--------------------------------------------------------------------------
105 // allocate the memory block
106 //--------------------------------------------------------------------------
107
108 if (GB_Global_malloc_tracking_get ( ))
109 {
110
111 //----------------------------------------------------------------------
112 // for memory usage testing only
113 //----------------------------------------------------------------------
114
115 // brutal memory debug; pretend to fail if (count-- <= 0).
116 bool pretend_to_fail = false ;
117 if (GB_Global_malloc_debug_get ( ))
118 {
119 pretend_to_fail = GB_Global_malloc_debug_count_decrement ( ) ;
120 }
121
122 // allocate the memory
123 if (pretend_to_fail)
124 {
125 p = NULL ;
126 }
127 else
128 {
129 p = GB_malloc_helper (&size, true) ;
130 }
131
132 }
133 else
134 {
135
136 //----------------------------------------------------------------------
137 // normal use, in production
138 //----------------------------------------------------------------------
139
140 p = GB_malloc_helper (&size, false) ;
141 }
142
143 //--------------------------------------------------------------------------
144 // return result
145 //--------------------------------------------------------------------------
146
147 (*size_allocated) = (p == NULL) ? 0 : size ;
148 ASSERT (GB_IMPLIES (p != NULL, size == GB_Global_memtable_size (p))) ;
149 // GB_Global_free_pool_dump (2) ;
150 return (p) ;
151 }
152
153