Skip to content

Commit

Permalink
Add Process::getAffinity(), Thread::setName(), Thread::setAffinity(),…
Browse files Browse the repository at this point in the history
… Thread::getAffinity(), Thread::setPriority(), Thread::getPriority(), Thread::gettid()
  • Loading branch information
matyhtf committed Sep 26, 2024
1 parent 62f3c08 commit 1d24c27
Show file tree
Hide file tree
Showing 16 changed files with 362 additions and 14 deletions.
5 changes: 5 additions & 0 deletions ext-src/php_swoole_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ int php_swoole_convert_to_fd_ex(zval *zsocket, int *async);
php_socket *php_swoole_convert_to_socket(int sock);
#endif

#ifdef HAVE_CPU_AFFINITY
bool php_swoole_array_to_cpu_set(zval *array, cpu_set_t *cpu_set);
void php_swoole_cpu_set_to_array(zval *array, cpu_set_t *cpu_set);
#endif

zend_bool php_swoole_signal_isset_handler(int signo);

#if PHP_VERSION_ID < 80200
Expand Down
1 change: 1 addition & 0 deletions ext-src/stubs/php_swoole_process.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static function wait(bool $blocking = true): array|false {}
public static function daemon(bool $nochdir = true, bool $noclose = true, array $pipes = []): bool {}
#ifdef HAVE_CPU_AFFINITY
public static function setAffinity(array $cpu_settings): bool {}
public static function getAffinity(): array {}
#endif
public function set(array $settings): void {}
public function setTimeout(float $seconds): bool {}
Expand Down
7 changes: 6 additions & 1 deletion ext-src/stubs/php_swoole_process_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: da9456fa0529629d994305f53fd07b250c36a56a */
* Stub hash: e772aa72b9cf7af24c2ed5ab7bbabb7f6a34c3ed */

ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Process___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
Expand Down Expand Up @@ -62,6 +62,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Process_setAffinity
ZEND_END_ARG_INFO()
#endif

#if defined(HAVE_CPU_AFFINITY)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Process_getAffinity, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#endif

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Process_set, 0, 1, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, settings, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
Expand Down
11 changes: 11 additions & 0 deletions ext-src/stubs/php_swoole_thread.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,16 @@ public function detach(): bool {}
public static function getArguments(): ?array {}
public static function getId(): int {}
public static function getTsrmInfo(): array {}

public static function setName(string $name): bool {}
#ifdef HAVE_CPU_AFFINITY
public static function setAffinity(array $cpu_settings): bool {}
public static function getAffinity(): array {}
#endif
public function setPriority(int $priority, int $policy = 0): bool {}
public function getPriority(): array {}
#ifdef __linux__
public function gettid(): int {}
#endif
}
}
29 changes: 28 additions & 1 deletion ext-src/stubs/php_swoole_thread_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 261ac9fd29d4f2f37118ff3b96428a0b2f85223a */
* Stub hash: 5921b76860e0772b4970ee37ebdf397a6054a1e1 */

ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, script_file, IS_STRING, 0)
Expand All @@ -21,3 +21,30 @@ ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getTsrmInfo, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_setName, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
ZEND_END_ARG_INFO()

#if defined(HAVE_CPU_AFFINITY)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_setAffinity, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, cpu_settings, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#endif

#if defined(HAVE_CPU_AFFINITY)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getAffinity, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#endif

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_setPriority, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, priority, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, policy, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()

#define arginfo_class_Swoole_Thread_getPriority arginfo_class_Swoole_Thread_getTsrmInfo

