Skip to content

Commit f4211e1

Browse files
feat(debug): add more metrics in ThreadDebugState
1 parent 1bd96ad commit f4211e1

File tree

7 files changed

+61
-35
lines changed

7 files changed

+61
-35
lines changed

debugstate.go

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package frankenphp
22

3+
// #include "frankenphp.h"
4+
import "C"
35
import (
46
"github.com/dunglas/frankenphp/internal/state"
57
)
@@ -56,25 +58,30 @@ func threadDebugState(thread *phpThread) ThreadDebugState {
5658
}
5759

5860
s.RequestCount = thread.requestCount.Load()
59-
s.MemoryUsage = thread.lastMemoryUsage.Load()
61+
s.MemoryUsage = int64(C.frankenphp_get_thread_memory_usage(C.uintptr_t(thread.threadIndex)))
6062

61-
if isBusy {
62-
thread.handlerMu.RLock()
63-
fc := thread.handler.frankenPHPContext()
64-
thread.handlerMu.RUnlock()
63+
if !isBusy {
64+
return s
65+
}
6566

66-
if fc != nil && fc.request != nil && fc.responseWriter != nil {
67-
if fc.originalRequest != nil {
68-
s.CurrentURI = fc.originalRequest.URL.RequestURI()
69-
s.CurrentMethod = fc.originalRequest.Method
70-
} else {
71-
s.CurrentURI = fc.requestURI
72-
s.CurrentMethod = fc.request.Method
73-
}
74-
if !fc.startedAt.IsZero() {
75-
s.RequestStartedAt = fc.startedAt.UnixMilli()
76-
}
77-
}
67+
thread.handlerMu.RLock()
68+
defer thread.handlerMu.RUnlock()
69+
70+
fc := thread.handler.frankenPHPContext()
71+
if fc == nil || fc.request == nil || fc.responseWriter == nil {
72+
return s
73+
}
74+
75+
if fc.originalRequest == nil {
76+
s.CurrentURI = fc.requestURI
77+
s.CurrentMethod = fc.request.Method
78+
} else {
79+
s.CurrentURI = fc.originalRequest.URL.RequestURI()
80+
s.CurrentMethod = fc.originalRequest.Method
81+
}
82+
83+
if !fc.startedAt.IsZero() {
84+
s.RequestStartedAt = fc.startedAt.UnixMilli()
7885
}
7986

8087
return s

frankenphp.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,12 @@ static void frankenphp_reset_session_state(void) {
244244
}
245245
#endif
246246

247-
static __thread size_t thread_last_memory_usage = 0;
247+
static frankenphp_thread_metrics *thread_metrics = NULL;
248248

249249
/* Adapted from php_request_shutdown */
250250
static void frankenphp_worker_request_shutdown() {
251-
thread_last_memory_usage = zend_memory_usage(0);
251+
__atomic_store_n(&thread_metrics[thread_index].last_memory_usage,
252+
zend_memory_usage(0), __ATOMIC_RELAXED);
252253

253254
/* Flush all output buffers */
254255
zend_try { php_output_end_all(); }
@@ -1237,7 +1238,8 @@ int frankenphp_execute_script(char *file_name) {
12371238
sandboxed_env = NULL;
12381239
}
12391240

1240-
thread_last_memory_usage = zend_memory_usage(0);
1241+
__atomic_store_n(&thread_metrics[thread_index].last_memory_usage,
1242+
zend_memory_usage(0), __ATOMIC_RELAXED);
12411243
php_request_shutdown((void *)0);
12421244
frankenphp_free_request_context();
12431245

@@ -1410,7 +1412,19 @@ int frankenphp_reset_opcache(void) {
14101412

14111413
int frankenphp_get_current_memory_limit() { return PG(memory_limit); }
14121414

1413-
size_t frankenphp_get_current_memory_usage() { return thread_last_memory_usage; }
1415+
void frankenphp_init_thread_metrics(int max_threads) {
1416+
thread_metrics = calloc(max_threads, sizeof(frankenphp_thread_metrics));
1417+
}
1418+
1419+
void frankenphp_destroy_thread_metrics(void) {
1420+
free(thread_metrics);
1421+
thread_metrics = NULL;
1422+
}
1423+
1424+
size_t frankenphp_get_thread_memory_usage(uintptr_t idx) {
1425+
return __atomic_load_n(&thread_metrics[idx].last_memory_usage,
1426+
__ATOMIC_RELAXED);
1427+
}
14141428

14151429
static zend_module_entry **modules = NULL;
14161430
static int modules_len = 0;

frankenphp.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ void frankenphp_register_server_vars(zval *track_vars_array,
185185
zend_string *frankenphp_init_persistent_string(const char *string, size_t len);
186186
int frankenphp_reset_opcache(void);
187187
int frankenphp_get_current_memory_limit();
188-
size_t frankenphp_get_current_memory_usage();
188+
189+
typedef struct {
190+
size_t last_memory_usage;
191+
} frankenphp_thread_metrics;
192+
193+
void frankenphp_init_thread_metrics(int max_threads);
194+
void frankenphp_destroy_thread_metrics(void);
195+
size_t frankenphp_get_thread_memory_usage(uintptr_t thread_index);
189196

190197
void register_extensions(zend_module_entry **m, int len);
191198

phpmainthread.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ func initPHPThreads(numThreads int, numMaxThreads int, phpIni map[string]string)
5454
return nil, err
5555
}
5656

57+
C.frankenphp_init_thread_metrics(C.int(mainThread.maxThreads))
58+
5759
// initialize all other threads
5860
phpThreads = make([]*phpThread, mainThread.maxThreads)
5961
phpThreads[0] = initialThread
@@ -97,6 +99,7 @@ func drainPHPThreads() {
9799
doneWG.Wait()
98100
mainThread.state.Set(state.Done)
99101
mainThread.state.WaitFor(state.Reserved)
102+
C.frankenphp_destroy_thread_metrics()
100103
phpThreads = nil
101104
}
102105

phpthread.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@ import (
1717
// identified by the index in the phpThreads slice
1818
type phpThread struct {
1919
runtime.Pinner
20-
threadIndex int
21-
requestChan chan contextHolder
22-
drainChan chan struct{}
23-
handlerMu sync.RWMutex
24-
handler threadHandler
25-
state *state.ThreadState
26-
requestCount atomic.Int64
27-
lastMemoryUsage atomic.Int64
20+
threadIndex int
21+
requestChan chan contextHolder
22+
drainChan chan struct{}
23+
handlerMu sync.RWMutex
24+
handler threadHandler
25+
state *state.ThreadState
26+
requestCount atomic.Int64
2827
}
2928

3029
// threadHandler defines how the callbacks from the C thread should be handled
@@ -176,10 +175,6 @@ func go_frankenphp_after_script_execution(threadIndex C.uintptr_t, exitStatus C.
176175
if exitStatus < 0 {
177176
panic(ErrScriptExecution)
178177
}
179-
180-
thread.requestCount.Add(1)
181-
thread.lastMemoryUsage.Store(int64(C.frankenphp_get_current_memory_usage()))
182-
183178
thread.handler.afterScriptExecution(int(exitStatus))
184179

185180
// unpin all memory used during script execution

threadregular.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func (handler *regularThread) beforeScriptExecution() string {
6060
}
6161

6262
func (handler *regularThread) afterScriptExecution(_ int) {
63+
handler.thread.requestCount.Add(1)
6364
handler.afterRequest()
6465
}
6566

threadworker.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ func go_frankenphp_finish_worker_request(threadIndex C.uintptr_t, retval *C.zval
293293
}
294294

295295
thread.requestCount.Add(1)
296-
thread.lastMemoryUsage.Store(int64(C.frankenphp_get_current_memory_usage()))
297296

298297
fc.closeContext()
299298
thread.handler.(*workerThread).workerFrankenPHPContext = nil

0 commit comments

Comments
 (0)