diff --git a/win32/devdoc/job_object_helper.md b/win32/devdoc/job_object_helper.md index 4ff19d3..96dfe70 100644 --- a/win32/devdoc/job_object_helper.md +++ b/win32/devdoc/job_object_helper.md @@ -1,44 +1,79 @@ -# job_object_help requirements +# job_object_helper requirements -`job_object_help` is a module that wraps the Windows JobObject API, primarily for the purpose of limiting the amount of memory and CPU the current process can consume. +`job_object_helper` is a module that wraps the Windows JobObject API, primarily for the purpose of limiting the amount of memory and CPU the current process can consume. ## Exposed API ```c - MOCKABLE_FUNCTION(, int, job_object_helper_limit_resources, uint32_t, percent_physical_memory, uint32_t, percent_cpu); +MOCKABLE_FUNCTION(, THANDLE(JOB_OBJECT_HELPER), job_object_helper_create); +MOCKABLE_FUNCTION(, int, job_object_helper_limit_memory, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_physical_memory); +MOCKABLE_FUNCTION(, int, job_object_helper_limit_cpu, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_cpu); ``` -## job_object_helper_limit_resources +## job_object_helper_create ```c - MOCKABLE_FUNCTION(, int, job_object_helper_limit_resources, uint32_t, percent_physical_memory, uint32_t, percent_cpu); +MOCKABLE_FUNCTION(, THANDLE(JOB_OBJECT_HELPER), job_object_helper_create); ``` +``job_object_helper_create`` is used to create a `JOB_OBJECT_HELPER` object. -`job_object_helper_limit_resources` is an API that uses the job object API to limit the amount of physical memory and CPU that the current process can consume. +**SRS_JOB_OBJECT_HELPER_18_016: [** `job_object_helper_create` shall allocate a `JOB_OBJECT_HELPER` object. **]** -**SRS_JOB_OBJECT_HELPER_18_001: [** If `percent_physical_memory` is `0`, `job_object_helper_limit_resources` shall fail and return a non-zero value. **]** +**SRS_JOB_OBJECT_HELPER_18_023: [** `job_object_helper_create` shall call `GlobalMemoryStatusEx` to get the total amount of physical memory in kb. **]** -**SRS_JOB_OBJECT_HELPER_18_002: [** If `percent_cpu` is `0`, `job_object_helper_limit_resources` shall fail and return a non-zero value. **]** +**SRS_JOB_OBJECT_HELPER_18_024: [** `job_object_helper_create` shall call `CreateJobObject` to create a new job object passing `NULL` for both `lpJobAttributes` and `lpName`. **]** -**SRS_JOB_OBJECT_HELPER_18_004: [** If `percent_physical_memory` is greater than `100`, `job_object_helper_limit_resources` shall fail and return a non-zero value. **]** +**SRS_JOB_OBJECT_HELPER_18_025: [** `job_object_helper_create` shall call `GetCurrentProcess` to get the current process handle. **]** -**SRS_JOB_OBJECT_HELPER_18_005: [** If `percent_cpu` is greater than `100`, `job_object_helper_limit_resources` shall fail and return a non-zero value. **]** +**SRS_JOB_OBJECT_HELPER_18_026: [** `job_object_helper_create` shall call `AssignProcessToJobObject` to assign the current process to the new job object. **]** -**SRS_JOB_OBJECT_HELPER_18_006: [** `job_object_helper_limit_resources` shall call `CreateJobObject` to create a new job object passing `NULL` for both `lpJobAttributes` and `lpName`. **]** +**SRS_JOB_OBJECT_HELPER_18_027: [** `job_object_helper_create` shall call `CloseHandle` to close the handle of the current process. **]** -**SRS_JOB_OBJECT_HELPER_18_007: [** `job_object_helper_limit_resources` shall call `GetCurrentProcess` to get the current process handle. **]** +**SRS_JOB_OBJECT_HELPER_18_018: [** If there are any failures, `job_object_helper_create` shall fail and return `NULL`. **]** -**SRS_JOB_OBJECT_HELPER_18_008: [** `job_object_helper_limit_resources` shall call `AssignProcessToJobObject` to assign the current process to the new job object. **]** +**SRS_JOB_OBJECT_HELPER_18_019: [** `job_object_helper_create` shall succeed and return the `JOB_OBJECT_HELPER` object. **]** -**SRS_JOB_OBJECT_HELPER_18_009: [** `job_object_helper_limit_resources` shall call `GlobalMemoryStatusEx` to get the total amount of physical memory in kb. **]** -**SRS_JOB_OBJECT_HELPER_18_010: [** `job_object_helper_limit_resources` shall call `SetInformationJobObject`, passing `JobObjectExtendedLimitInformation` and a `JOBOBJECT_EXTENDED_LIMIT_INFORMATION` object with `JOB_OBJECT_LIMIT_JOB_MEMORY` set and `JobMemoryLimit` set to the `percent_physical_memory` percent of the physical memory in bytes. **]** +## job_object_helper_dispose +```c +static void job_object_helper_dispose(JOB_OBJECT_HELPER* job_object_helper); +``` +`job_object_helper_dispose` frees all of the resources used by the `JOB_OBJECT_HELPER` object. -**SRS_JOB_OBJECT_HELPER_18_011: [** `job_object_helper_limit_resources` shall call `SetInformationJobObject` passing `JobObjectCpuRateControlInformation` and a `JOBOBJECT_CPU_RATE_CONTROL_INFORMATION` object with `JOB_OBJECT_CPU_RATE_CONTROL_ENABLE` and `JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP` set, and `CpuRate` set to `percent_cpu` times `100`. **]** +**SRS_JOB_OBJECT_HELPER_18_033: [** `job_object_helper_dispose` shall call `CloseHandle` to close the handle to the job object. **]** -**SRS_JOB_OBJECT_HELPER_18_012: [** `job_object_helper_limit_resources` shall call `CloseHandle` to close the handle of the current process. **]** -**SRS_JOB_OBJECT_HELPER_18_013: [** `job_object_helper_limit_resources` shall call `CloseHandle` to close the handle to the job object. **]** +## job_object_helper_limit_memory +```c +MOCKABLE_FUNCTION(, int, job_object_helper_limit_memory, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_physical_memory); +``` +`job_object_helper_limit_memory` limits the amount of physical memory available to the current progess. -**SRS_JOB_OBJECT_HELPER_18_014: [** `job_object_helper_limit_resources` shall succeed and return `0`. **]** +**SRS_JOB_OBJECT_HELPER_18_035: [** If `job_object_helper` is `NULL`, `job_object_helper_limit_memory` shall fail and return a non-zero value. **]** -**SRS_JOB_OBJECT_HELPER_18_015: [** If there are any failures, `job_object_helper_limit_resources` shall fail and return a non-zero value. **]** +**SRS_JOB_OBJECT_HELPER_18_036: [** If `percent_physical_memory` is `0`, `job_object_helper_limit_memory` shall fail and return a non-zero value. **]** +**SRS_JOB_OBJECT_HELPER_18_037: [** If `percent_physical_memory` is greater than `100`, `job_object_helper_limit_memory` shall fail and return a non-zero value. **]** + +*SRS_JOB_OBJECT_HELPER_18_039: [** `job_object_helper_limit_memory` shall call `SetInformationJobObject`, passing `JobObjectExtendedLimitInformation` and a `JOBOBJECT_EXTENDED_LIMIT_INFORMATION` object with `JOB_OBJECT_LIMIT_JOB_MEMORY` set and `JobMemoryLimit` set to the `percent_physical_memory` percent of the physical memory in bytes. **]** + +**SRS_JOB_OBJECT_HELPER_18_041: [** If there are any failures, `job_object_helper_limit_memory` shall fail and return a non-zero value. **]** + +**SRS_JOB_OBJECT_HELPER_18_042: [** `job_object_helper_limit_memory` shall succeed and return `0`. **]** + + +## job_object_helper_limit_cpu +```c +MOCKABLE_FUNCTION(, int, job_object_helper_limit_cpu, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_cpu); +``` +`job_object_helper_limit_cpu` limits the amount of CPU available to the current process. + +**SRS_JOB_OBJECT_HELPER_18_043: [** If `job_object_helper` is `NULL`, `job_object_helper_limit_cpu` shall fail and return a non-zero value. **]** + +**SRS_JOB_OBJECT_HELPER_18_044: [** If `percent_cpu` is `0`, `job_object_helper_limit_cpu` shall fail and return a non-zero value. **]** + +**SRS_JOB_OBJECT_HELPER_18_045: [** If `percent_cpu` is greater than `100`, `job_object_helper_limit_cpu` shall fail and return a non-zero value. **]** + +**SRS_JOB_OBJECT_HELPER_18_047: [** `job_object_helper_limit_cpu` shall call `SetInformationJobObject` passing `JobObjectCpuRateControlInformation` and a `JOBOBJECT_CPU_RATE_CONTROL_INFORMATION` object with `JOB_OBJECT_CPU_RATE_CONTROL_ENABLE` and `JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP` set, and `CpuRate` set to `percent_cpu` times `100`. **]** + +**SRS_JOB_OBJECT_HELPER_18_049: [** If there are any failures, `job_object_helper_limit_cpu` shall fail and return a non-zero value. **]** + +**SRS_JOB_OBJECT_HELPER_18_050: [** `job_object_helper_limit_cpu` shall succeed and return `0`. **]** diff --git a/win32/inc/c_pal/job_object_helper.h b/win32/inc/c_pal/job_object_helper.h index 7ccca31..c7921ba 100644 --- a/win32/inc/c_pal/job_object_helper.h +++ b/win32/inc/c_pal/job_object_helper.h @@ -13,15 +13,20 @@ #include "macro_utils/macro_utils.h" +#include "c_pal/thandle.h" + +typedef struct JOB_OBJECT_HELPER_TAG JOB_OBJECT_HELPER; +THANDLE_TYPE_DECLARE(JOB_OBJECT_HELPER); + #include "umock_c/umock_c_prod.h" #ifdef __cplusplus extern "C" { #endif - - MOCKABLE_FUNCTION(, int, job_object_helper_limit_resources, uint32_t, percent_physical_memory, uint32_t, percent_cpu); - + MOCKABLE_FUNCTION(, THANDLE(JOB_OBJECT_HELPER), job_object_helper_create); + MOCKABLE_FUNCTION(, int, job_object_helper_limit_memory, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_physical_memory); + MOCKABLE_FUNCTION(, int, job_object_helper_limit_cpu, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_cpu); #ifdef __cplusplus } #endif diff --git a/win32/src/job_object_helper.c b/win32/src/job_object_helper.c index bf50b21..dca09ef 100644 --- a/win32/src/job_object_helper.c +++ b/win32/src/job_object_helper.c @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -#include "stdint.h" +#include #include "macro_utils/macro_utils.h" #include "c_logging/logger.h" @@ -9,9 +9,26 @@ #include "c_pal/job_object_helper.h" -IMPLEMENT_MOCKABLE_FUNCTION(, int, job_object_helper_limit_resources, uint32_t, percent_physical_memory, uint32_t, percent_cpu) +static void job_object_helper_dispose(JOB_OBJECT_HELPER* job_object_helper) { + (void) job_object_helper; +} + +IMPLEMENT_MOCKABLE_FUNCTION(, THANDLE(JOB_OBJECT_HELPER), job_object_helper_create) +{ + return NULL; +} + +IMPLEMENT_MOCKABLE_FUNCTION(, int, job_object_helper_limit_memory, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_physical_memory) +{ + (void) job_object_helper; (void) percent_physical_memory; + return MU_FAILURE; +} + +IMPLEMENT_MOCKABLE_FUNCTION(, int, job_object_helper_limit_cpu, THANDLE(JOB_OBJECT_HELPER), job_object_helper, uint32_t, percent_cpu) +{ + (void) job_object_helper; (void) percent_cpu; return MU_FAILURE; -} \ No newline at end of file +}