#if defined(__linux__)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_gettid, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO()
#endif
54 changes: 43 additions & 11 deletions ext-src/swoole_process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ static PHP_METHOD(swoole_process, wait);
static PHP_METHOD(swoole_process, daemon);
#ifdef HAVE_CPU_AFFINITY
static PHP_METHOD(swoole_process, setAffinity);
static PHP_METHOD(swoole_process, getAffinity);
#endif
static PHP_METHOD(swoole_process, set);
static PHP_METHOD(swoole_process, setTimeout);
Expand Down Expand Up @@ -142,6 +143,7 @@ static const zend_function_entry swoole_process_methods[] =
PHP_ME(swoole_process, daemon, arginfo_class_Swoole_Process_daemon, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#ifdef HAVE_CPU_AFFINITY
PHP_ME(swoole_process, setAffinity, arginfo_class_Swoole_Process_setAffinity, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(swoole_process, getAffinity, arginfo_class_Swoole_Process_getAffinity, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#endif
PHP_ME(swoole_process, setPriority, arginfo_class_Swoole_Process_setPriority, ZEND_ACC_PUBLIC)
PHP_ME(swoole_process, getPriority, arginfo_class_Swoole_Process_getPriority, ZEND_ACC_PUBLIC)
Expand Down Expand Up @@ -946,37 +948,67 @@ static PHP_METHOD(swoole_process, daemon) {
}

#ifdef HAVE_CPU_AFFINITY
static PHP_METHOD(swoole_process, setAffinity) {
zval *array;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
bool php_swoole_array_to_cpu_set(zval *array, cpu_set_t *cpu_set) {
if (php_swoole_array_length(array) == 0) {
RETURN_FALSE;
return false;
}

if (php_swoole_array_length(array) > SW_CPU_NUM) {
php_swoole_fatal_error(E_WARNING, "More than the number of CPU");
RETURN_FALSE;
return false;
}

zval *value = nullptr;
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
CPU_ZERO(cpu_set);

SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(array), value)
if (zval_get_long(value) >= SW_CPU_NUM) {
php_swoole_fatal_error(E_WARNING, "invalid cpu id [%d]", (int) Z_LVAL_P(value));
RETURN_FALSE;
return false;
}
CPU_SET(Z_LVAL_P(value), &cpu_set);
CPU_SET(Z_LVAL_P(value), cpu_set);
SW_HASHTABLE_FOREACH_END();

return true;
}

void php_swoole_cpu_set_to_array(zval *array, cpu_set_t *cpu_set) {
array_init(array);

int cpu_n = SW_CPU_NUM;
SW_LOOP_N(cpu_n) {
if (CPU_ISSET(i, cpu_set)) {
add_next_index_long(array, i);
}
}
}

static PHP_METHOD(swoole_process, setAffinity) {
zval *array;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY(array)
ZEND_PARSE_PARAMETERS_END();

cpu_set_t cpu_set;
if (!php_swoole_array_to_cpu_set(array, &cpu_set)) {
RETURN_FALSE;
}

if (swoole_set_cpu_affinity(&cpu_set) < 0) {
php_swoole_sys_error(E_WARNING, "sched_setaffinity() failed");
RETURN_FALSE;
}
RETURN_TRUE;
}

static PHP_METHOD(swoole_process, getAffinity) {
cpu_set_t cpu_set;
if (swoole_get_cpu_affinity(&cpu_set) < 0) {
php_swoole_sys_error(E_WARNING, "sched_getaffinity() failed");
RETURN_FALSE;
}
php_swoole_cpu_set_to_array(return_value, &cpu_set);
}
#endif

static PHP_METHOD(swoole_process, exit) {
Expand Down
111 changes: 111 additions & 0 deletions ext-src/swoole_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ static PHP_METHOD(swoole_thread, detach);
static PHP_METHOD(swoole_thread, getArguments);
static PHP_METHOD(swoole_thread, getId);
static PHP_METHOD(swoole_thread, getTsrmInfo);
static PHP_METHOD(swoole_thread, setName);
#ifdef HAVE_CPU_AFFINITY
static PHP_METHOD(swoole_thread, setAffinity);
static PHP_METHOD(swoole_thread, getAffinity);
#endif
static PHP_METHOD(swoole_thread, setPriority);
static PHP_METHOD(swoole_thread, getPriority);
#ifdef __linux__
static PHP_METHOD(swoole_thread, gettid);
#endif
SW_EXTERN_C_END

// clang-format off
Expand All @@ -104,6 +114,16 @@ static const zend_function_entry swoole_thread_methods[] = {
PHP_ME(swoole_thread, getArguments, arginfo_class_Swoole_Thread_getArguments, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(swoole_thread, getId, arginfo_class_Swoole_Thread_getId, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(swoole_thread, getTsrmInfo, arginfo_class_Swoole_Thread_getTsrmInfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(swoole_thread, setName, arginfo_class_Swoole_Thread_setName, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#ifdef HAVE_CPU_AFFINITY
PHP_ME(swoole_thread, setAffinity, arginfo_class_Swoole_Thread_setAffinity, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(swoole_thread, getAffinity, arginfo_class_Swoole_Thread_getAffinity, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#endif
PHP_ME(swoole_thread, setPriority, arginfo_class_Swoole_Thread_setPriority, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(swoole_thread, getPriority, arginfo_class_Swoole_Thread_getPriority, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#ifdef __linux__
PHP_ME(swoole_thread, gettid, arginfo_class_Swoole_Thread_gettid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#endif
PHP_MALIAS(swoole_thread, info, getTsrmInfo, arginfo_class_Swoole_Thread_getTsrmInfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_FE_END
};
Expand All @@ -121,6 +141,14 @@ void php_swoole_thread_minit(int module_number) {
swoole_thread_ce, ZEND_STRL("HARDWARE_CONCURRENCY"), std::thread::hardware_concurrency());
zend_declare_class_constant_string(swoole_thread_ce, ZEND_STRL("API_NAME"), tsrm_api_name());

zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_OTHER"), SCHED_OTHER);
zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_FIFO"), SCHED_FIFO);
zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_RR"), SCHED_RR);
zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_BATCH"), SCHED_BATCH);
zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_ISO"), SCHED_ISO);
zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_IDLE"), SCHED_IDLE);
zend_declare_class_constant_long(swoole_thread_ce, ZEND_STRL("SCHED_DEADLINE"), SCHED_DEADLINE);

SW_INIT_CLASS_ENTRY_DATA_OBJECT(swoole_thread_error, "Swoole\\Thread\\Error");
zend_declare_property_long(swoole_thread_error_ce, ZEND_STRL("code"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
}
Expand Down Expand Up @@ -200,6 +228,89 @@ static PHP_METHOD(swoole_thread, getId) {
RETURN_LONG((zend_long) pthread_self());
}

static PHP_METHOD(swoole_thread, setName) {
char *name;
size_t l_name;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(name, l_name)
ZEND_PARSE_PARAMETERS_END();

RETURN_BOOL(pthread_setname_np(pthread_self(), name) == 0);
}

#ifdef HAVE_CPU_AFFINITY
static PHP_METHOD(swoole_thread, setAffinity) {
zval *array;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY(array)
ZEND_PARSE_PARAMETERS_END();

cpu_set_t cpu_set;
if (!php_swoole_array_to_cpu_set(array, &cpu_set)) {
RETURN_FALSE;
}

if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set) < 0) {
php_swoole_error(E_WARNING, "pthread_setaffinity_np() failed");
RETURN_FALSE;
}
RETURN_TRUE;
}

static PHP_METHOD(swoole_thread, getAffinity) {
cpu_set_t cpu_set;
if (pthread_getaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set) < 0) {
php_swoole_error(E_WARNING, "pthread_getaffinity_np() failed");
RETURN_FALSE;
}
php_swoole_cpu_set_to_array(return_value, &cpu_set);
}
#endif

static PHP_METHOD(swoole_thread, setPriority) {
zend_long priority, policy = -1;
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_LONG(priority)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(policy)
ZEND_PARSE_PARAMETERS_END();

struct sched_param param;
if (policy == -1) {
pthread_setschedparam(pthread_self(), policy, &param);
}

param.sched_priority = priority;
int retval = pthread_setschedparam(pthread_self(), policy, &param);
if (retval == 0) {
RETURN_TRUE;
} else {
php_swoole_sys_error(E_WARNING, "pthread_setschedparam() failed");
RETURN_FALSE;
}
}

static PHP_METHOD(swoole_thread, getPriority) {
struct sched_param param;
int policy;
if (pthread_getschedparam(pthread_self(), &policy, &param) != 0) {
php_swoole_error(E_WARNING, "pthread_getschedparam() failed");
RETURN_FALSE;
}

array_init(return_value);
add_assoc_long_ex(return_value, ZEND_STRL("policy"), policy);
add_assoc_long_ex(return_value, ZEND_STRL("priority"), param.sched_priority);
}

#ifdef __linux__
static PHP_METHOD(swoole_thread, gettid) {
RETURN_LONG(syscall(SYS_gettid));
}
#endif

zend_string *php_swoole_serialize(zval *zdata) {
php_serialize_data_t var_hash;
smart_str serialized_data = {0};
Expand Down
1 change: 1 addition & 0 deletions include/swoole.h
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ int swoole_tmpfile(char *filename);
typedef cpuset_t cpu_set_t;
#endif
int swoole_set_cpu_affinity(cpu_set_t *set);
int swoole_get_cpu_affinity(cpu_set_t *set);
#endif

#if defined(_POSIX_TIMERS) && ((_POSIX_TIMERS > 0) || defined(__OpenBSD__)) && defined(_POSIX_MONOTONIC_CLOCK) && \
Expand Down
8 changes: 8 additions & 0 deletions src/os/base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ int swoole_set_cpu_affinity(cpu_set_t *set) {
return sched_setaffinity(getpid(), sizeof(*set), set);
#endif
}

int swoole_get_cpu_affinity(cpu_set_t *set) {
#ifdef __FreeBSD__
return cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(*set), set);
#else
return sched_getaffinity(getpid(), sizeof(*set), set);
#endif
}
#endif

namespace swoole {
Expand Down
5 changes: 5 additions & 0 deletions tests/include/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -860,3 +860,8 @@ function build_ftp_url(string $path = ''): string
{
return 'ftp://' . FTP_USER . ':' . FTP_PASS . '@' . FTP_HOST . ':' . FTP_PORT . '/' . $path;
}

function get_thread_name(): string
{
return trim(file_get_contents('/proc/' . posix_getpid() . '/task/' . \Swoole\Thread::gettid() . '/comm'));
}
10 changes: 10 additions & 0 deletions tests/include/skipif.inc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ function skip_if_nts()
skip('not support in nts', !defined('SWOOLE_THREAD'));
}

function skip_if_not_linux()
{
skip('only support linux', PHP_OS !== 'Linux');
}

function skip_if_musl_libc()
{
skip('not support when use musl libc', !empty(`ldd 2>&1 | grep -i musl`));
Expand Down Expand Up @@ -280,3 +285,8 @@ function skip_if_no_ftp()
require_once __DIR__ . '/config.php';
skip('no available proxy', !check_tcp_port(FTP_HOST, FTP_PORT));
}

function skip_if_not_root()
{
skip('not root user', posix_geteuid() !== 0);
}
Loading

0 comments on commit 1d24c27

Please sign in to comment.