Skip to content

Commit

Permalink
Extract time_enabled and time_running
Browse files Browse the repository at this point in the history
Also, use interned strings where possible
  • Loading branch information
jbboehr committed Apr 5, 2024
1 parent 780a0d3 commit 0727b0e
Show file tree
Hide file tree
Showing 25 changed files with 543 additions and 177 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(SOURCE_FILES
src/handle.c
src/pmu_event_info.c
src/pmu_info.c
src/read_result.c
)

add_compile_definitions(HAVE_CONFIG_H=1)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ $handle = PerfExt\open(["perf::PERF_COUNT_SW_CPU_CLOCK"]);
$handle->enable();
for ($i = 0; $i < 3; $i++) {
var_dump($handle->read());
var_dump($handle->readArray());
sleep(1);
}
```
Expand Down
4 changes: 4 additions & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,15 @@ if test "$PHP_PERF" != "no"; then
])

AC_CHECK_SIZEOF(pid_t)
AC_CHECK_SIZEOF(uint64_t)

CFLAGS="$WARN_CFLAGS $CFLAGS"
LDFLAGS="$WARN_LDFLAGS $LDFLAGS"

if test "$PHP_PERF_DEBUG" == "yes"; then
AC_DEFINE([PERF_DEBUG], [1], [Enable vyrtue debug support])
else
AC_DEFINE([NDEBUG], [1], [Disable debug support])
fi

PHP_ADD_LIBRARY(cap, , PERF_SHARED_LIBADD)
Expand All @@ -60,6 +63,7 @@ if test "$PHP_PERF" != "no"; then
src/handle.c
src/pmu_event_info.c
src/pmu_info.c
src/read_result.c
])

PHP_ADD_BUILD_DIR(src)
Expand Down
4 changes: 2 additions & 2 deletions examples/estimate-overhead.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@

for ($i = 0; $i < $count; $i++) {
$handle->reset();
$left = $handle->read();
$right = $handle->read();
$left = $handle->readArray();
$right = $handle->readArray();
foreach ($left as $k => $lv) {
$rv = $right[$k];
$delta = abs($lv - $rv);
Expand Down
2 changes: 1 addition & 1 deletion examples/three-sw-clock.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
$handle->enable();

for ($i = 0; $i < 3; $i++) {
var_dump($handle->read());
var_dump($handle->readArray());
sleep(1);
}

8 changes: 7 additions & 1 deletion examples/watch.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@

while (true) {
$stats = $handle->read();
$percent_running = $stats->timeEnabled > 0 ? 100 * $stats->timeRunning / $stats->timeEnabled : 0;

printf("cpu=%d pid=%d\n", $cpu, $pid);
foreach ($stats as $k => $v) {
printf("time_enabled=%d time_running=%d percent_running=%d%%\n", $stats->timeEnabled, $stats->timeRunning, $percent_running);
foreach ($stats->values as $k => $v) {
printf("%s=%d\n", $k, $v);
}

usleep($interval);
}

foreach ($tmp as $k => $v) {
echo $k;
}
22 changes: 18 additions & 4 deletions perf.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,37 @@ final class Handle
/**
* @throws IOException
*/
public function enable(): self {}
final public function enable(): self {}

/**
* @throws IOException
*/
public function disable(): self {}
final public function disable(): self {}

/**
* @return array<string, int>
* @throws OverflowException|IOException
*/
public function read(): array {}
final public function read(): ReadResult {}

/**
* @return array<string, int>
* @throws OverflowException|IOException
*/
final public function readArray(): array {}

/**
* @throws IOException
*/
public function reset(): self {}
final public function reset(): self {}
}

final class ReadResult
{
public readonly int $timeEnabled;
public readonly int $timeRunning;
/** @var array<string, int> **/
public readonly array $values;
}

/**
Expand Down
11 changes: 10 additions & 1 deletion php_perf.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ PERFIDIOUS_PUBLIC extern zend_class_entry *perfidious_io_exception_ce;
PERFIDIOUS_PUBLIC extern zend_class_entry *perfidious_pmu_event_info_ce;
PERFIDIOUS_PUBLIC extern zend_class_entry *perfidious_pmu_info_ce;
PERFIDIOUS_PUBLIC extern zend_class_entry *perfidious_handle_ce;
PERFIDIOUS_PUBLIC extern zend_class_entry *perfidious_read_result_ce;

ZEND_BEGIN_MODULE_GLOBALS(perf)
zend_bool global_enable;
Expand Down Expand Up @@ -136,8 +137,16 @@ PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
struct perfidious_handle *
perfidious_handle_open_ex(zend_string **event_names, size_t event_names_length, pid_t pid, int cpu, bool persist);

ZEND_HOT
PERFIDIOUS_PUBLIC
PERFIDIOUS_ATTR_NONNULL_ALL
zend_result perfidious_handle_read_to_array(struct perfidious_handle *handle, zval *return_value);
PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
size_t perfidious_handle_read_buffer_size(struct perfidious_handle *restrict handle);

ZEND_HOT
PERFIDIOUS_PUBLIC
PERFIDIOUS_ATTR_NONNULL_ALL
PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
zend_result perfidious_handle_read_raw(struct perfidious_handle *restrict handle, size_t size, void *restrict buffer);

#endif /* PHP_PERF_H */
12 changes: 5 additions & 7 deletions src/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static zend_class_entry *register_class_ExceptionInterface(void)

PERFIDIOUS_ATTR_RETURNS_NONNULL
PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
static zend_class_entry *register_class_OverflowException(zend_class_entry *iface)
static zend_class_entry *register_class_OverflowException(zend_class_entry *restrict iface)
{
zend_class_entry ce;
zend_class_entry *class_entry;
Expand All @@ -61,7 +61,7 @@ static zend_class_entry *register_class_OverflowException(zend_class_entry *ifac

PERFIDIOUS_ATTR_RETURNS_NONNULL
PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
static zend_class_entry *register_class_PmuNotFoundException(zend_class_entry *iface)
static zend_class_entry *register_class_PmuNotFoundException(zend_class_entry *restrict iface)
{
zend_class_entry ce;
zend_class_entry *class_entry;
Expand All @@ -76,7 +76,7 @@ static zend_class_entry *register_class_PmuNotFoundException(zend_class_entry *i

PERFIDIOUS_ATTR_RETURNS_NONNULL
PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
static zend_class_entry *register_class_PmuEventNotFoundException(zend_class_entry *iface)
static zend_class_entry *register_class_PmuEventNotFoundException(zend_class_entry *restrict iface)
{
zend_class_entry ce;
zend_class_entry *class_entry;
Expand All @@ -91,7 +91,7 @@ static zend_class_entry *register_class_PmuEventNotFoundException(zend_class_ent

PERFIDIOUS_ATTR_RETURNS_NONNULL
PERFIDIOUS_ATTR_WARN_UNUSED_RESULT
static zend_class_entry *register_class_IOException(zend_class_entry *iface)
static zend_class_entry *register_class_IOException(zend_class_entry *restrict iface)
{
zend_class_entry ce;
zend_class_entry *class_entry;
Expand All @@ -105,14 +105,12 @@ static zend_class_entry *register_class_IOException(zend_class_entry *iface)
}

PERFIDIOUS_LOCAL
zend_result perfidious_exceptions_minit(void)
void perfidious_exceptions_minit(void)
{
perfidious_exception_interface_ce = register_class_ExceptionInterface();
perfidious_overflow_exception_ce = register_class_OverflowException(perfidious_exception_interface_ce);
perfidious_pmu_not_found_exception_ce = register_class_PmuNotFoundException(perfidious_exception_interface_ce);
perfidious_pmu_event_not_found_exception_ce =
register_class_PmuEventNotFoundException(perfidious_exception_interface_ce);
perfidious_io_exception_ce = register_class_IOException(perfidious_exception_interface_ce);

return SUCCESS;
}
33 changes: 13 additions & 20 deletions src/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,20 @@
#include "main/php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"

#include "php_perf.h"
#include "./functions.h"
#include "functions.h"
#include "handle.h"

#define DEFAULT_METRICS "perf::PERF_COUNT_HW_CPU_CYCLES,perf::PERF_COUNT_HW_INSTRUCTIONS"

ZEND_DECLARE_MODULE_GLOBALS(perf);

PERFIDIOUS_LOCAL zend_result perfidious_exceptions_minit(void);
PERFIDIOUS_LOCAL zend_result perfidious_handle_minit(void);
PERFIDIOUS_LOCAL zend_result perfidious_pmu_event_info_minit(void);
PERFIDIOUS_LOCAL zend_result perfidious_pmu_info_minit(void);
PERFIDIOUS_LOCAL void perfidious_exceptions_minit(void);
PERFIDIOUS_LOCAL void perfidious_handle_minit(void);
PERFIDIOUS_LOCAL void perfidious_pmu_event_info_minit(void);
PERFIDIOUS_LOCAL void perfidious_pmu_info_minit(void);
PERFIDIOUS_LOCAL void perfidious_read_result_minit(void);

#if PHP_VERSION_ID < 80200
static ZEND_INI_MH(OnUpdateStr)
Expand Down Expand Up @@ -153,21 +156,11 @@ static PHP_MINIT_FUNCTION(perf)

REGISTER_STRING_CONSTANT(PHP_PERF_NAMESPACE "\\VERSION", (char *) PHP_PERF_VERSION, flags);

if (SUCCESS != perfidious_exceptions_minit()) {
return FAILURE;
}

if (SUCCESS != perfidious_handle_minit()) {
return FAILURE;
}

if (SUCCESS != perfidious_pmu_event_info_minit()) {
return FAILURE;
}

if (SUCCESS != perfidious_pmu_info_minit()) {
return FAILURE;
}
perfidious_exceptions_minit();
perfidious_handle_minit();
perfidious_pmu_event_info_minit();
perfidious_pmu_info_minit();
perfidious_read_result_minit();

if (PERF_G(global_enable) && PERF_G(global_metrics) != NULL) {
struct perfidious_handle *handle = NULL;
Expand Down
83 changes: 53 additions & 30 deletions src/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
#include <Zend/zend_portability.h>
#include "main/php.h"
#include "php_perf.h"
#include "./functions.h"
#include "./handle.h"
#include "functions.h"
#include "handle.h"
#include "private.h"

ZEND_COLD
PERFIDIOUS_ATTR_NONNULL_ALL
Expand All @@ -39,6 +40,7 @@ static zend_result perfidious_get_pmu_info(zend_long pmu, zval *rv, bool silent)
{
pfm_pmu_info_t pmu_info = {0};
int ret;
zval tmp = {0};

pmu_info.size = sizeof(pmu_info);

Expand All @@ -55,14 +57,25 @@ static zend_result perfidious_get_pmu_info(zend_long pmu, zval *rv, bool silent)
ZVAL_UNDEF(rv);
object_init_ex(rv, perfidious_pmu_info_ce);

zend_update_property_string(Z_OBJCE_P(rv), Z_OBJ_P(rv), "name", sizeof("name") - 1, pmu_info.name);
zend_update_property_string(Z_OBJCE_P(rv), Z_OBJ_P(rv), "desc", sizeof("desc") - 1, pmu_info.desc);
zend_update_property_long(Z_OBJCE_P(rv), Z_OBJ_P(rv), "pmu", sizeof("pmu") - 1, (zend_long) pmu_info.pmu);
zend_update_property_long(Z_OBJCE_P(rv), Z_OBJ_P(rv), "type", sizeof("type") - 1, (zend_long) pmu_info.type);
zend_update_property_long(
Z_OBJCE_P(rv), Z_OBJ_P(rv), "nevents", sizeof("nevents") - 1, (zend_long) pmu_info.nevents
);
zend_update_property_bool(Z_OBJCE_P(rv), Z_OBJ_P(rv), "is_present", sizeof("is_present") - 1, pmu_info.is_present);
ZVAL_STRING(&tmp, pmu_info.name);
zend_update_property_ex(Z_OBJCE_P(rv), Z_OBJ_P(rv), PERFIDIOUS_INTERNED_NAME, &tmp);
zval_ptr_dtor(&tmp);

ZVAL_STRING(&tmp, pmu_info.desc);
zend_update_property_ex(Z_OBJCE_P(rv), Z_OBJ_P(rv), PERFIDIOUS_INTERNED_DESC, &tmp);
zval_ptr_dtor(&tmp);

ZVAL_LONG(&tmp, (zend_long) pmu_info.pmu);
zend_update_property_ex(Z_OBJCE_P(rv), Z_OBJ_P(rv), PERFIDIOUS_INTERNED_PMU, &tmp);

ZVAL_LONG(&tmp, (zend_long) pmu_info.type);
zend_update_property_ex(Z_OBJCE_P(rv), Z_OBJ_P(rv), PERFIDIOUS_INTERNED_TYPE, &tmp);

ZVAL_LONG(&tmp, (zend_long) pmu_info.nevents);
zend_update_property_ex(Z_OBJCE_P(rv), Z_OBJ_P(rv), PERFIDIOUS_INTERNED_NEVENTS, &tmp);

ZVAL_BOOL(&tmp, (zend_bool) pmu_info.is_present);
zend_update_property_ex(Z_OBJCE_P(rv), Z_OBJ_P(rv), PERFIDIOUS_INTERNED_IS_PRESENT, &tmp);

return SUCCESS;
}
Expand Down Expand Up @@ -167,24 +180,38 @@ PHP_FUNCTION(perfidious_list_pmu_events)
}

char buf[512];
zval arr = {0};
zval tmp = {0};
array_init(&tmp);

array_init(&arr);

object_init_ex(&arr, perfidious_pmu_event_info_ce);

size_t buf_len = snprintf(buf, sizeof(buf), "%s::%s", pinfo.name, info.name);

object_init_ex(&tmp, perfidious_pmu_event_info_ce);
ZVAL_STRINGL(&tmp, buf, buf_len);
zend_update_property_ex(Z_OBJCE(arr), Z_OBJ(arr), PERFIDIOUS_INTERNED_NAME, &tmp);
zval_ptr_dtor(&tmp);

zend_update_property_stringl(Z_OBJCE(tmp), Z_OBJ(tmp), "name", sizeof("name") - 1, buf, buf_len);
zend_update_property_string(Z_OBJCE(tmp), Z_OBJ(tmp), "desc", sizeof("desc") - 1, info.desc);
if (info.equiv) {
zend_update_property_string(Z_OBJCE(tmp), Z_OBJ(tmp), "equiv", sizeof("equiv") - 1, info.equiv);
ZVAL_STRING(&tmp, info.desc);
zend_update_property_ex(Z_OBJCE(arr), Z_OBJ(arr), PERFIDIOUS_INTERNED_DESC, &tmp);
zval_ptr_dtor(&tmp);

if (info.equiv != NULL) {
ZVAL_STRING(&tmp, info.equiv);
} else {
zend_update_property_null(Z_OBJCE(tmp), Z_OBJ(tmp), "equiv", sizeof("equiv") - 1);
ZVAL_NULL(&tmp);
}
zend_update_property_long(Z_OBJCE(tmp), Z_OBJ(tmp), "pmu", sizeof("pmu") - 1, (zend_long) info.pmu);
zend_update_property_bool(Z_OBJCE(tmp), Z_OBJ(tmp), "is_present", sizeof("is_present") - 1, pinfo.is_present);
zend_update_property_ex(Z_OBJCE(arr), Z_OBJ(arr), PERFIDIOUS_INTERNED_EQUIV, &tmp);
zval_ptr_dtor(&tmp);

ZVAL_LONG(&tmp, (zend_long) info.pmu);
zend_update_property_ex(Z_OBJCE(arr), Z_OBJ(arr), PERFIDIOUS_INTERNED_PMU, &tmp);

ZVAL_BOOL(&tmp, pinfo.is_present);
zend_update_property_ex(Z_OBJCE(arr), Z_OBJ(arr), PERFIDIOUS_INTERNED_IS_PRESENT, &tmp);

add_next_index_zval(return_value, &tmp);
add_next_index_zval(return_value, &arr);
}
}

Expand All @@ -193,25 +220,21 @@ PERFIDIOUS_LOCAL
PHP_FUNCTION(perfidious_open)
{
HashTable *event_names_ht;
zend_long pid = 0;
zend_long pid_zl = 0;
zend_long cpu = -1;
zval *z;
pid_t pid;

ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_ARRAY_HT(event_names_ht);
Z_PARAM_OPTIONAL
Z_PARAM_LONG(pid)
Z_PARAM_LONG(pid_zl)
Z_PARAM_LONG(cpu)
ZEND_PARSE_PARAMETERS_END();

#if SIZEOF_ZEND_LONG > SIZEOF_PID_T
// Check pid for overflow
const zend_long PID_MAX = (((zend_long) 1) << ((SIZEOF_PID_T * 8) - 1)) - 1;
if (pid > PID_MAX) {
zend_throw_exception_ex(perfidious_overflow_exception_ce, 0, "pid too large: %ld > %ld", pid, PID_MAX);
return;
if (false == perfidious_zend_long_to_pid_t(pid_zl, &pid)) {
RETURN_NULL();
}
#endif

// Check capability if pid > 0
if (pid > 0) {
Expand Down Expand Up @@ -247,7 +270,7 @@ PHP_FUNCTION(perfidious_open)

arr[arr_count] = NULL;

struct perfidious_handle *handle = perfidious_handle_open_ex(arr, arr_count, (pid_t) pid, (int) cpu, false);
struct perfidious_handle *handle = perfidious_handle_open_ex(arr, arr_count, pid, (int) cpu, false);

object_init_ex(return_value, perfidious_handle_ce);

Expand Down
Loading

0 comments on commit 0727b0e

Please sign in to comment.