mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
os: add os.{get,set}Priority()
PR-URL: https://github.com/nodejs/node/pull/22407 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
7 files changed
+343
-2
No files matched your search
@@ -192,6 +192,19 @@ added: v0.3.3
|
||||
The `os.freemem()` method returns the amount of free system memory in bytes as
|
||||
an integer.
|
||||
|
||||
## os.getPriority([pid])
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* `pid` {integer} The process ID to retrieve scheduling priority for.
|
||||
**Default** `0`.
|
||||
* Returns: {integer}
|
||||
|
||||
The `os.getPriority()` method returns the scheduling priority for the process
|
||||
specified by `pid`. If `pid` is not provided, or is `0`, the priority of the
|
||||
current process is returned.
|
||||
|
||||
## os.homedir()
|
||||
<!-- YAML
|
||||
added: v2.3.0
|
||||
@@ -338,6 +351,26 @@ On POSIX systems, the operating system release is determined by calling
|
||||
[uname(3)][]. On Windows, `GetVersionExW()` is used. Please see
|
||||
https://en.wikipedia.org/wiki/Uname#Examples for more information.
|
||||
|
||||
## os.setPriority([pid, ]priority)
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* `pid` {integer} The process ID to set scheduling priority for.
|
||||
**Default** `0`.
|
||||
* `priority` {integer} The scheduling priority to assign to the process.
|
||||
|
||||
The `os.setPriority()` method attempts to set the scheduling priority for the
|
||||
process specified by `pid`. If `pid` is not provided, or is `0`, the priority
|
||||
of the current process is used.
|
||||
|
||||
The `priority` input must be an integer between `-20` (high priority) and `19`
|
||||
(low priority). Due to differences between Unix priority levels and Windows
|
||||
priority classes, `priority` is mapped to one of six priority constants in
|
||||
`os.constants.priority`. When retrieving a process priority level, this range
|
||||
mapping may cause the return value to be slightly different on Windows. To avoid
|
||||
confusion, it is recommended to set `priority` to one of the priority constants.
|
||||
|
||||
## os.tmpdir()
|
||||
<!-- YAML
|
||||
added: v0.9.9
|
||||
@@ -1208,6 +1241,60 @@ information.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Priority Constants
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
The following process scheduling constants are exported by
|
||||
`os.constants.priority`:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Constant</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PRIORITY_LOW</code></td>
|
||||
<td>The lowest process scheduling priority. This corresponds to
|
||||
<code>IDLE_PRIORITY_CLASS</code> on Windows, and a nice value of
|
||||
<code>19</code> on all other platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PRIORITY_BELOW_NORMAL</code></td>
|
||||
<td>The process scheduling priority above <code>PRIORITY_LOW</code> and
|
||||
below <code>PRIORITY_NORMAL</code>. This corresponds to
|
||||
<code>BELOW_NORMAL_PRIORITY_CLASS</code> on Windows, and a nice value of
|
||||
<code>10</code> on all other platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PRIORITY_NORMAL</code></td>
|
||||
<td>The default process scheduling priority. This corresponds to
|
||||
<code>NORMAL_PRIORITY_CLASS</code> on Windows, and a nice value of
|
||||
<code>0</code> on all other platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PRIORITY_ABOVE_NORMAL</code></td>
|
||||
<td>The process scheduling priority above <code>PRIORITY_NORMAL</code> and
|
||||
below <code>PRIORITY_HIGH</code>. This corresponds to
|
||||
<code>ABOVE_NORMAL_PRIORITY_CLASS</code> on Windows, and a nice value of
|
||||
<code>-7</code> on all other platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PRIORITY_HIGH</code></td>
|
||||
<td>The process scheduling priority above <code>PRIORITY_ABOVE_NORMAL</code>
|
||||
and below <code>PRIORITY_HIGHEST</code>. This corresponds to
|
||||
<code>HIGH_PRIORITY_CLASS</code> on Windows, and a nice value of
|
||||
<code>-14</code> on all other platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PRIORITY_HIGHEST</code></td>
|
||||
<td>The highest process scheduling priority. This corresponds to
|
||||
<code>REALTIME_PRIORITY_CLASS</code> on Windows, and a nice value of
|
||||
<code>-20</code> on all other platforms.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### libuv Constants
|
||||
|
||||
<table>
|
||||
|
||||
@@ -29,6 +29,7 @@ const constants = process.binding('constants');
|
||||
Object.assign(exports,
|
||||
constants.os.dlopen,
|
||||
constants.os.errno,
|
||||
constants.os.priority,
|
||||
constants.os.signals,
|
||||
constants.fs,
|
||||
constants.crypto);
|
||||
|
||||
@@ -27,6 +27,7 @@ const { deprecate } = require('internal/util');
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
const { codes: { ERR_SYSTEM_ERROR } } = require('internal/errors');
|
||||
const { validateInt32 } = require('internal/validators');
|
||||
|
||||
const {
|
||||
getCPUs,
|
||||
@@ -37,10 +38,12 @@ const {
|
||||
getLoadAvg,
|
||||
getOSRelease: _getOSRelease,
|
||||
getOSType: _getOSType,
|
||||
getPriority: _getPriority,
|
||||
getTotalMem,
|
||||
getUserInfo: _getUserInfo,
|
||||
getUptime,
|
||||
isBigEndian
|
||||
isBigEndian,
|
||||
setPriority: _setPriority
|
||||
} = process.binding('os');
|
||||
|
||||
function getCheckedFunction(fn) {
|
||||
@@ -206,17 +209,49 @@ function networkInterfaces() {
|
||||
return interfaceAddresses;
|
||||
}
|
||||
|
||||
function setPriority(pid, priority) {
|
||||
if (priority === undefined) {
|
||||
priority = pid;
|
||||
pid = 0;
|
||||
}
|
||||
|
||||
validateInt32(pid, 'pid');
|
||||
validateInt32(priority, 'priority', -20, 19);
|
||||
|
||||
const ctx = {};
|
||||
|
||||
if (_setPriority(pid, priority, ctx) !== 0)
|
||||
throw new ERR_SYSTEM_ERROR(ctx);
|
||||
}
|
||||
|
||||
function getPriority(pid) {
|
||||
if (pid === undefined)
|
||||
pid = 0;
|
||||
else
|
||||
validateInt32(pid, 'pid');
|
||||
|
||||
const ctx = {};
|
||||
const priority = _getPriority(pid, ctx);
|
||||
|
||||
if (priority === undefined)
|
||||
throw new ERR_SYSTEM_ERROR(ctx);
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
arch,
|
||||
cpus,
|
||||
endianness,
|
||||
freemem: getFreeMem,
|
||||
getPriority,
|
||||
homedir: getHomeDirectory,
|
||||
hostname: getHostname,
|
||||
loadavg,
|
||||
networkInterfaces,
|
||||
platform,
|
||||
release: getOSRelease,
|
||||
setPriority,
|
||||
tmpdir,
|
||||
totalmem: getTotalMem,
|
||||
type: getOSType,
|
||||
|
||||
@@ -758,6 +758,44 @@ void DefineSignalConstants(Local<Object> target) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void DefinePriorityConstants(Local<Object> target) {
|
||||
#ifdef UV_PRIORITY_LOW
|
||||
# define PRIORITY_LOW UV_PRIORITY_LOW
|
||||
NODE_DEFINE_CONSTANT(target, PRIORITY_LOW);
|
||||
# undef PRIORITY_LOW
|
||||
#endif
|
||||
|
||||
#ifdef UV_PRIORITY_BELOW_NORMAL
|
||||
# define PRIORITY_BELOW_NORMAL UV_PRIORITY_BELOW_NORMAL
|
||||
NODE_DEFINE_CONSTANT(target, PRIORITY_BELOW_NORMAL);
|
||||
# undef PRIORITY_BELOW_NORMAL
|
||||
#endif
|
||||
|
||||
#ifdef UV_PRIORITY_NORMAL
|
||||
# define PRIORITY_NORMAL UV_PRIORITY_NORMAL
|
||||
NODE_DEFINE_CONSTANT(target, PRIORITY_NORMAL);
|
||||
# undef PRIORITY_NORMAL
|
||||
#endif
|
||||
|
||||
#ifdef UV_PRIORITY_ABOVE_NORMAL
|
||||
# define PRIORITY_ABOVE_NORMAL UV_PRIORITY_ABOVE_NORMAL
|
||||
NODE_DEFINE_CONSTANT(target, PRIORITY_ABOVE_NORMAL);
|
||||
# undef PRIORITY_ABOVE_NORMAL
|
||||
#endif
|
||||
|
||||
#ifdef UV_PRIORITY_HIGH
|
||||
# define PRIORITY_HIGH UV_PRIORITY_HIGH
|
||||
NODE_DEFINE_CONSTANT(target, PRIORITY_HIGH);
|
||||
# undef PRIORITY_HIGH
|
||||
#endif
|
||||
|
||||
#ifdef UV_PRIORITY_HIGHEST
|
||||
# define PRIORITY_HIGHEST UV_PRIORITY_HIGHEST
|
||||
NODE_DEFINE_CONSTANT(target, PRIORITY_HIGHEST);
|
||||
# undef PRIORITY_HIGHEST
|
||||
#endif
|
||||
}
|
||||
|
||||
void DefineOpenSSLConstants(Local<Object> target) {
|
||||
#ifdef OPENSSL_VERSION_NUMBER
|
||||
NODE_DEFINE_CONSTANT(target, OPENSSL_VERSION_NUMBER);
|
||||
@@ -1338,6 +1376,10 @@ void DefineConstants(v8::Isolate* isolate, Local<Object> target) {
|
||||
CHECK(sig_constants->SetPrototype(env->context(),
|
||||
Null(env->isolate())).FromJust());
|
||||
|
||||
Local<Object> priority_constants = Object::New(isolate);
|
||||
CHECK(priority_constants->SetPrototype(env->context(),
|
||||
Null(env->isolate())).FromJust());
|
||||
|
||||
Local<Object> fs_constants = Object::New(isolate);
|
||||
CHECK(fs_constants->SetPrototype(env->context(),
|
||||
Null(env->isolate())).FromJust());
|
||||
@@ -1361,6 +1403,7 @@ void DefineConstants(v8::Isolate* isolate, Local<Object> target) {
|
||||
DefineErrnoConstants(err_constants);
|
||||
DefineWindowsErrorConstants(err_constants);
|
||||
DefineSignalConstants(sig_constants);
|
||||
DefinePriorityConstants(priority_constants);
|
||||
DefineSystemConstants(fs_constants);
|
||||
DefineOpenSSLConstants(crypto_constants);
|
||||
DefineCryptoConstants(crypto_constants);
|
||||
@@ -1374,6 +1417,7 @@ void DefineConstants(v8::Isolate* isolate, Local<Object> target) {
|
||||
os_constants->Set(OneByteString(isolate, "dlopen"), dlopen_constants);
|
||||
os_constants->Set(OneByteString(isolate, "errno"), err_constants);
|
||||
os_constants->Set(OneByteString(isolate, "signals"), sig_constants);
|
||||
os_constants->Set(OneByteString(isolate, "priority"), priority_constants);
|
||||
target->Set(OneByteString(isolate, "os"), os_constants);
|
||||
target->Set(OneByteString(isolate, "fs"), fs_constants);
|
||||
target->Set(OneByteString(isolate, "crypto"), crypto_constants);
|
||||
|
||||
@@ -52,6 +52,7 @@ using v8::Context;
|
||||
using v8::Float64Array;
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::Int32;
|
||||
using v8::Integer;
|
||||
using v8::Local;
|
||||
using v8::MaybeLocal;
|
||||
@@ -405,6 +406,46 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
|
||||
static void SetPriority(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK_EQ(args.Length(), 3);
|
||||
CHECK(args[0]->IsInt32());
|
||||
CHECK(args[1]->IsInt32());
|
||||
|
||||
const int pid = args[0].As<Int32>()->Value();
|
||||
const int priority = args[1].As<Int32>()->Value();
|
||||
const int err = uv_os_setpriority(pid, priority);
|
||||
|
||||
if (err) {
|
||||
CHECK(args[2]->IsObject());
|
||||
env->CollectUVExceptionInfo(args[2], err, "uv_os_setpriority");
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
static void GetPriority(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK_EQ(args.Length(), 2);
|
||||
CHECK(args[0]->IsInt32());
|
||||
|
||||
const int pid = args[0].As<Int32>()->Value();
|
||||
int priority;
|
||||
const int err = uv_os_getpriority(pid, &priority);
|
||||
|
||||
if (err) {
|
||||
CHECK(args[1]->IsObject());
|
||||
env->CollectUVExceptionInfo(args[1], err, "uv_os_getpriority");
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(priority);
|
||||
}
|
||||
|
||||
|
||||
void Initialize(Local<Object> target,
|
||||
Local<Value> unused,
|
||||
Local<Context> context) {
|
||||
@@ -420,6 +461,8 @@ void Initialize(Local<Object> target,
|
||||
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
|
||||
env->SetMethod(target, "getHomeDirectory", GetHomeDirectory);
|
||||
env->SetMethod(target, "getUserInfo", GetUserInfo);
|
||||
env->SetMethod(target, "setPriority", SetPriority);
|
||||
env->SetMethod(target, "getPriority", GetPriority);
|
||||
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
|
||||
Boolean::New(env->isolate(), IsBigEndian()));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ assert.deepStrictEqual(
|
||||
|
||||
assert.deepStrictEqual(
|
||||
Object.keys(constants.os).sort(), ['UV_UDP_REUSEADDR', 'dlopen', 'errno',
|
||||
'signals']
|
||||
'priority', 'signals']
|
||||
);
|
||||
|
||||
// Make sure all the constants objects don't inherit from Object.prototype
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const os = require('os');
|
||||
const {
|
||||
PRIORITY_LOW,
|
||||
PRIORITY_BELOW_NORMAL,
|
||||
PRIORITY_NORMAL,
|
||||
PRIORITY_ABOVE_NORMAL,
|
||||
PRIORITY_HIGH,
|
||||
PRIORITY_HIGHEST
|
||||
} = os.constants.priority;
|
||||
|
||||
// Validate priority constants.
|
||||
assert.strictEqual(typeof PRIORITY_LOW, 'number');
|
||||
assert.strictEqual(typeof PRIORITY_BELOW_NORMAL, 'number');
|
||||
assert.strictEqual(typeof PRIORITY_NORMAL, 'number');
|
||||
assert.strictEqual(typeof PRIORITY_ABOVE_NORMAL, 'number');
|
||||
assert.strictEqual(typeof PRIORITY_HIGH, 'number');
|
||||
assert.strictEqual(typeof PRIORITY_HIGHEST, 'number');
|
||||
|
||||
// Test pid type validation.
|
||||
[null, true, false, 'foo', {}, [], /x/].forEach((pid) => {
|
||||
const errObj = {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: /The "pid" argument must be of type number\./
|
||||
};
|
||||
|
||||
common.expectsError(() => {
|
||||
os.setPriority(pid, PRIORITY_NORMAL);
|
||||
}, errObj);
|
||||
|
||||
common.expectsError(() => {
|
||||
os.getPriority(pid);
|
||||
}, errObj);
|
||||
});
|
||||
|
||||
// Test pid range validation.
|
||||
[NaN, Infinity, -Infinity, 3.14, 2 ** 32].forEach((pid) => {
|
||||
const errObj = {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
message: /The value of "pid" is out of range\./
|
||||
};
|
||||
|
||||
common.expectsError(() => {
|
||||
os.setPriority(pid, PRIORITY_NORMAL);
|
||||
}, errObj);
|
||||
|
||||
common.expectsError(() => {
|
||||
os.getPriority(pid);
|
||||
}, errObj);
|
||||
});
|
||||
|
||||
// Test priority type validation.
|
||||
[null, true, false, 'foo', {}, [], /x/].forEach((priority) => {
|
||||
common.expectsError(() => {
|
||||
os.setPriority(0, priority);
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: /The "priority" argument must be of type number\./
|
||||
});
|
||||
});
|
||||
|
||||
// Test priority range validation.
|
||||
[
|
||||
NaN,
|
||||
Infinity,
|
||||
-Infinity,
|
||||
3.14,
|
||||
2 ** 32,
|
||||
PRIORITY_HIGHEST - 1,
|
||||
PRIORITY_LOW + 1
|
||||
].forEach((priority) => {
|
||||
common.expectsError(() => {
|
||||
os.setPriority(0, priority);
|
||||
}, {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
message: /The value of "priority" is out of range\./
|
||||
});
|
||||
});
|
||||
|
||||
// Verify that valid values work.
|
||||
for (let i = PRIORITY_HIGHEST; i <= PRIORITY_LOW; i++) {
|
||||
// A pid of 0 corresponds to the current process.
|
||||
try {
|
||||
os.setPriority(0, i);
|
||||
} catch (err) {
|
||||
// The current user might not have sufficient permissions to set this
|
||||
// specific priority level. Skip this priority, but keep trying lower
|
||||
// priorities.
|
||||
if (err.info.code === 'EACCES')
|
||||
continue;
|
||||
|
||||
assert(err);
|
||||
}
|
||||
|
||||
checkPriority(0, i);
|
||||
|
||||
// An undefined pid corresponds to the current process.
|
||||
os.setPriority(i);
|
||||
checkPriority(undefined, i);
|
||||
|
||||
// Specifying the actual pid works.
|
||||
os.setPriority(process.pid, i);
|
||||
checkPriority(process.pid, i);
|
||||
}
|
||||
|
||||
|
||||
function checkPriority(pid, expected) {
|
||||
const priority = os.getPriority(pid);
|
||||
|
||||
// Verify that the priority values match on Unix, and are range mapped on
|
||||
// Windows.
|
||||
if (!common.isWindows) {
|
||||
assert.strictEqual(priority, expected);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected < PRIORITY_HIGH)
|
||||
assert.strictEqual(priority, PRIORITY_HIGHEST);
|
||||
else if (expected < PRIORITY_ABOVE_NORMAL)
|
||||
assert.strictEqual(priority, PRIORITY_HIGH);
|
||||
else if (expected < PRIORITY_NORMAL)
|
||||
assert.strictEqual(priority, PRIORITY_ABOVE_NORMAL);
|
||||
else if (expected < PRIORITY_BELOW_NORMAL)
|
||||
assert.strictEqual(priority, PRIORITY_NORMAL);
|
||||
else if (expected < PRIORITY_LOW)
|
||||
assert.strictEqual(priority, PRIORITY_BELOW_NORMAL);
|
||||
else
|
||||
assert.strictEqual(priority, PRIORITY_LOW);
|
||||
}
|
||||
Reference in new issue
Block a user