xref: /freebsd/contrib/libcxxrt/memory.cc (revision 70e0bbedef95258a4dadc996d641a9bebd3f107d)
1 /**
2  * memory.cc - Contains stub definition of C++ new/delete operators.
3  *
4  * These definitions are intended to be used for testing and are weak symbols
5  * to allow them to be replaced by definitions from a STL implementation.
6  * These versions simply wrap malloc() and free(), they do not provide a
7  * C++-specific allocator.
8  */
9 
10 #include <stddef.h>
11 #include <stdlib.h>
12 #include "stdexcept.h"
13 
14 #if !__has_builtin(__sync_swap)
15 #define __sync_swap __sync_lock_test_and_set
16 #endif
17 
18 namespace std
19 {
20 	struct nothrow_t {};
21 }
22 
23 
24 /// The type of the function called when allocation fails.
25 typedef void (*new_handler)();
26 /**
27  * The function to call when allocation fails.  By default, there is no
28  * handler and a bad allocation exception is thrown if an allocation fails.
29  */
30 static new_handler new_handl;
31 
32 namespace std
33 {
34 	/**
35 	 * Sets a function to be called when there is a failure in new.
36 	 */
37 	__attribute__((weak))
38 	new_handler set_new_handler(new_handler handler)
39 	{
40 		return __sync_swap(&new_handl, handler);
41 	}
42 }
43 
44 
45 __attribute__((weak))
46 void* operator new(size_t size)
47 {
48 	void * mem = malloc(size);
49 	while (0 == mem)
50 	{
51 		if (0 != new_handl)
52 		{
53 			new_handl();
54 		}
55 		else
56 		{
57 			throw std::bad_alloc();
58 		}
59 		mem = malloc(size);
60 	}
61 
62 	return mem;
63 }
64 
65 __attribute__((weak))
66 void* operator new(size_t size, const std::nothrow_t &) throw()
67 {
68 	void *mem = malloc(size);
69 	while (0 == mem)
70 	{
71 		if (0 != new_handl)
72 		{
73 			try
74 			{
75 				new_handl();
76 			}
77 			catch (...)
78 			{
79 				// nothrow operator new should return NULL in case of
80 				// std::bad_alloc exception in new handler
81 				return NULL;
82 			}
83 		}
84 		else
85 		{
86 			return NULL;
87 		}
88 		mem = malloc(size);
89 	}
90 
91 	return mem;
92 }
93 
94 
95 __attribute__((weak))
96 void operator delete(void * ptr)
97 {
98 	free(ptr);
99 }
100 
101 
102 __attribute__((weak))
103 void * operator new[](size_t size)
104 {
105 	return ::operator new(size);
106 }
107 
108 
109 __attribute__((weak))
110 void operator delete[](void * ptr) throw()
111 {
112 	::operator delete(ptr);
113 }
114 
115 
116