diff --git a/ci_config.json b/ci_config.json index e52db801e..6c45fc72d 100644 --- a/ci_config.json +++ b/ci_config.json @@ -511,6 +511,14 @@ "libpciaccess-dev" ] }, + "libpfm": { + "_comment": "Wrap only supports Linux", + "build_on": { + "windows": false, + "msys2": false, + "darwin": false + } + }, "libpsl": { "_comment": "with build all, it selects icu as a dependency which breaks the tests.", "alpine_packages": [ diff --git a/releases.json b/releases.json index 9a5dd6a08..a18a857c7 100644 --- a/releases.json +++ b/releases.json @@ -1753,6 +1753,14 @@ "2.3.1-1" ] }, + "libpfm": { + "dependency_names": [ + "libpfm" + ], + "versions": [ + "4.13.0-1" + ] + }, "libpng": { "dependency_names": [ "libpng" diff --git a/subprojects/libpfm.wrap b/subprojects/libpfm.wrap new file mode 100644 index 000000000..02e668c7f --- /dev/null +++ b/subprojects/libpfm.wrap @@ -0,0 +1,9 @@ +[wrap-file] +directory = libpfm-4.13.0 +source_url = https://sourceforge.net/projects/perfmon2/files/libpfm4/libpfm-4.13.0.tar.gz/download +source_filename = libpfm-4.13.0.tar.gz +source_hash = d18b97764c755528c1051d376e33545d0eb60c6ebf85680436813fa5b04cc3d1 +patch_directory = libpfm + +[provide] +libpfm = libpfm_dep diff --git a/subprojects/packagefiles/libpfm/examples/meson.build b/subprojects/packagefiles/libpfm/examples/meson.build new file mode 100644 index 000000000..5c99a6c96 --- /dev/null +++ b/subprojects/packagefiles/libpfm/examples/meson.build @@ -0,0 +1,19 @@ +deps = [m_dep, libpfm_dep] +if host_machine.system() == 'linux' + deps += [threads_dep, rt_dep] +elif host_machine.system() == 'windows' + deps += [cc.find_library('gnurx', required: false)] +endif + +executable( + 'showevtinfo', + 'showevtinfo.c', + c_args: ['-D_GNU_SOURCE'], + dependencies: deps, +) +executable( + 'check_events', + 'check_events.c', + c_args: ['-D_GNU_SOURCE'], + dependencies: deps, +) diff --git a/subprojects/packagefiles/libpfm/include/meson.build b/subprojects/packagefiles/libpfm/include/meson.build new file mode 100644 index 000000000..b7f9d928c --- /dev/null +++ b/subprojects/packagefiles/libpfm/include/meson.build @@ -0,0 +1,7 @@ +inc = include_directories('.') +install_headers( + 'perfmon/pfmlib.h', + 'perfmon/perf_event.h', + 'perfmon/pfmlib_perf_event.h', + subdir: 'perfmon', +) diff --git a/subprojects/packagefiles/libpfm/lib/meson.build b/subprojects/packagefiles/libpfm/lib/meson.build new file mode 100644 index 000000000..564fc7a88 --- /dev/null +++ b/subprojects/packagefiles/libpfm/lib/meson.build @@ -0,0 +1,217 @@ +srcs = files('pfmlib_common.c') + +if host_machine.system() == 'linux' + srcs += files( + 'pfmlib_perf_event.c', + 'pfmlib_perf_event_pmu.c', + 'pfmlib_perf_event_raw.c', + ) +endif + +args = ['-D_REENTRANT'] + +if host_machine.cpu_family() == 'ia64' + args += ['-DCONFIG_PFMLIB_ARCH_IA64'] + +elif host_machine.cpu_family() in ['x86', 'x86_64'] + if host_machine.system() == 'linux' + srcs += files( + 'pfmlib_amd64_perf_event.c', + 'pfmlib_intel_netburst_perf_event.c', + 'pfmlib_intel_snbep_unc_perf_event.c', + 'pfmlib_intel_x86_perf_event.c', + ) + endif + + srcs += files( + 'pfmlib_amd64.c', + 'pfmlib_amd64_fam10h.c', + 'pfmlib_amd64_fam11h.c', + 'pfmlib_amd64_fam12h.c', + 'pfmlib_amd64_fam14h.c', + 'pfmlib_amd64_fam15h.c', + 'pfmlib_amd64_fam16h.c', + 'pfmlib_amd64_fam17h.c', + 'pfmlib_amd64_fam19h.c', + 'pfmlib_amd64_fam19h_l3.c', + 'pfmlib_amd64_k7.c', + 'pfmlib_amd64_k8.c', + 'pfmlib_amd64_rapl.c', + 'pfmlib_intel_atom.c', + 'pfmlib_intel_bdw.c', + 'pfmlib_intel_bdx_unc_cbo.c', + 'pfmlib_intel_bdx_unc_ha.c', + 'pfmlib_intel_bdx_unc_imc.c', + 'pfmlib_intel_bdx_unc_irp.c', + 'pfmlib_intel_bdx_unc_pcu.c', + 'pfmlib_intel_bdx_unc_qpi.c', + 'pfmlib_intel_bdx_unc_r2pcie.c', + 'pfmlib_intel_bdx_unc_r3qpi.c', + 'pfmlib_intel_bdx_unc_sbo.c', + 'pfmlib_intel_bdx_unc_ubo.c', + 'pfmlib_intel_core.c', + 'pfmlib_intel_glm.c', + 'pfmlib_intel_hsw.c', + 'pfmlib_intel_hswep_unc_cbo.c', + 'pfmlib_intel_hswep_unc_ha.c', + 'pfmlib_intel_hswep_unc_imc.c', + 'pfmlib_intel_hswep_unc_irp.c', + 'pfmlib_intel_hswep_unc_pcu.c', + 'pfmlib_intel_hswep_unc_qpi.c', + 'pfmlib_intel_hswep_unc_r2pcie.c', + 'pfmlib_intel_hswep_unc_r3qpi.c', + 'pfmlib_intel_hswep_unc_sbo.c', + 'pfmlib_intel_hswep_unc_ubo.c', + 'pfmlib_intel_icl.c', + 'pfmlib_intel_ivb.c', + 'pfmlib_intel_ivb_unc.c', + 'pfmlib_intel_ivbep_unc_cbo.c', + 'pfmlib_intel_ivbep_unc_ha.c', + 'pfmlib_intel_ivbep_unc_imc.c', + 'pfmlib_intel_ivbep_unc_irp.c', + 'pfmlib_intel_ivbep_unc_pcu.c', + 'pfmlib_intel_ivbep_unc_qpi.c', + 'pfmlib_intel_ivbep_unc_r2pcie.c', + 'pfmlib_intel_ivbep_unc_r3qpi.c', + 'pfmlib_intel_ivbep_unc_ubo.c', + 'pfmlib_intel_knc.c', + 'pfmlib_intel_knl.c', + 'pfmlib_intel_knl_unc_cha.c', + 'pfmlib_intel_knl_unc_edc.c', + 'pfmlib_intel_knl_unc_imc.c', + 'pfmlib_intel_knl_unc_m2pcie.c', + 'pfmlib_intel_netburst.c', + 'pfmlib_intel_nhm.c', + 'pfmlib_intel_nhm_unc.c', + 'pfmlib_intel_rapl.c', + 'pfmlib_intel_skl.c', + 'pfmlib_intel_skx_unc_cha.c', + 'pfmlib_intel_skx_unc_iio.c', + 'pfmlib_intel_skx_unc_imc.c', + 'pfmlib_intel_skx_unc_irp.c', + 'pfmlib_intel_skx_unc_m2m.c', + 'pfmlib_intel_skx_unc_m3upi.c', + 'pfmlib_intel_skx_unc_pcu.c', + 'pfmlib_intel_skx_unc_ubo.c', + 'pfmlib_intel_skx_unc_upi.c', + 'pfmlib_intel_slm.c', + 'pfmlib_intel_snb.c', + 'pfmlib_intel_snb_unc.c', + 'pfmlib_intel_snbep_unc.c', + 'pfmlib_intel_snbep_unc_cbo.c', + 'pfmlib_intel_snbep_unc_ha.c', + 'pfmlib_intel_snbep_unc_imc.c', + 'pfmlib_intel_snbep_unc_pcu.c', + 'pfmlib_intel_snbep_unc_qpi.c', + 'pfmlib_intel_snbep_unc_r2pcie.c', + 'pfmlib_intel_snbep_unc_r3qpi.c', + 'pfmlib_intel_snbep_unc_ubo.c', + 'pfmlib_intel_spr.c', + 'pfmlib_intel_tmt.c', + 'pfmlib_intel_wsm.c', + 'pfmlib_intel_x86.c', + 'pfmlib_intel_x86_arch.c', + ) + args += ['-DCONFIG_PFMLIB_ARCH_X86'] + + if host_machine.cpu_family() == 'x86' + srcs += files('pfmlib_intel_coreduo.c', 'pfmlib_intel_p6.c') + args += ['-DCONFIG_PFMLIB_ARCH_I386'] + elif host_machine.cpu_family() == 'x86_64' + args += ['-DCONFIG_PFMLIB_ARCH_X86_64'] + endif + +elif host_machine.cpu_family() in ['ppc', 'ppc64'] + if host_machine.system() == 'linux' + srcs += files('pfmlib_powerpc_perf_event.c') + endif + + srcs += files( + 'pfmlib_power10.c', + 'pfmlib_power4.c', + 'pfmlib_power5.c', + 'pfmlib_power6.c', + 'pfmlib_power7.c', + 'pfmlib_power8.c', + 'pfmlib_power9.c', + 'pfmlib_powerpc.c', + 'pfmlib_powerpc_nest.c', + 'pfmlib_ppc970.c', + 'pfmlib_torrent.c', + ) + args += ['-DCONFIG_PFMLIB_ARCH_POWERPC'] + +elif host_machine.cpu_family() == 's390x' + if host_machine.system() == 'linux' + srcs += files('pfmlib_s390x_perf_event.c') + endif + + srcs += files('pfmlib_s390x_cpumf.c') + args += ['-DCONFIG_PFMLIB_ARCH_S390X'] + +elif host_machine.cpu_family() in ['sparc', 'sparc64'] + if host_machine.system() == 'linux' + srcs += files('pfmlib_sparc_perf_event.c') + endif + + srcs += files( + 'pfmlib_sparc.c', + 'pfmlib_sparc_niagara.c', + 'pfmlib_sparc_ultra12.c', + 'pfmlib_sparc_ultra3.c', + 'pfmlib_sparc_ultra4.c', + ) + args += ['-DCONFIG_PFMLIB_ARCH_SPARC'] + +elif host_machine.cpu_family() == 'arm' + if host_machine.system() != 'linux' + error('ARM is not supported except on Linux') + endif + + srcs += files( + 'pfmlib_arm.c', + 'pfmlib_arm_armv6.c', + 'pfmlib_arm_armv7_pmuv1.c', + 'pfmlib_arm_armv8.c', + 'pfmlib_arm_armv9.c', + 'pfmlib_arm_perf_event.c', + 'pfmlib_kunpeng_unc_perf_event.c', + 'pfmlib_tx2_unc_perf_event.c', + ) + args += ['-DCONFIG_PFMLIB_ARCH_ARM'] + +elif host_machine.cpu_family() == 'aarch64' + if host_machine.system() != 'linux' + error('ARM is not supported except on Linux') + endif + + srcs += files( + 'pfmlib_arm.c', + 'pfmlib_arm_armv8.c', + 'pfmlib_arm_armv9.c', + 'pfmlib_arm_perf_event.c', + 'pfmlib_kunpeng_unc_perf_event.c', + 'pfmlib_tx2_unc_perf_event.c', + ) + args += ['-DCONFIG_PFMLIB_ARCH_ARM64'] + +elif host_machine.cpu_family() in ['mips', 'mips64'] + if host_machine.system() == 'linux' + srcs += files('pfmlib_mips_perf_event.c') + endif + + srcs += files('pfmlib_mips.c', 'pfmlib_mips_74k.c') + args += ['-DCONFIG_PFMLIB_ARCH_MIPS'] +endif + +libpfm_lib = library( + 'pfm', + srcs, + c_args: args, + gnu_symbol_visibility: 'hidden', + include_directories: inc, + pic: true, + install: true, +) +libpfm_dep = declare_dependency(link_with: libpfm_lib, include_directories: inc) +meson.override_dependency('libpfm', libpfm_dep) diff --git a/subprojects/packagefiles/libpfm/meson.build b/subprojects/packagefiles/libpfm/meson.build new file mode 100644 index 000000000..b2f796591 --- /dev/null +++ b/subprojects/packagefiles/libpfm/meson.build @@ -0,0 +1,53 @@ +project('libpfm', 'c', version: '4.13.0', meson_version: '>=1.0.0') + +cc = meson.get_compiler('c') + +if host_machine.system() != 'linux' + error( + 'Due to upstream bugs, this libpfm wrap does not support building for any platform other than Linux', + ) +endif + +if not cc.has_header('unistd.h') + error('libpfm does not support building without POSIX headers') +endif +if host_machine.system() == 'linux' and not cc.has_header('sys/prctl.h') + error('libpfm does not support building for Linux without Linux headers') +endif + +m_dep = cc.find_library('m', required: false) +rt_dep = cc.find_library('rt', required: false) +threads_dep = dependency('threads') +curses_dep = dependency('curses', required: false, disabler: true) + +add_project_arguments( + cc.get_supported_arguments('-Wno-unused-parameter'), + language: 'c', +) + +if get_option('buildtype').contains('debug') + add_project_arguments('-DCONFIG_PFMLIB_DEBUG', language: 'c') +endif + +if host_machine.system() == 'linux' + add_project_arguments('-DCONFIG_PFMLIB_OS_LINUX', language: 'c') +elif host_machine.system() == 'windows' + add_project_arguments('-DPFMLIB_WINDOWS', language: 'c') +endif + +# Define __WORDSIZE on platforms that don't always #define it, like Musl libc. +# This isn't completely accurate but is close enough for practical purposes. +if not cc.compiles('#include \nstatic int x = __WORDSIZE;') + add_project_arguments( + '-D__WORDSIZE=@0@'.format(cc.sizeof('void*') * 8), + language: 'c', + ) +endif + +subdir('include') +subdir('lib') +subdir('tests') +subdir('examples') +if host_machine.system() == 'linux' + subdir('perf_examples') +endif diff --git a/subprojects/packagefiles/libpfm/perf_examples/meson.build b/subprojects/packagefiles/libpfm/perf_examples/meson.build new file mode 100644 index 000000000..6e351c8a1 --- /dev/null +++ b/subprojects/packagefiles/libpfm/perf_examples/meson.build @@ -0,0 +1,103 @@ +deps = [threads_dep, libpfm_dep] +args = ['-D_GNU_SOURCE'] +common_srcs = files('perf_util.c') + +executable('self', 'self.c', common_srcs, c_args: args, dependencies: deps) +executable( + 'self_basic', + 'self_basic.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'self_count', + 'self_count.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable('task', 'task.c', common_srcs, c_args: args, dependencies: deps) +executable( + 'task_attach_timeout', + 'task_attach_timeout.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable('syst', 'syst.c', common_srcs, c_args: args, dependencies: deps) +executable( + 'notify_self', + 'notify_self.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'notify_group', + 'notify_group.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'task_smpl', + 'task_smpl.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'self_smpl_multi', + 'self_smpl_multi.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'self_pipe', + 'self_pipe.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'syst_count', + 'syst_count.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'task_cpu', + 'task_cpu.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'syst_smpl', + 'syst_smpl.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable('evt2raw', 'evt2raw.c', common_srcs, c_args: args, dependencies: deps) +executable( + 'branch_smpl', + 'branch_smpl.c', + common_srcs, + c_args: args, + dependencies: deps, +) +executable( + 'rtop', + 'rtop.c', + common_srcs, + c_args: args, + dependencies: [curses_dep, m_dep, deps], +) + +if host_machine.cpu_family() in ['x86', 'x86_64'] + subdir('x86') +endif diff --git a/subprojects/packagefiles/libpfm/perf_examples/x86/meson.build b/subprojects/packagefiles/libpfm/perf_examples/x86/meson.build new file mode 100644 index 000000000..7ddb71c8f --- /dev/null +++ b/subprojects/packagefiles/libpfm/perf_examples/x86/meson.build @@ -0,0 +1,8 @@ +executable( + 'bts_smpl', + 'bts_smpl.c', + common_srcs, + c_args: args, + dependencies: deps, + include_directories: include_directories('..'), +) diff --git a/subprojects/packagefiles/libpfm/tests/meson.build b/subprojects/packagefiles/libpfm/tests/meson.build new file mode 100644 index 000000000..96c0ada91 --- /dev/null +++ b/subprojects/packagefiles/libpfm/tests/meson.build @@ -0,0 +1,22 @@ +srcs = files('validate.c') +deps = [m_dep, libpfm_dep] + +if host_machine.cpu_family() in ['x86', 'x86_64'] + srcs += files('validate_x86.c') +elif host_machine.cpu_family() in ['mips', 'mips64'] + srcs += files('validate_mips.c') +elif host_machine.cpu_family() == 'arm' + srcs += files('validate_arm.c') +elif host_machine.cpu_family() == 'aarch64' + srcs += files('validate_arm64.c') +elif host_machine.cpu_family() in ['ppc', 'ppc64'] + srcs += files('validate_power.c') +endif + +if host_machine.system() == 'linux' + srcs += files('validate_perf.c') + deps += threads_dep +endif + +val = executable('validate', srcs, c_args: '-D_GNU_SOURCE', dependencies: deps) +test('validate', val)