Code size analysis#

pw_async2: Cooperative async tasks for embedded

Core async2 implementation#

The following table shows the code size cost of adding pw_async2 to a system. These size reports assume a baseline system with an RTOS which already uses a handful of core Pigweed components including HAL abstractions and pw_allocator.

The first row captures the core of pw_async2: the dispatcher, tasks, and wakers, using the pw_async2_basic dispatcher backend. This is the minimum size cost a system must pay to adopt pw_async2. The following row demonstrates the cost of adding another task to this system. Of course, the majority of the cost of the task exists within its implementation — this simply shows that there is minimal internal overhead.

The following two rows in the table deal with the pair of OnceSender and OnceReceiver types, which allow for returning a delayed result from an async function, similar to a Future type in other languages. This type is templated on its stored value, causing specialization overhead for each type sent through the sender/receiver pair. The first OnceSender row showcases the base cost of using a OnceSender and OnceReceiver; the second row adds another template specialization on top of this to demonstrate the incremental cost.

Label

Segment

Delta

Full cost of including pw_async2

FLASH

+356

[section .rodata]

+4

[section .text]

+156

pw::async2::size_report::Measure()

+4

__bi_84

+12

vClearInterruptMaskFromISR

NEW

+308

pw::async2::NativeDispatcherBase::RunOneTask()

NEW

+136

pw::async2::NativeDispatcherBase::NativeDispatcherBase()

NEW

+124

pw::async2::NativeDispatcherBase::Post()

NEW

+112

pw::async2::backend::NativeDispatcher::DoRunToCompletion()

NEW

+100

pw::async2::NativeDispatcherBase::WakeTask()

NEW

+96

pw::async2::backend::NativeDispatcher::DoRunUntilStalled()

NEW

+60

pw::async2::NativeDispatcherBase::AttemptRequestWake()

NEW

+56

pw::async2::Waker::operator=()

NEW

+52

pw::async2::Waker::InternalCloneInto()

NEW

+42

pw::async2::size_report::MockTask::~MockTask()

NEW

+40

pw::async2::Waker::Wake()

NEW

+36

pw::async2::Waker::InsertIntoTaskWakerList()

NEW

+32

pw::async2::NativeDispatcherBase::PopWokenTask()

NEW

+32

pw::async2::Task::RemoveWakerLocked()

NEW

+32

pw::async2::Waker::RemoveFromTaskWakerList()

NEW

+32

pw::async2::backend::NativeDispatcher::NativeDispatcher()

NEW

+30

pw::async2::NativeDispatcherBase::RemoveWokenTaskLocked()

NEW

+28

pw::async2::size_report::MockTask::DoPend()

NEW

+24

pw::async2::NativeDispatcherBase::RemoveTaskFromList()

NEW

+24

pw::async2::size_report::MockTask

NEW

+22

pw::async2::NativeDispatcherBase::Wake()

NEW

+22

pw::async2::Task::RemoveAllWakersLocked()

NEW

+20

pw::async2::NativeDispatcherBase::RemoveSleepingTaskLocked()

NEW

+20

pw::async2::Waker::Waker()

NEW

+16

_GLOBAL__sub_I_async2_core.cc

NEW

+16

pw::async2::Waker::RemoveFromTaskWakerListLocked()

NEW

+12

pw::async2::Dispatcher::RunToCompletion()

NEW

+12

pw::async2::Dispatcher::RunUntilStalled()

NEW

+12

pw::async2::NativeDispatcherBase

NEW

+12

pw::async2::backend::NativeDispatcher

NEW

+12

pw::async2::backend::NativeDispatcher::DoWake()

NEW

+10

pw::async2::Context::InternalStoreWaker()

NEW

+10

pw::async2::size_report::MockTask::DoDestroy()

+2,124

RAM

NEW

+164

pw::async2::size_report::dispatcher

NEW

+8

pw::async2::impl::dispatcher_lock()::lock

+172

Base incremental cost of adding a task to an existing async system

FLASH

+36

pw::async2::size_report::Measure()

-4

vClearInterruptMaskFromISR

+32

Size of OnceSender / OnceReceiver

FLASH

+52

[section .rodata]

+72

pw::async2::size_report::Measure()

-12

