• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jbboehr / php-perf / 8566247520

05 Apr 2024 07:01AM UTC coverage: 86.094% (-0.1%) from 86.19%
8566247520

push

github

jbboehr
Various cleanup and fixes

158 of 186 new or added lines in 7 files covered. (84.95%)

3 existing lines in 2 files now uncovered.

551 of 640 relevant lines covered (86.09%)

356.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.06
/src/functions.c
1
/**
2
 * Copyright (C) 2024 John Boehr & contributors
3
 *
4
 * This file is part of php-perf.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19

20
#ifdef HAVE_CONFIG_H
21
#include "config.h"
22
#endif
23

24
#include <unistd.h>
25
#include <sys/capability.h>
26
#include <perfmon/pfmlib.h>
27
#include <Zend/zend_API.h>
28
#include <Zend/zend_exceptions.h>
29
#include <Zend/zend_portability.h>
30
#include "main/php.h"
31
#include "php_perf.h"
32
#include "functions.h"
33
#include "handle.h"
34
#include "private.h"
35

36
ZEND_COLD
37
PERFIDIOUS_LOCAL
38
PHP_FUNCTION(perfidious_get_pmu_info)
6✔
39
{
40
    zend_long pmu;
41

42
    ZEND_PARSE_PARAMETERS_START(1, 1)
6✔
43
        Z_PARAM_LONG(pmu)
12✔
44
    ZEND_PARSE_PARAMETERS_END();
6✔
45

46
    if (SUCCESS != perfidious_get_pmu_info(pmu, return_value, false)) {
6✔
47
        RETURN_NULL();
3✔
48
    }
49
}
50

51
ZEND_COLD
52
PERFIDIOUS_LOCAL
53
PHP_FUNCTION(perfidious_global_handle)
12✔
54
{
55
    ZEND_PARSE_PARAMETERS_NONE();
12✔
56

57
    if (EXPECTED(PERFIDIOUS_G(global_enable) && PERFIDIOUS_G(global_handle))) {
12✔
58
        object_init_ex(return_value, perfidious_handle_ce);
9✔
59

60
        struct perfidious_handle_obj *obj = perfidious_fetch_handle_object(Z_OBJ_P(return_value));
9✔
61
        obj->no_auto_close = true;
9✔
62
        obj->handle = PERFIDIOUS_G(global_handle);
9✔
63
    } else {
64
        RETURN_NULL();
3✔
65
    }
66
}
67

68
ZEND_COLD
69
PERFIDIOUS_LOCAL
70
PHP_FUNCTION(perfidious_list_pmus)
3✔
71
{
72
    zend_long index;
73
    zval tmp = {0};
3✔
74

75
    ZEND_PARSE_PARAMETERS_NONE();
3✔
76

77
    array_init(return_value);
3✔
78

79
    pfm_for_all_pmus(index)
1,365✔
80
    {
81
        if (SUCCESS == perfidious_get_pmu_info(index, &tmp, true)) {
1,362✔
82
            add_next_index_zval(return_value, &tmp);
83
        }
84
    }
85
}
86

87
ZEND_COLD
88
PERFIDIOUS_LOCAL
89
PHP_FUNCTION(perfidious_list_pmu_events)
3✔
90
{
91
    zend_long pmu_id;
92

93
    ZEND_PARSE_PARAMETERS_START(1, 1)
3✔
94
        Z_PARAM_LONG(pmu_id)
6✔
95
    ZEND_PARSE_PARAMETERS_END();
3✔
96

97
    pfm_pmu_t pmu = pmu_id;
3✔
98
    pfm_pmu_info_t pmu_info = {0};
3✔
99
    pfm_err_t pfm_err;
100
    zval tmp = {0};
3✔
101

102
    pmu_info.size = sizeof(pmu_info);
3✔
103

104
    pfm_err = pfm_get_pmu_info(pmu, &pmu_info);
3✔
105
    if (pfm_err != PFM_SUCCESS) {
3✔
UNCOV
106
        zend_throw_exception_ex(
×
107
            perfidious_pmu_not_found_exception_ce,
108
            pfm_err,
109
            "libpfm: cannot get pmu info for %lu: %s",
110
            (zend_long) pmu,
111
            pfm_strerror(pfm_err)
112
        );
NEW
113
        RETURN_NULL();
×
114
    }
115

116
    array_init(return_value);
3✔
117

118
    for (int i = pmu_info.first_event; i != -1; i = pfm_get_event_next(i)) {
249✔
119
        if (UNEXPECTED(FAILURE == perfidious_get_pmu_event_info(&pmu_info, i, &tmp))) {
246✔
NEW
120
            zval_ptr_dtor(return_value);
×
NEW
121
            RETURN_NULL();
×
122
        }
123

124
        add_next_index_zval(return_value, &tmp);
125
    }
126
}
127

128
ZEND_COLD
129
PERFIDIOUS_LOCAL
130
PHP_FUNCTION(perfidious_open)
39✔
131
{
132
    HashTable *event_names_ht;
133
    zend_long pid_zl = 0;
39✔
134
    zend_long cpu = -1;
39✔
135
    zval *z;
136
    pid_t pid;
137

138
    ZEND_PARSE_PARAMETERS_START(1, 3)
39✔
139
        Z_PARAM_ARRAY_HT(event_names_ht);
78✔
140
        Z_PARAM_OPTIONAL
39✔
141
        Z_PARAM_LONG(pid_zl)
48✔
142
        Z_PARAM_LONG(cpu)
12✔
143
    ZEND_PARSE_PARAMETERS_END();
39✔
144

145
    if (false == perfidious_zend_long_to_pid_t(pid_zl, &pid)) {
39✔
146
        RETURN_NULL();
3✔
147
    }
148

149
    // Check capability if pid > 0
150
    if (pid > 0) {
36✔
151
        cap_t cap = cap_get_proc();
3✔
152
        if (cap != NULL) {
3✔
153
            cap_flag_value_t v = CAP_CLEAR;
3✔
154
            cap_get_flag(cap, CAP_PERFMON, CAP_EFFECTIVE, &v);
3✔
155
            if (v == CAP_CLEAR) {
3✔
156
                zend_throw_exception_ex(perfidious_io_exception_ce, 0, "pid greater than zero and CAP_PERFMON not set");
3✔
157
                return;
3✔
158
            }
159
        }
160
    }
161

162
    // Check cpu for overflow
163
    long int n_proc_onln = sysconf(_SC_NPROCESSORS_ONLN);
33✔
164
    if (cpu > n_proc_onln) {
33✔
165
        zend_throw_exception_ex(perfidious_overflow_exception_ce, 0, "cpu too large: %ld > %ld", cpu, n_proc_onln);
3✔
166
        return;
3✔
167
    }
168

169
    // Copy event names into an array
170
    zend_string **arr = alloca(sizeof(zend_string *) * (zend_array_count(event_names_ht) + 1));
30✔
171
    size_t arr_count = 0;
30✔
172

173
    ZEND_HASH_FOREACH_VAL(event_names_ht, z)
102✔
174
    {
175
        if (EXPECTED(Z_TYPE_P(z) == IS_STRING)) {
36✔
176
            arr[arr_count++] = Z_STR_P(z);
33✔
177
        } else {
178
            zend_type_error("All event names must be strings");
3✔
179
        }
180
    }
181
    ZEND_HASH_FOREACH_END();
182

183
    arr[arr_count] = NULL;
30✔
184

185
    struct perfidious_handle *handle = perfidious_handle_open_ex(arr, arr_count, pid, (int) cpu, false);
30✔
186

187
    if (UNEXPECTED(NULL == handle)) {
30✔
188
        RETURN_NULL();
3✔
189
    }
190

191
    object_init_ex(return_value, perfidious_handle_ce);
27✔
192

193
    struct perfidious_handle_obj *obj = perfidious_fetch_handle_object(Z_OBJ_P(return_value));
27✔
194
    obj->handle = handle;
27✔
195
}
196

197
ZEND_COLD
198
PERFIDIOUS_LOCAL
199
PHP_FUNCTION(perfidious_request_handle)
12✔
200
{
201
    ZEND_PARSE_PARAMETERS_NONE();
12✔
202

203
    if (EXPECTED(PERFIDIOUS_G(request_enable) && PERFIDIOUS_G(request_handle))) {
12✔
204
        object_init_ex(return_value, perfidious_handle_ce);
9✔
205

206
        struct perfidious_handle_obj *obj = perfidious_fetch_handle_object(Z_OBJ_P(return_value));
9✔
207
        obj->no_auto_close = true;
9✔
208
        obj->handle = PERFIDIOUS_G(request_handle);
9✔
209
    } else {
210
        RETURN_NULL();
3✔
211
    }
212
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc