Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Clone ETL dependency
run: git clone --depth 1 https://github.com/ETLCPP/etl.git etlcpp/etl

- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include (cmake/helper.cmake)
enable_testing()

add_subdirectory(maps)
add_subdirectory(etlcpp)
add_subdirectory(vectors)
add_subdirectory(smart_ptr)
add_subdirectory(array)
Expand Down
56 changes: 56 additions & 0 deletions etlcpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# ETL Demo Project - String View and Components Benchmarking
cmake_minimum_required(VERSION 3.10)
project(demo_string_view)

#-----------------------------------------------------------------------------
# Build Configuration
#-----------------------------------------------------------------------------
# Set Release build type and size optimization, no debug info
set(CMAKE_BUILD_TYPE Release)
if (MSVC)
# MSVC does not support GCC/Clang linker flags
set(CMAKE_CXX_FLAGS_RELEASE "/O2")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-Os -Wl,-Map=${CMAKE_PROJECT_NAME}.map")
endif()

#-----------------------------------------------------------------------------
# Dependencies
#-----------------------------------------------------------------------------
# Add ETL include directory (relative to this demo folder)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/etl/include")
message(STATUS "Using local ETL from etlcpp/etl/include")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/etl/include)
else()
message(WARNING "Local ETL not found, please ensure etl/include is available.")
include_directories(../etl/include)
endif()

