Skip to content

Commit 1980548

Browse files
kibergusfacchinm
authored andcommitted
Correct implementation of gcc specific internal functions
Last bit not implemented by a4496b9 Squash and rebase of arduino/Arduino#108
1 parent 6c861d8 commit 1980548

File tree

1 file changed

+49
-11
lines changed

1 file changed

+49
-11
lines changed

cores/arduino/abi.cpp

+49-11
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,59 @@
1515
License along with this library; if not, write to the Free Software
1616
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1717
*/
18+
#include <abi.h>
19+
#include <stdint.h>
20+
#include <exception>
1821

19-
#include <stdlib.h>
22+
#include <avr/io.h>
23+
#include <avr/interrupt.h>
2024

21-
extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
22-
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
25+
namespace {
26+
// guard is an integer type big enough to hold flag and a mutex.
27+
// By default gcc uses long long int and avr ABI does not change it
28+
// So we have 32 or 64 bits available. Actually, we need 16.
2329

24-
void __cxa_pure_virtual(void) {
25-
// We might want to write some diagnostics to uart in this case
26-
//std::terminate();
27-
abort();
30+
inline char& flag_part(__guard *g) {
31+
return *(reinterpret_cast<char*>(g));
2832
}
2933

30-
void __cxa_deleted_virtual(void) {
31-
// We might want to write some diagnostics to uart in this case
32-
//std::terminate();
33-
abort();
34+
inline uint8_t& sreg_part(__guard *g) {
35+
return *(reinterpret_cast<uint8_t*>(g) + sizeof(char));
36+
}
37+
}
38+
39+
int __cxa_guard_acquire(__guard *g) {
40+
uint8_t oldSREG = SREG;
41+
cli();
42+
// Initialization of static variable has to be done with blocked interrupts
43+
// because if this function is called from interrupt and sees that somebody
44+
// else is already doing initialization it MUST wait until initializations
45+
// is complete. That's impossible.
46+
// If you don't want this overhead compile with -fno-threadsafe-statics
47+
if (flag_part(g)) {
48+
SREG = oldSREG;
49+
return false;
50+
} else {
51+
sreg_part(g) = oldSREG;
52+
return true;
53+
}
54+
}
55+
56+
void __cxa_guard_release (__guard *g) {
57+
flag_part(g) = 1;
58+
SREG = sreg_part(g);
3459
}
3560

61+
void __cxa_guard_abort (__guard *g) {
62+
SREG = sreg_part(g);
63+
}
64+
65+
void __cxa_pure_virtual(void) {
66+
// We might want to write some diagnostics to uart in this case
67+
std::terminate();
68+
}
69+
70+
void __cxa_deleted_virtual(void) {
71+
// We might want to write some diagnostics to uart in this case
72+
std::terminate();
73+
}

0 commit comments

Comments
 (0)