Skip to content

Commit b9a0f6e

Browse files
committed
Document that calls are safe on nullptr Delegates, and remove redundant chesks from using code.
1 parent eaa3fb5 commit b9a0f6e

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

src/SoftwareSerial.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ void IRAM_ATTR UARTBase::rxBitISR(UARTBase* self) {
573573
// tick's LSB is repurposed for the level bit
574574
if (!self->m_isrBuffer->push((curTick | 1U) ^ !level)) self->m_isrOverflow.store(true);
575575
// Trigger rx callback only when receiver is starved
576-
if (empty && self->m_rxHandler) self->m_rxHandler();
576+
if (empty) self->m_rxHandler();
577577
}
578578

579579
void IRAM_ATTR UARTBase::rxBitSyncISR(UARTBase* self) {
@@ -599,7 +599,7 @@ void IRAM_ATTR UARTBase::rxBitSyncISR(UARTBase* self) {
599599
}
600600
}
601601
// Trigger rx callback only when receiver is starved
602-
if (empty && self->m_rxHandler) self->m_rxHandler();
602+
if (empty) self->m_rxHandler();
603603
}
604604

605605
void UARTBase::onReceive(const Delegate<void(), void*>& handler) {
@@ -617,10 +617,9 @@ void UARTBase::onReceive(Delegate<void(), void*>&& handler) {
617617
// The template member functions below must be in IRAM, but due to a bug GCC doesn't currently
618618
// honor the attribute. Instead, it is possible to do explicit specialization and adorn
619619
// these with the IRAM attribute:
620-
// Delegate<>::operator bool, Delegate<>::operator (), circular_queue<>::available,
620+
// Delegate<>::operator (), circular_queue<>::available,
621621
// circular_queue<>::available_for_push, circular_queue<>::push_peek, circular_queue<>::push
622622

623-
template IRAM_ATTR delegate::detail::DelegateImpl<void*, void>::operator bool() const;
624623
template void IRAM_ATTR delegate::detail::DelegateImpl<void*, void>::operator()() const;
625624
template size_t IRAM_ATTR circular_queue<uint32_t, UARTBase*>::available() const;
626625
template bool IRAM_ATTR circular_queue<uint32_t, UARTBase*>::push(uint32_t&&);

src/SoftwareSerial.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,9 @@ using namespace EspSoftwareSerial;
435435
// The template member functions below must be in IRAM, but due to a bug GCC doesn't currently
436436
// honor the attribute. Instead, it is possible to do explicit specialization and adorn
437437
// these with the IRAM attribute:
438-
// Delegate<>::operator bool, Delegate<>::operator (), circular_queue<>::available,
438+
// Delegate<>::operator (), circular_queue<>::available,
439439
// circular_queue<>::available_for_push, circular_queue<>::push_peek, circular_queue<>::push
440440

441-
extern template delegate::detail::DelegateImpl<void*, void>::operator bool() const;
442441
extern template void delegate::detail::DelegateImpl<void*, void>::operator()() const;
443442
extern template size_t circular_queue<uint32_t, EspSoftwareSerial::UARTBase*>::available() const;
444443
extern template bool circular_queue<uint32_t, EspSoftwareSerial::UARTBase*>::push(uint32_t&&);

src/circular_queue/Delegate.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,14 @@ namespace delegate
323323
}
324324
}
325325

326+
/// Calling is safe without checking for nullptr.
327+
/// If non-void, returns the default value.
328+
/// In ISR context, where faults and exceptions must not
329+
/// occurs, this saves the extra check for nullptr,
330+
/// and allows the compiler to optimize out checks
331+
/// in std::function which may not be ISR-safe or
332+
/// cause linker errors, like l32r relocation errors
333+
/// on the Xtensa ISA.
326334
R IRAM_ATTR operator()(P... args) const
327335
{
328336
if (FP == kind)
@@ -538,6 +546,14 @@ namespace delegate
538546
}
539547
}
540548