#-----------------------------------------------------------------------------
# ETL Configuration
#-----------------------------------------------------------------------------
# Define ETL macros for enhanced functionality
add_definitions(-DETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
add_definitions(-DETL_LOG_ERRORS)

#-----------------------------------------------------------------------------
# Source Files
#-----------------------------------------------------------------------------
set(DEMO_SOURCES
main.cpp
etl_string_view_demo.cpp
my_string_view_demo.cpp
etl_timer_demo.cpp
etl_task_scheduler_demo.cpp
etl_assert_demo.cpp
)

#-----------------------------------------------------------------------------
# Executable Target
#-----------------------------------------------------------------------------

add_executable(${PROJECT_NAME} ${DEMO_SOURCES})

# Add test for ETL demo application
enable_testing()
add_test(NAME etlcpp_demo COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
124 changes: 124 additions & 0 deletions etlcpp/etl_assert_demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include "etl_assert_demo.h"
#include "etl/vector.h"
#include "etl/string.h"
#include "etl/error_handler.h"
#include "etl/exception.h"
#include "etl/not_null.h"
#include <cstdio>
#include <memory>
#include <chrono>
#include <cassert>
#include <stdexcept>
#include <iostream>

class my_exception : public etl::exception {
public:
my_exception(const char* file, int line)
: etl::exception("Custom assertion failure", file, line) {}
};

namespace {
// Custom error handler to log ETL exceptions
void etl_assert_error_handler(const etl::exception& e) {
printf("[ETL ERROR HANDLER] Exception caught: %s at line %d\n",
e.what(), static_cast<int>(e.line_number()));
}
}


// Basic ETL assert demonstration
void benchmark_assert_demo_etl() {
printf("\n=== ETL Assert Demo - Basic Assertions ===\n");

// Set up error handler to log exceptions
etl::error_handler::set_callback<etl_assert_error_handler>();

// Test 1: Standard ETL exception
printf("Test 1: Standard ETL exception\n");
ETL_ASSERT(false, ETL_ERROR(etl::vector_out_of_bounds));
printf("Standard ETL exception triggered and handled\n");

// Test 2: Custom exception
printf("\nTest 2: Custom exception\n");
ETL_ASSERT(false, ETL_ERROR(my_exception));
printf("Custom exception triggered and handled\n");
}

// Equivalent functionality using early returns (no assertions)
void benchmark_assert_demo_standard() {
printf("\n=== Standard Assert Demo - Early Returns ===\n");

// Helper lambda for error logging
auto log_error = [](const char* message, int line) {
printf("[STANDARD ERROR HANDLER] Error: %s at line %d\n", message, line);
};

// Test 1: Standard error with early return
printf("Test 1: Standard error with early return\n");
auto test_function_1 = [&]() -> bool {
bool condition = false;
if (!condition) {
log_error("Vector out of bounds", __LINE__);
return false;
}
return true;
};

if (!test_function_1()) {
printf("Standard error triggered and handled\n");
}

// Test 2: Custom error with early return
printf("\nTest 2: Custom error with early return\n");
auto test_function_2 = [&]() -> bool {
bool condition = false;
if (!condition) {
log_error("Custom assertion failure", __LINE__);
return false;
}
return true;
};

if (!test_function_2()) {
printf("Custom error triggered and handled\n");
}
}

// Plain C-style implementation using early returns (no lambdas)
void benchmark_assert_demo_plain_c() {
printf("\n=== Plain C Assert Demo - Early Returns ===\n");

// Test 1: Standard error with early return - plain C style
printf("Test 1: Standard error with early return (plain C)\n");
{
bool condition = false;
if (!condition) {
printf("[PLAIN C ERROR HANDLER] Error: Vector out of bounds at line %d\n", __LINE__);
goto test1_error;
}
printf("Test 1 passed\n");
goto test1_done;

test1_error:
printf("Standard error triggered and handled\n");

test1_done:;
}

// Test 2: Custom error with early return - plain C style
printf("\nTest 2: Custom error with early return (plain C)\n");
{
bool condition = false;
if (!condition) {
printf("[PLAIN C ERROR HANDLER] Error: Custom assertion failure at line %d\n", __LINE__);
goto test2_error;
}
printf("Test 2 passed\n");
goto test2_done;

test2_error:
printf("Custom error triggered and handled\n");

test2_done:;
}
}
13 changes: 13 additions & 0 deletions etlcpp/etl_assert_demo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef ETL_ASSERT_DEMO_H
#define ETL_ASSERT_DEMO_H

// Demo functions showing ETL assert macro usage
void benchmark_assert_demo_etl();

// Demo function showing equivalent functionality with early returns
void benchmark_assert_demo_standard();

// Demo function showing plain C-style early returns (no lambdas)
void benchmark_assert_demo_plain_c();

#endif // ETL_ASSERT_DEMO_H
35 changes: 35 additions & 0 deletions etlcpp/etl_string_view_demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "etl/string_view.h"
#include "etl/error_handler.h"
#include "etl_string_view_demo.h"

static etl::string_view get_sv() {
return etl::string_view{"Hello, Embedded Template Library!"};
}

size_t benchmark_etl_string_view_size() {
return get_sv().size();
}

int benchmark_etl_string_view_empty() {
return get_sv().empty();
}

char benchmark_etl_string_view_front() {
return get_sv().front();
}

char benchmark_etl_string_view_back() {
return get_sv().back();
}

size_t benchmark_etl_string_view_find() {
return get_sv().find("Template");
}

int benchmark_etl_string_view_compare() {
return get_sv().compare("Hello, Embedded Template Library!");
}

size_t benchmark_etl_string_view_substr_size() {
return get_sv().substr(7, 9).size();
}
18 changes: 18 additions & 0 deletions etlcpp/etl_string_view_demo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once
#include <cstddef>

#ifdef __cplusplus
extern "C" {
#endif

size_t benchmark_etl_string_view_size();
int benchmark_etl_string_view_empty();
char benchmark_etl_string_view_front();
char benchmark_etl_string_view_back();
size_t benchmark_etl_string_view_find();
int benchmark_etl_string_view_compare();
size_t benchmark_etl_string_view_substr_size();

#ifdef __cplusplus
}
#endif
59 changes: 59 additions & 0 deletions etlcpp/etl_task_scheduler_demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "etl_task_scheduler_demo.h"
#include <etl/scheduler.h>
#include <etl/task.h>
#include <cstdio>
#include <thread>
#include <atomic>

// Example task class
class PrintTask : public etl::task {
public:
PrintTask(const char* msg, etl::task_priority_t priority)
: etl::task(priority), message(msg), work_count(0) {}

uint32_t task_request_work() const override {
// Simulate work available for 5 cycles
return work_count < 5 ? 1 : 0;
}

void task_process_work() override {
printf("[Task] %s (cycle %d)\n", message, work_count + 1);
++work_count;
}

private:
const char* message;
mutable int work_count;
};

// ETL-only scheduler demo (no std::thread, no std::atomic)
void benchmark_etl_task_scheduler_etl_only()
{
PrintTask t1("A", 2);
PrintTask t2("B", 1);
etl::scheduler<etl::scheduler_policy_sequential_single, 2> sched;
sched.add_task(t1);
sched.add_task(t2);

// Manually run scheduler cycles instead of using start() which loops forever
printf("Running ETL scheduler for limited cycles:\n");
for (int cycle = 0; cycle < 5; ++cycle) {
printf("Cycle %d:\n", cycle + 1);

// Manually check each task and process work
bool has_work = false;
if (t1.task_request_work() > 0) {
t1.task_process_work();
has_work = true;
}
if (t2.task_request_work() > 0) {
t2.task_process_work();
has_work = true;
}

if (!has_work) {
printf("No more work available, stopping scheduler.\n");
break;
}
}
}
4 changes: 4 additions & 0 deletions etlcpp/etl_task_scheduler_demo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

void benchmark_etl_task_scheduler_demo_run();
void benchmark_etl_task_scheduler_etl_only();
Loading