vClearInterruptMaskFromISR

-4

__bi_84

-6

operator delete()

-2

pw::async2::size_report::MockTask::DoDestroy()

NEW

+96

pw::async2::OnceReceiver<>::OnceReceiver()

NEW

+84

pw::async2::OnceReceiver<>::Pend()

NEW

+56

pw::async2::size_report::SenderAdd()

NEW

+52

pw::async2::OnceSender<>::emplace<>()

NEW

+44

pw::async2::OnceReceiver<>::~OnceReceiver()

NEW

+44

pw::async2::OnceSender<>::~OnceSender()

NEW

+42

pw::async2::size_report::ReceiverTask<>::~ReceiverTask()

NEW

+40

_ZN2pw15internal_result12StatusOrDataIjLb1EEC2INS_6StatusETnNSt3__29enable_ifIXsr3std16is_constructibleIS4_OT_EE5valueEiE4typeELi0EEES8_

NEW

+40

pw::async2::size_report::ReceiverTask<>::ReceiverTask()

NEW

+24

pw::async2::size_report::ReceiverTask<>

NEW

+22

pw::async2::size_report::ReceiverTask<>::DoPend()

NEW

+20

_ZNSt3__28optionalIN2pw6ResultIjEEEC2B8nn210000INS1_6StatusETnNS_9enable_ifIXclsr22_CheckOptionalLikeCtorIT_OS8_EE17__enable_implicitIS8_EEEiE4typeELi0EEEONS0_IS8_EE

NEW

+20

std::__2::pair<>::~pair()

NEW

+14

_ZNSt3__223__optional_storage_baseIN2pw6ResultIjEELb0EE11__constructB8nn210000IJNS1_6StatusEEEEvDpOT_

NEW

+14

_ZNSt3__223__optional_storage_baseIN2pw6ResultIjEELb0EE16__construct_fromB8nn210000INS_8optionalINS1_6StatusEEEEEvOT_

NEW

+12

_ZNRSt3__28optionalIjE5valueB8nn210000Ev

NEW

+12

_ZNSt3__227__throw_bad_optional_accessB8nn210000Ev

NEW

+6

std::__2::__libcpp_verbose_abort()

NEW

+2

pw::async2::Task::DoDestroy()

+744

RAM

NEW

+8

pw::async2::sender_receiver_lock()::lock

+8

Cost of additional OnceSender / OnceReceiver template specialization

FLASH

+76

pw::async2::size_report::Measure()

+96

pw::async2::OnceReceiver<>::OnceReceiver()

+84

pw::async2::OnceReceiver<>::Pend()

+52

pw::async2::OnceSender<>::emplace<>()

+44

pw::async2::OnceReceiver<>::~OnceReceiver()

+44

pw::async2::OnceSender<>::~OnceSender()

+42

pw::async2::size_report::ReceiverTask<>::~ReceiverTask()

+40

pw::async2::size_report::ReceiverTask<>::ReceiverTask()

+24

pw::async2::size_report::ReceiverTask<>

+22

pw::async2::size_report::ReceiverTask<>::DoPend()

+18

std::__2::pair<>::~pair()

NEW

+54

pw::async2::size_report::SenderSub()

NEW

+40

_ZN2pw15internal_result12StatusOrDataIiLb1EEC2INS_6StatusETnNSt3__29enable_ifIXsr3std16is_constructibleIS4_OT_EE5valueEiE4typeELi0EEES8_

NEW

+20

_ZNSt3__28optionalIN2pw6ResultIiEEEC2B8nn210000INS1_6StatusETnNS_9enable_ifIXclsr22_CheckOptionalLikeCtorIT_OS8_EE17__enable_implicitIS8_EEEiE4typeELi0EEEONS0_IS8_EE

NEW

+14

_ZNSt3__223__optional_storage_baseIN2pw6ResultIiEELb0EE11__constructB8nn210000IJNS1_6StatusEEEEvDpOT_

NEW

+14

_ZNSt3__223__optional_storage_baseIN2pw6ResultIiEELb0EE16__construct_fromB8nn210000INS_8optionalINS1_6StatusEEEEEvOT_

NEW

+12

_ZNRSt3__28optionalIiE5valueB8nn210000Ev

+696