1232950Stheraven/*
2232950Stheraven * Copyright 2010-2011 PathScale, Inc. All rights reserved.
3232950Stheraven *
4232950Stheraven * Redistribution and use in source and binary forms, with or without
5232950Stheraven * modification, are permitted provided that the following conditions are met:
6232950Stheraven *
7232950Stheraven * 1. Redistributions of source code must retain the above copyright notice,
8232950Stheraven *    this list of conditions and the following disclaimer.
9232950Stheraven *
10232950Stheraven * 2. Redistributions in binary form must reproduce the above copyright notice,
11232950Stheraven *    this list of conditions and the following disclaimer in the documentation
12232950Stheraven *    and/or other materials provided with the distribution.
13232950Stheraven *
14232950Stheraven * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
15232950Stheraven * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16232950Stheraven * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17232950Stheraven * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
18232950Stheraven * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19232950Stheraven * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20232950Stheraven * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21232950Stheraven * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22232950Stheraven * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23232950Stheraven * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24232950Stheraven * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25232950Stheraven */
26232950Stheraven
27227825Stheraven/**
28227825Stheraven * memory.cc - Contains stub definition of C++ new/delete operators.
29227825Stheraven *
30227825Stheraven * These definitions are intended to be used for testing and are weak symbols
31227825Stheraven * to allow them to be replaced by definitions from a STL implementation.
32227825Stheraven * These versions simply wrap malloc() and free(), they do not provide a
33227825Stheraven * C++-specific allocator.
34227825Stheraven */
35227825Stheraven
36227825Stheraven#include <stddef.h>
37227825Stheraven#include <stdlib.h>
38227825Stheraven#include "stdexcept.h"
39245304Stheraven#include "atomic.h"
40227825Stheraven
41232950Stheraven
42227825Stheravennamespace std
43227825Stheraven{
44227825Stheraven	struct nothrow_t {};
45227825Stheraven}
46227825Stheraven
47227825Stheraven
48227825Stheraven/// The type of the function called when allocation fails.
49227825Stheraventypedef void (*new_handler)();
50227825Stheraven/**
51227825Stheraven * The function to call when allocation fails.  By default, there is no
52227825Stheraven * handler and a bad allocation exception is thrown if an allocation fails.
53227825Stheraven */
54227825Stheravenstatic new_handler new_handl;
55227825Stheraven
56227825Stheravennamespace std
57227825Stheraven{
58227825Stheraven	/**
59227825Stheraven	 * Sets a function to be called when there is a failure in new.
60227825Stheraven	 */
61227825Stheraven	__attribute__((weak))
62227825Stheraven	new_handler set_new_handler(new_handler handler)
63227825Stheraven	{
64245304Stheraven		return ATOMIC_SWAP(&new_handl, handler);
65227825Stheraven	}
66245304Stheraven	__attribute__((weak))
67245304Stheraven	new_handler get_new_handler(void)
68245304Stheraven	{
69245304Stheraven		return ATOMIC_LOAD(&new_handl);
70245304Stheraven	}
71227825Stheraven}
72227825Stheraven
73227825Stheraven
74227825Stheraven__attribute__((weak))
75227825Stheravenvoid* operator new(size_t size)
76227825Stheraven{
77245304Stheraven	if (0 == size)
78245304Stheraven	{
79245304Stheraven		size = 1;
80245304Stheraven	}
81227825Stheraven	void * mem = malloc(size);
82227825Stheraven	while (0 == mem)
83227825Stheraven	{
84245304Stheraven		new_handler h = std::get_new_handler();
85245304Stheraven		if (0 != h)
86227825Stheraven		{
87245304Stheraven			h();
88227825Stheraven		}
89227825Stheraven		else
90227825Stheraven		{
91227825Stheraven			throw std::bad_alloc();
92227825Stheraven		}
93227825Stheraven		mem = malloc(size);
94227825Stheraven	}
95227825Stheraven
96227825Stheraven	return mem;
97227825Stheraven}
98227825Stheraven
99227825Stheraven__attribute__((weak))
100227825Stheravenvoid* operator new(size_t size, const std::nothrow_t &) throw()
101227825Stheraven{
102253159Stheraven	try {
103253159Stheraven		return :: operator new(size);
104253159Stheraven	} catch (...) {
105253159Stheraven		// nothrow operator new should return NULL in case of
106253159Stheraven		// std::bad_alloc exception in new handler
107253159Stheraven		return NULL;
108245304Stheraven	}
109227825Stheraven}
110227825Stheraven
111227825Stheraven
112227825Stheraven__attribute__((weak))
113227825Stheravenvoid operator delete(void * ptr)
114253159Stheraven#if __cplusplus < 201000L
115253159Stheraventhrow()
116253159Stheraven#endif
117227825Stheraven{
118227825Stheraven	free(ptr);
119227825Stheraven}
120227825Stheraven
121227825Stheraven
122227825Stheraven__attribute__((weak))
123227825Stheravenvoid * operator new[](size_t size)
124253159Stheraven#if __cplusplus < 201000L
125253159Stheraventhrow(std::bad_alloc)
126253159Stheraven#endif
127227825Stheraven{
128227825Stheraven	return ::operator new(size);
129227825Stheraven}
130227825Stheraven
131227825Stheraven
132227825Stheraven__attribute__((weak))
133253159Stheravenvoid * operator new[](size_t size, const std::nothrow_t &) throw()
134227825Stheraven{
135253159Stheraven	try {
136253159Stheraven		return ::operator new[](size);
137253159Stheraven	} catch (...) {
138253159Stheraven		// nothrow operator new should return NULL in case of
139253159Stheraven		// std::bad_alloc exception in new handler
140253159Stheraven		return NULL;
141253159Stheraven	}
142253159Stheraven}
143253159Stheraven
144253159Stheraven
145253159Stheraven__attribute__((weak))
146253159Stheravenvoid operator delete[](void * ptr)
147253159Stheraven#if __cplusplus < 201000L
148253159Stheraventhrow()
149253159Stheraven#endif
150253159Stheraven{
151227825Stheraven	::operator delete(ptr);
152227825Stheraven}
153227825Stheraven
154227825Stheraven
155