-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ext/pcntl: pcntl_getqos_class/pcntl_setqos_class addition. #13945
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a256774
to
bdab6c1
Compare
ext/pcntl/pcntl.c
Outdated
RETURN_THROWS(); | ||
} | ||
|
||
RETURN_TRUE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just return NULL/void?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to give a success status at least ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really that useful if the function can only ever return true
? I know a lot of other functions in pcntl only return true
nowadays, but that's because they used to return false
for ZPP failures or cases that have been promoted to Errors.
ext/pcntl/pcntl.c
Outdated
if (UNEXPECTED(pthread_get_qos_class_np(pthread_self(), &qos_class, NULL) != 0)) | ||
{ | ||
// unlikely unless an external tool set the QOS class with a wrong value | ||
PCNTL_G(last_error) = errno; | ||
zend_value_error("invalid QOS class %u", qos_class); | ||
RETURN_THROWS(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can this happen? Also this doesn't look like a ValueError as no user input is taken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true
ext/pcntl/pcntl.c
Outdated
if (pthread_set_qos_class_self_np((qos_class_t)qos_class, 0) != 0) | ||
{ | ||
PCNTL_G(last_error) = errno; | ||
zend_argument_value_error(1, "must be between QOS_CLASS_USER_INTERACTIVE and QOS_CLASS_BLACKGROUND"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that flag a bitmask? Or just individual settings, in the latter case I'd list them all rather than making the user guess the "underlying" int value of the constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
individual. also the list had not been updated since a long time (and no reason to do so anyway) so yes .. I ll update.
bdab6c1
to
1ec8a4a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last wording nit, but looks good to me otherwise :)
ext/pcntl/pcntl.c
Outdated
if (pthread_set_qos_class_self_np((qos_class_t)qos_class, 0) != 0) | ||
{ | ||
PCNTL_G(last_error) = errno; | ||
zend_argument_value_error(1, "must be between QOS_CLASS_USER_INTERACTIVE, QOS_CLASS_USER_INITIATED, QOS_CLASS_DEFAULT, QOS_CLASS_UTILITY and QOS_CLASS_BACKGROUND"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zend_argument_value_error(1, "must be between QOS_CLASS_USER_INTERACTIVE, QOS_CLASS_USER_INITIATED, QOS_CLASS_DEFAULT, QOS_CLASS_UTILITY and QOS_CLASS_BACKGROUND"); | |
zend_argument_value_error(1, "must be one of QOS_CLASS_USER_INTERACTIVE, QOS_CLASS_USER_INITIATED, QOS_CLASS_DEFAULT, QOS_CLASS_UTILITY, or QOS_CLASS_BACKGROUND"); |
1ec8a4a
to
376bdd9
Compare
I'm gonna be "that guy", and ask: should we start introducing enums instead of constants for new functions? I see a bunch of QOS constants being added here, but using enums instead would provide better type safety, and an improved DX because the function "documents itself" (i.e. the IDE and SA tools can help you better). |
Actually, that's a good point :D |
You want something like enum QosClass {
case UserInitiated;
} like zig like to do ? |
Indeed something like that.
That could be PHP9 material. |
Ok I ll it a go a bit later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this API much better, some remarks.
ext/pcntl/pcntl.c
Outdated
@@ -53,6 +53,7 @@ typedef cpuset_t cpu_set_t; | |||
|
|||
#if defined(HAVE_PTHREAD_SET_QOS_CLASS_SELF_NP) | |||
#include <pthread/qos.h> | |||
PHPAPI zend_class_entry *QosClass_ce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this exposed via PHPAPI? Do we expect other extensions to reuse this enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think no :)
ext/pcntl/pcntl.c
Outdated
if (pthread_set_qos_class_self_np((qos_class_t)qos_class, 0) != 0) | ||
{ | ||
PCNTL_G(last_error) = errno; | ||
zend_argument_value_error(1, "must be one of QOS_CLASS_USER_INTERACTIVE, QOS_CLASS_USER_INITIATED, QOS_CLASS_DEFAULT, QOS_CLASS_UTILITY and QOS_CLASS_BACKGROUND"); | ||
zend_argument_value_error(1, "must be one of QosClass enum entries : ::UserInteractive, ::UserInitiated, ::Default, ::Utility and ::Background"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zend_argument_value_error(1, "must be one of QosClass enum entries : ::UserInteractive, ::UserInitiated, ::Default, ::Utility and ::Background"); | |
zend_argument_value_error(1, "must be one of QosClass enum entries : ::UserInteractive, ::UserInitiated, ::Default, ::Utility or ::Background"); |
ext/pcntl/php_pcntl.h
Outdated
@@ -58,4 +58,6 @@ ZEND_TSRMLS_CACHE_EXTERN() | |||
ZEND_EXTERN_MODULE_GLOBALS(pcntl) | |||
#define PCNTL_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(pcntl, v) | |||
|
|||
extern PHPAPI zend_class_entry *QosClass_ce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
ext/pcntl/pcntl.c
Outdated
RETURN_THROWS(); | ||
} | ||
|
||
ZVAL_COPY_OR_DUP(return_value, zend_enum_fetch_case_value(qos_obj)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zend_enum_fetch_case_value
returns the backed value, but you want the object instead.
Introducting macOs Quality Of Service through those two calls. on macOs arm64/M*, there is no concept of individual cores, thus the old thread policy for cpu affinity does not work here. Instead, the user can apply to the current process the level of performance/energy consumption they wish from the highest QOS_CLASS_USER_INTERACTIVE to QOS_CLASS_BACKGROUND.
85df17c
to
8078a9b
Compare
ext/pcntl/pcntl.stub.php
Outdated
enum QosClass: int | ||
{ | ||
case UserInteractive = 0x21; | ||
case UserInitiated = 0x19; | ||
case Default = 0x15; | ||
case Utility = 0x11; | ||
case Background = 0x09; | ||
case Unspecified = 0x00; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it should be a backed enum, exposing those values to userland is not really helpful IMHO. Also what is this Unspecified case about?
ext/pcntl/pcntl.c
Outdated
PCNTL_G(last_error) = errno; | ||
zend_argument_value_error(1, "must be one of QosClass enum entries : ::UserInteractive, ::UserInitiated, ::Default, ::Utility or ::Background"); | ||
RETURN_THROWS(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should never happen if we are requiring an enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me
ext/pcntl/pcntl.c
Outdated
qos_class_t qos_class = QOS_CLASS_DEFAULT; | ||
zend_string *entry = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(qos_obj))); | ||
|
||
if (zend_string_equals_cstr(entry, "UserInteractive", sizeof("UserInteractive") - 1)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use zend_string_equals_literal for these instead, it's less error-prone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alright
|
||
static zend_object *qos_lval_to_zval(qos_class_t qos_class) | ||
{ | ||
const char *entryname; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If macOS ever introduces more qos types, then the fact this is uninitialized but used below will be UB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite apple has very little incentive to add more level of service, default is handled below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, you are right. I missed the default
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
@@ -1003,3 +1003,17 @@ function pcntl_setcpuaffinity(?int $process_id = null, array $cpu_ids = []): boo | |||
#ifdef HAVE_SCHED_GETCPU | |||
function pcntl_getcpu(): int {} | |||
#endif | |||
|
|||
#ifdef HAVE_PTHREAD_SET_QOS_CLASS_SELF_NP | |||
enum QosClass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be named Pcntl\QosClass
as per https://wiki.php.net/rfc/namespaces_in_bundled_extensions.
Introducting macOs Quality Of Service through those two calls. on macOs arm64/M*, there is no concept of individual cores, thus the old thread policy for cpu affinity does not work here. Instead, the user can apply to the current process the level of
performance/energy consumption they wish from the highest
QOS_CLASS_USER_INTERACTIVE to QOS_CLASS_BACKGROUND.