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
14 changes: 11 additions & 3 deletions .github/actions/generate-build-matrix/generate_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@

def get_default_combinations(event_name, all_combinations):
"""Gets the default build combinations based on the GitHub event type."""
if event_name in ("push", "pull_request", "pull_request_target", "workflow_dispatch"):
if event_name in (
"push",
"pull_request",
"pull_request_target",
"issue_comment",
"workflow_dispatch",
):
return ["gcc/none"]
elif event_name == "issue_comment":
return ["gcc/none", "clang/none"]
elif event_name == "schedule":
return ["gcc/perfetto"]
else:
# Default to a minimal safe configuration for unknown events
return ["gcc/none"]
Expand All @@ -23,10 +29,12 @@ def main():
"gcc/asan",
"gcc/tsan",
"gcc/valgrind",
"gcc/perfetto",
"clang/none",
"clang/asan",
"clang/tsan",
"clang/valgrind",
"clang/perfetto",
]
user_input = os.getenv("USER_INPUT", "")
comment_body = os.getenv("COMMENT_BODY", "")
Expand Down
79 changes: 74 additions & 5 deletions .github/workflows/cmake-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ run-name: "${{ github.actor }} building and testing ${{ github.repository }}"
types: [created]
push:
branches: [main, develop]
schedule:
- cron: "7 18 * * 6"
workflow_dispatch:
inputs:
ref:
Expand All @@ -24,6 +26,16 @@ run-name: "${{ github.actor }} building and testing ${{ github.repository }}"
Default (if empty): Run `gcc/none`
required: false
default: ""
perfetto-heap-profile:
description: "Enable heap profiling for Perfetto runs"
required: false
type: boolean
default: false
perfetto-cpu-profile:
description: "Enable CPU profiling for Perfetto runs"
required: false
type: boolean
default: true
workflow_call:
inputs:
checkout-path:
Expand Down Expand Up @@ -72,7 +84,7 @@ jobs:
setup:
if: >
github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request' || github.event_name == 'push' ||
github.event_name == 'workflow_call' || (
github.event_name == 'schedule' || github.event_name == 'workflow_call' || (
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(fromJSON('["OWNER", "COLLABORATOR", "MEMBER"]'), github.event.comment.author_association) &&
Expand Down Expand Up @@ -140,6 +152,7 @@ jobs:

container:
image: ghcr.io/framework-r-d/phlex-ci:latest
options: --cap-add=SYS_PTRACE

steps:
- name: Check out code
Expand Down Expand Up @@ -175,6 +188,7 @@ jobs:
extra-options: |
${{ matrix.sanitizer == 'asan' && format('-D{0}_ENABLE_ASAN=ON', steps.repo_name.outputs.name) || '' }}
${{ matrix.sanitizer == 'tsan' && format('-D{0}_ENABLE_TSAN=ON', steps.repo_name.outputs.name) || '' }}
${{ matrix.sanitizer == 'perfetto' && format('-D{0}_ENABLE_PERFETTO=ON', steps.repo_name.outputs.name) || '' }}

- name: Build
id: build
Expand All @@ -183,7 +197,7 @@ jobs:
build-path: ${{ needs.setup.outputs.build_path }}

- name: Run tests
if: matrix.sanitizer != 'valgrind'
if: matrix.sanitizer != 'valgrind' && matrix.sanitizer != 'perfetto'
working-directory: ${{ needs.setup.outputs.build_path }}
run: |
. /entrypoint.sh
Expand Down Expand Up @@ -215,12 +229,67 @@ jobs:
echo "⚠️ Valgrind tests failed, but the workflow will continue."
fi

- name: Run Perfetto profiling
if: matrix.sanitizer == 'perfetto'
working-directory: ${{ needs.setup.outputs.build_path }}
env:
PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto-heap-profile || 'false' }}
PERFETTO_CPU_PROFILE: ${{ github.event.inputs.perfetto-cpu-profile || true }}
run: |
. /entrypoint.sh

echo "➡️ Running tests with Perfetto profiling..."

# Set perf_event_paranoid for CPU profiling
if [ "$PERFETTO_CPU_PROFILE" = "true" ]; then
echo "Configuring perf_event_paranoid for CPU profiling"
echo -1 | tee /proc/sys/kernel/perf_event_paranoid 2>/dev/null || echo "Warning: Could not set perf_event_paranoid"
fi

# Configure profiling based on environment
TRACEBOX_ARGS=""
if [ "$PERFETTO_HEAP_PROFILE" = "true" ]; then
echo "Enabling heap profiling"
TRACEBOX_ARGS="$TRACEBOX_ARGS --app '*' --heapprofd"
fi
if [ "$PERFETTO_CPU_PROFILE" = "true" ]; then
echo "Enabling CPU profiling"
TRACEBOX_ARGS="$TRACEBOX_ARGS --cpu-freq --cpu-idle --cpu-sched"
fi

# Run tests with or without tracebox wrapper
TEST_RESULT=0
if [ -n "$TRACEBOX_ARGS" ]; then
echo "::group::Running ctest with tracebox"
tracebox $TRACEBOX_ARGS -o "perfetto-trace.pftrace" -- ctest --progress --output-on-failure -j "$(nproc)" || TEST_RESULT=$?
else
echo "::group::Running ctest with Perfetto SDK tracing"
ctest --progress --output-on-failure -j "$(nproc)" || TEST_RESULT=$?
fi

