memory.cc revision 245302
1232922Stheraven/*
2232922Stheraven * Copyright 2010-2011 PathScale, Inc. All rights reserved.
3232922Stheraven *
4232922Stheraven * Redistribution and use in source and binary forms, with or without
5232922Stheraven * modification, are permitted provided that the following conditions are met:
6232922Stheraven *
7232922Stheraven * 1. Redistributions of source code must retain the above copyright notice,
8232922Stheraven *    this list of conditions and the following disclaimer.
9232922Stheraven *
10232922Stheraven * 2. Redistributions in binary form must reproduce the above copyright notice,
11232922Stheraven *    this list of conditions and the following disclaimer in the documentation
12232922Stheraven *    and/or other materials provided with the distribution.
13232922Stheraven *
14232922Stheraven * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
15232922Stheraven * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16232922Stheraven * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17232922Stheraven * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
18232922Stheraven * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19232922Stheraven * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20232922Stheraven * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21232922Stheraven * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22232922Stheraven * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23232922Stheraven * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24232922Stheraven * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25232922Stheraven */
26232922Stheraven
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"
39245302Stheraven#include "atomic.h"
40227825Stheraven
41232922Stheraven
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	{
64245302Stheraven		return ATOMIC_SWAP(&new_handl, handler);
65227825Stheraven	}
66245302Stheraven	__attribute__((weak))
67245302Stheraven	new_handler get_new_handler(void)
68245302Stheraven	{
69245302Stheraven		return ATOMIC_LOAD(&new_handl);
70245302Stheraven	}
71227825Stheraven}
72227825Stheraven
73227825Stheraven
74227825Stheraven__attribute__((weak))
75227825Stheravenvoid* operator new(size_t size)
76227825Stheraven{
77245302Stheraven	if (0 == size)
78245302Stheraven	{
79245302Stheraven		size = 1;
80245302Stheraven	}
81227825Stheraven	void * mem = malloc(size);
82227825Stheraven	while (0 == mem)
83227825Stheraven	{
84245302Stheraven		new_handler h = std::get_new_handler();
85245302Stheraven		if (0 != h)
86227825Stheraven		{
87245302Stheraven			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{
102245302Stheraven	if (0 == size)
103245302Stheraven	{
104245302Stheraven		size = 1;
105245302Stheraven	}
106227825Stheraven	void *mem = malloc(size);
107227825Stheraven	while (0 == mem)
108227825Stheraven	{
109245302Stheraven		new_handler h = std::get_new_handler();
110245302Stheraven		if (0 != h)
111227825Stheraven		{
112227825Stheraven			try
113227825Stheraven			{
114245302Stheraven				h();
115227825Stheraven			}
116227825Stheraven			catch (...)
117227825Stheraven			{
118227825Stheraven				// nothrow operator new should return NULL in case of
119227825Stheraven				// std::bad_alloc exception in new handler
120227825Stheraven				return NULL;
121227825Stheraven			}
122227825Stheraven		}
123227825Stheraven		else
124227825Stheraven		{
125227825Stheraven			return NULL;
126227825Stheraven		}
127227825Stheraven		mem = malloc(size);
128227825Stheraven	}
129227825Stheraven
130227825Stheraven	return mem;
131227825Stheraven}
132227825Stheraven
133227825Stheraven
134227825Stheraven__attribute__((weak))
135227825Stheravenvoid operator delete(void * ptr)
136227825Stheraven{
137227825Stheraven	free(ptr);
138227825Stheraven}
139227825Stheraven
140227825Stheraven
141227825Stheraven__attribute__((weak))
142227825Stheravenvoid * operator new[](size_t size)
143227825Stheraven{
144227825Stheraven	return ::operator new(size);
145227825Stheraven}
146227825Stheraven
147227825Stheraven
148227825Stheraven__attribute__((weak))
149227995Stheravenvoid operator delete[](void * ptr) throw()
150227825Stheraven{
151227825Stheraven	::operator delete(ptr);
152227825Stheraven}
153227825Stheraven
154227825Stheraven
155