diff options
-rw-r--r-- | RELEASES.md | 4 | ||||
-rw-r--r-- | inc/powercap.h | 27 | ||||
-rw-r--r-- | src/powercap.c | 107 |
3 files changed, 138 insertions, 0 deletions
diff --git a/RELEASES.md b/RELEASES.md index ee6443a..4e923bf 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -14,6 +14,10 @@ * 'powercap_control_type_file_get_path' * 'powercap_zone_file_get_path' * 'powercap_constraint_file_get_path' +* Functions to support opening files powercap.h: + * 'powercap_control_type_file_open' + * 'powercap_zone_file_open' + * 'powercap_constraint_file_open' ### Changed diff --git a/inc/powercap.h b/inc/powercap.h index 814b296..9e4c0ec 100644 --- a/inc/powercap.h +++ b/inc/powercap.h @@ -121,6 +121,7 @@ int powercap_constraint_file_get_name(powercap_constraint_file type, uint32_t co * Returns a negative value in case of other error. */ int powercap_get_path(const char* control_type_name, const uint32_t* zones, uint32_t depth, char* buf, size_t size); + /** * Get the full path to a control type file. * Return is like snprintf, except if the output was truncated due to the size limit, the return value is still > size, @@ -130,6 +131,7 @@ int powercap_get_path(const char* control_type_name, const uint32_t* zones, uint */ int powercap_control_type_file_get_path(powercap_control_type_file type, const char* control_type_name, char* buf, size_t size); + /** * Get the full path to a zone file. * Return is like snprintf, except if the output was truncated due to the size limit, the return value is still > size, @@ -152,6 +154,31 @@ int powercap_constraint_file_get_path(powercap_constraint_file type, const char* size_t size); /** + * Open a control type file. + * Returns the file descriptor from the open function and assigns it to the powercap_control_type (if not NULL). + * Also returns a negative value in case of other errors, like bad parameters. + */ +int powercap_control_type_file_open(powercap_control_type* control, powercap_control_type_file type, + const char* control_type_name, int flags); + +/** + * Open a zone file. + * Returns the file descriptor from the open function and assigns it to the powercap_zone (if not NULL). + * Also returns a negative value in case of other errors, like bad parameters. + */ +int powercap_zone_file_open(powercap_zone* zone, powercap_zone_file type, const char* control_type_name, + const uint32_t* zones, uint32_t depth, int flags); + +/** + * Open a constraint file. + * Returns the file descriptor from the open function and assigns it to the powercap_constraint (if not NULL). + * Also returns a negative value in case of other errors, like bad parameters. + */ +int powercap_constraint_file_open(powercap_constraint* constraint, powercap_constraint_file type, + const char* control_type_name, const uint32_t* zones, uint32_t depth, + uint32_t constraint_num, int flags); + +/** * Set the control type's enabled value. */ int powercap_control_type_set_enabled(const powercap_control_type* control, int val); diff --git a/src/powercap.c b/src/powercap.c index f1847c3..35ce60e 100644 --- a/src/powercap.c +++ b/src/powercap.c @@ -81,6 +81,113 @@ int powercap_constraint_file_get_path(powercap_constraint_file type, const char* return snprintf_constraint_file_path(buf, size, control_type_name, zones, depth, constraint, type); } +int powercap_control_type_file_open(powercap_control_type* control, powercap_control_type_file type, + const char* control_type_name, int flags) { + char buf[PATH_MAX]; + int fd; + /* check type in case users pass bad int value instead of enum; int cast silences clang compiler */ + if (!is_valid_control_type(control_type_name) || (int) type < 0 || (int) type > POWERCAP_CONTROL_TYPE_FILE_ENABLED) { + errno = EINVAL; + return -errno; + } + fd = open_control_type_file(buf, sizeof(buf), control_type_name, type, flags); + if (control) { + switch (type) { + case POWERCAP_CONTROL_TYPE_FILE_ENABLED: + control->enabled = fd;; + break; + default: + // unreachable + errno = EINVAL; + return -errno; + } + } + return fd; +} + +int powercap_zone_file_open(powercap_zone* zone, powercap_zone_file type, const char* control_type_name, + const uint32_t* zones, uint32_t depth, int flags) { + char buf[PATH_MAX]; + int fd; + /* check type in case users pass bad int value instead of enum; int cast silences clang compiler */ + if (!is_valid_control_type(control_type_name) || (int) type < 0 || (int) type > POWERCAP_ZONE_FILE_NAME || + (depth && !zones)) { + errno = EINVAL; + return -errno; + } + fd = open_zone_file(buf, sizeof(buf), control_type_name, zones, depth, type, flags); + if (zone) { + switch (type) { + case POWERCAP_ZONE_FILE_MAX_ENERGY_RANGE_UJ: + zone->max_energy_range_uj = fd; + break; + case POWERCAP_ZONE_FILE_ENERGY_UJ: + zone->energy_uj = fd; + break; + case POWERCAP_ZONE_FILE_MAX_POWER_RANGE_UW: + zone->max_power_range_uw = fd; + break; + case POWERCAP_ZONE_FILE_POWER_UW: + zone->power_uw = fd; + break; + case POWERCAP_ZONE_FILE_ENABLED: + zone->enabled = fd; + break; + case POWERCAP_ZONE_FILE_NAME: + zone->name = fd; + break; + default: + // unreachable + errno = EINVAL; + return -errno; + } + } + return fd; +} + +int powercap_constraint_file_open(powercap_constraint* constraint, powercap_constraint_file type, + const char* control_type_name, const uint32_t* zones, uint32_t depth, + uint32_t constraint_num, int flags) { + char buf[PATH_MAX]; + int fd; + if (!constraint || !is_valid_control_type(control_type_name) || + (int) type < 0 || (int) type > POWERCAP_CONSTRAINT_FILE_NAME || (depth && !zones)) { + errno = EINVAL; + return -errno; + } + fd = open_constraint_file(buf, sizeof(buf), control_type_name, zones, depth, constraint_num, type, flags); + if (constraint) { + switch (type) { + case POWERCAP_CONSTRAINT_FILE_POWER_LIMIT_UW: + constraint->power_limit_uw = fd; + break; + case POWERCAP_CONSTRAINT_FILE_TIME_WINDOW_US: + constraint->time_window_us = fd; + break; + case POWERCAP_CONSTRAINT_FILE_MAX_POWER_UW: + constraint->max_power_uw = fd; + break; + case POWERCAP_CONSTRAINT_FILE_MIN_POWER_UW: + constraint->min_power_uw = fd; + break; + case POWERCAP_CONSTRAINT_FILE_MAX_TIME_WINDOW_US: + constraint->max_time_window_us = fd; + break; + case POWERCAP_CONSTRAINT_FILE_MIN_TIME_WINDOW_US: + constraint->min_time_window_us = fd; + break; + case POWERCAP_CONSTRAINT_FILE_NAME: + constraint->name = fd; + break; + default: + // unreachable + errno = EINVAL; + return -errno; + } + } + return fd; +} + #define VERIFY_ARG(arg) \ if (!(arg)) { \ errno = EINVAL; \ |