549+
/// Calling is safe without checking for nullptr.
550+
/// If non-void, returns the default value.
551+
/// In ISR context, where faults and exceptions must not
552+
/// occurs, this saves the extra check for nullptr,
553+
/// and allows the compiler to optimize out checks
554+
/// in std::function which may not be ISR-safe or
555+
/// cause linker errors, like l32r relocation errors
556+
/// on the Xtensa ISA.
541557
R IRAM_ATTR operator()(P... args) const
542558
{
543559
if (FP == kind)
@@ -746,6 +762,14 @@ namespace delegate
746762
}
747763
}
748764

765+
/// Calling is safe without checking for nullptr.
766+
/// If non-void, returns the default value.
767+
/// In ISR context, where faults and exceptions must not
768+
/// occurs, this saves the extra check for nullptr,
769+
/// and allows the compiler to optimize out checks
770+
/// in std::function which may not be ISR-safe or
771+
/// cause linker errors, like l32r relocation errors
772+
/// on the Xtensa ISA.
749773
R IRAM_ATTR operator()(P... args) const
750774
{
751775
if (FP == kind)
@@ -846,6 +870,14 @@ namespace delegate
846870
return reinterpret_cast<void*>(fn);
847871
}
848872

873+
/// Calling is safe without checking for nullptr.
874+
/// If non-void, returns the default value.
875+
/// In ISR context, where faults and exceptions must not
876+
/// occurs, this saves the extra check for nullptr,
877+
/// and allows the compiler to optimize out checks
878+
/// in std::function which may not be ISR-safe or
879+
/// cause linker errors, like l32r relocation errors
880+
/// on the Xtensa ISA.
849881
inline R IRAM_ATTR operator()(P... args) const __attribute__((always_inline))
850882
{
851883
if (fn) return fn(std::forward<P...>(args...));
@@ -1127,6 +1159,14 @@ namespace delegate
11271159
}
11281160
}
11291161

1162+
/// Calling is safe without checking for nullptr.
1163+
/// If non-void, returns the default value.
1164+
/// In ISR context, where faults and exceptions must not
1165+
/// occurs, this saves the extra check for nullptr,
1166+
/// and allows the compiler to optimize out checks
1167+
/// in std::function which may not be ISR-safe or
1168+
/// cause linker errors, like l32r relocation errors
1169+
/// on the Xtensa ISA.
11301170
R IRAM_ATTR operator()() const
11311171
{
11321172
if (FP == kind)
@@ -1341,6 +1381,14 @@ namespace delegate
13411381
}
13421382
}
13431383

1384+
/// Calling is safe without checking for nullptr.
1385+
/// If non-void, returns the default value.
1386+
/// In ISR context, where faults and exceptions must not
1387+
/// occurs, this saves the extra check for nullptr,
1388+
/// and allows the compiler to optimize out checks
1389+
/// in std::function which may not be ISR-safe or
1390+
/// cause linker errors, like l32r relocation errors
1391+
/// on the Xtensa ISA.
13441392
R IRAM_ATTR operator()() const
13451393
{
13461394
if (FP == kind)
@@ -1549,6 +1597,14 @@ namespace delegate
15491597
}
15501598
}
15511599

1600+
/// Calling is safe without checking for nullptr.
1601+
/// If non-void, returns the default value.
1602+
/// In ISR context, where faults and exceptions must not
1603+
/// occurs, this saves the extra check for nullptr,
1604+
/// and allows the compiler to optimize out checks
1605+
/// in std::function which may not be ISR-safe or
1606+
/// cause linker errors, like l32r relocation errors
1607+
/// on the Xtensa ISA.
15521608
R IRAM_ATTR operator()() const
15531609
{
15541610
if (FP == kind)
@@ -1649,6 +1705,14 @@ namespace delegate
16491705
return nullptr;
16501706
}
16511707

1708+
/// Calling is safe without checking for nullptr.
1709+
/// If non-void, returns the default value.
1710+
/// In ISR context, where faults and exceptions must not
1711+
/// occurs, this saves the extra check for nullptr,
1712+
/// and allows the compiler to optimize out checks
1713+
/// in std::function which may not be ISR-safe or
1714+
/// cause linker errors, like l32r relocation errors
1715+
/// on the Xtensa ISA.
16521716
inline R IRAM_ATTR operator()() const __attribute__((always_inline))
16531717
{
16541718
if (fn) return fn();

0 commit comments

Comments
 (0)