Thanks to visit codestin.com
Credit goes to github.com

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

Lines changed: 49 additions & 11 deletions
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)