echo "::endgroup::"
if [ "${TEST_RESULT:-0}" -eq 0 ]; then
echo "✅ Perfetto profiling completed."
else
echo "::error:: Perfetto profiling failed."
exit 1
fi

- name: Upload Perfetto traces
if: matrix.sanitizer == 'perfetto'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: perfetto-traces-${{ matrix.compiler }}
path: |
${{ needs.setup.outputs.build_path }}/**/*.pftrace
retention-days: 30
if-no-files-found: warn

cmake-build-skipped:
needs: [setup]
if: >
needs.setup.result == 'success' && github.event_name != 'workflow_dispatch' &&
!inputs.skip-relevance-check && needs.setup.outputs.is_act != 'true' &&
needs.setup.outputs.has_changes != 'true'
needs.setup.result == 'success' && github.event_name != 'workflow_dispatch' && !inputs.skip-relevance-check &&
needs.setup.outputs.is_act != 'true' && needs.setup.outputs.has_changes != 'true'
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/_deps/
/build-*/
/build/
/out/
/phlex-build/
/phlex-src/
CMakeFiles/
Expand Down
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ include(Modules/private/CreateCoverageTargets.cmake)

option(ENABLE_TSAN "Enable Thread Sanitizer" OFF)
option(ENABLE_ASAN "Enable Address Sanitizer" OFF)
include(CMakeDependentOption)
cmake_dependent_option(
ENABLE_PERFETTO
"Enable Perfetto profiling"
OFF
"CMAKE_SYSTEM_NAME STREQUAL Linux"
OFF
)
option(PHLEX_USE_FORM "Enable experimental integration with FORM" OFF)
option(ENABLE_COVERAGE "Enable code coverage instrumentation" OFF)
option(ENABLE_BUILD_PROFILING "Enable monitoring of compile and link operations" OFF)
Expand Down Expand Up @@ -196,6 +204,12 @@ if(ENABLE_ASAN)
endif()
endif()

# Configure Perfetto profiling if enabled
if(ENABLE_PERFETTO)
message(STATUS "Enabling Perfetto profiling")
find_package(Perfetto REQUIRED)
endif()

# Configure code coverage if enabled
if(ENABLE_COVERAGE)
# Check if the compiler supports code coverage
Expand Down
31 changes: 31 additions & 0 deletions Modules/FindPerfetto.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# FindPerfetto.cmake
# Finds the Perfetto SDK (single-header implementation)

include(FindPackageHandleStandardArgs)

find_path(
Perfetto_INCLUDE_DIR
NAMES perfetto.h
PATHS /opt/perfetto /usr/local/include /usr/include
DOC "Perfetto SDK header location"
)

find_file(
Perfetto_SOURCE
NAMES perfetto.cc
PATHS /opt/perfetto /usr/local/include /usr/include
DOC "Perfetto SDK implementation file"
)

find_package_handle_standard_args(Perfetto REQUIRED_VARS Perfetto_INCLUDE_DIR Perfetto_SOURCE)

if(Perfetto_FOUND AND NOT TARGET Perfetto::Perfetto)
find_package(Threads REQUIRED)
add_library(Perfetto_impl STATIC "${Perfetto_SOURCE}")
target_include_directories(Perfetto_impl PUBLIC "${Perfetto_INCLUDE_DIR}")
target_compile_definitions(Perfetto_impl PUBLIC PERFETTO_ENABLE_TRACING=1)
target_link_libraries(Perfetto_impl PUBLIC Threads::Threads)
add_library(Perfetto::Perfetto ALIAS Perfetto_impl)
endif()

mark_as_advanced(Perfetto_INCLUDE_DIR Perfetto_SOURCE)
30 changes: 30 additions & 0 deletions ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,36 @@ set -euo pipefail
rm -f /tmp/spack.yaml
CLEAN_TEMP_FILES

########################################################################
# Install Perfetto SDK for profiling

RUN <<'INSTALL_PERFETTO'
set -euo pipefail

# Install Perfetto SDK and tools
apt-get update
apt-get install -y --no-install-recommends \
wget
apt-get clean
rm -rf /var/lib/apt/lists/*

mkdir -p /opt/perfetto
cd /opt/perfetto
PERFETTO_VERSION=v51.0
wget -O perfetto.h https://raw.githubusercontent.com/google/perfetto/${PERFETTO_VERSION}/sdk/perfetto.h
wget -O perfetto.cc https://raw.githubusercontent.com/google/perfetto/${PERFETTO_VERSION}/sdk/perfetto.cc
chmod 644 perfetto.h perfetto.cc

# Install tracebox for system-wide profiling.
# Note: get.perfetto.dev/tracebox serves the latest binary with no versioned
# or checksum-verifiable download currently offered by the Perfetto project.
# Revisit when the project provides versioned tracebox releases with integrity
# metadata.
wget -O tracebox https://get.perfetto.dev/tracebox
chmod +x tracebox
mv tracebox /usr/local/bin/
INSTALL_PERFETTO

########################################################################
# Finalize CI image stage

Expand Down
4 changes: 4 additions & 0 deletions phlex/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ cet_make_exec(
jsonnet::lib
)

if(ENABLE_PERFETTO)
target_link_libraries(phlex PRIVATE Perfetto::Perfetto)
endif()

set_target_properties(phlex PROPERTIES INSTALL_RPATH "$ORIGIN/../lib")
Loading