memory.cc revision 227825
1227825Stheraven/**
2227825Stheraven * memory.cc - Contains stub definition of C++ new/delete operators.
3227825Stheraven *
4227825Stheraven * These definitions are intended to be used for testing and are weak symbols
5227825Stheraven * to allow them to be replaced by definitions from a STL implementation.
6227825Stheraven * These versions simply wrap malloc() and free(), they do not provide a
7227825Stheraven * C++-specific allocator.
8227825Stheraven */
9227825Stheraven
10227825Stheraven#include <stddef.h>
11227825Stheraven#include <stdlib.h>
12227825Stheraven#include "stdexcept.h"
13227825Stheraven
14227825Stheravennamespace std
15227825Stheraven{
16227825Stheraven	struct nothrow_t {};
17227825Stheraven}
18227825Stheraven
19227825Stheraven
20227825Stheraven/// The type of the function called when allocation fails.
21227825Stheraventypedef void (*new_handler)();
22227825Stheraven/**
23227825Stheraven * The function to call when allocation fails.  By default, there is no
24227825Stheraven * handler and a bad allocation exception is thrown if an allocation fails.
25227825Stheraven */
26227825Stheravenstatic new_handler new_handl;
27227825Stheraven
28227825Stheravennamespace std
29227825Stheraven{
30227825Stheraven	/**
31227825Stheraven	 * Sets a function to be called when there is a failure in new.
32227825Stheraven	 */
33227825Stheraven	__attribute__((weak))
34227825Stheraven	new_handler set_new_handler(new_handler handler)
35227825Stheraven	{
36227825Stheraven		return __sync_lock_test_and_set(&new_handl, handler);
37227825Stheraven	}
38227825Stheraven}
39227825Stheraven
40227825Stheraven
41227825Stheraven__attribute__((weak))
42227825Stheravenvoid* operator new(size_t size)
43227825Stheraven{
44227825Stheraven	void * mem = malloc(size);
45227825Stheraven	while (0 == mem)
46227825Stheraven	{
47227825Stheraven		if (0 != new_handl)
48227825Stheraven		{
49227825Stheraven			new_handl();
50227825Stheraven		}
51227825Stheraven		else
52227825Stheraven		{
53227825Stheraven			throw std::bad_alloc();
54227825Stheraven		}
55227825Stheraven		mem = malloc(size);
56227825Stheraven	}
57227825Stheraven
58227825Stheraven	return mem;
59227825Stheraven}
60227825Stheraven
61227825Stheraven__attribute__((weak))
62227825Stheravenvoid* operator new(size_t size, const std::nothrow_t &) throw()
63227825Stheraven{
64227825Stheraven	void *mem = malloc(size);
65227825Stheraven	while (0 == mem)
66227825Stheraven	{
67227825Stheraven		if (0 != new_handl)
68227825Stheraven		{
69227825Stheraven			try
70227825Stheraven			{
71227825Stheraven				new_handl();
72227825Stheraven			}
73227825Stheraven			catch (...)
74227825Stheraven			{
75227825Stheraven				// nothrow operator new should return NULL in case of
76227825Stheraven				// std::bad_alloc exception in new handler
77227825Stheraven				return NULL;
78227825Stheraven			}
79227825Stheraven		}
80227825Stheraven		else
81227825Stheraven		{
82227825Stheraven			return NULL;
83227825Stheraven		}
84227825Stheraven		mem = malloc(size);
85227825Stheraven	}
86227825Stheraven
87227825Stheraven	return mem;
88227825Stheraven}
89227825Stheraven
90227825Stheraven
91227825Stheraven__attribute__((weak))
92227825Stheravenvoid operator delete(void * ptr)
93227825Stheraven{
94227825Stheraven	free(ptr);
95227825Stheraven}
96227825Stheraven
97227825Stheraven
98227825Stheraven__attribute__((weak))
99227825Stheravenvoid * operator new[](size_t size)
100227825Stheraven{
101227825Stheraven	return ::operator new(size);
102227825Stheraven}
103227825Stheraven
104227825Stheraven
105227825Stheraven__attribute__((weak))
106227825Stheravenvoid operator delete[](void * ptr)
107227825Stheraven{
108227825Stheraven	::operator delete(ptr);
109227825Stheraven}
110227825Stheraven
111227825Stheraven
112