Skip to content

Commit 219da67

Browse files
cjihrigtargos
authored andcommitted
os: add os.{get,set}Priority()
PR-URL: #22407 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
1 parent 5b14066 commit 219da67

File tree

7 files changed

+343
-2
lines changed

7 files changed

+343
-2
lines changed

doc/api/os.md

+87
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,19 @@ added: v0.3.3
192192
The `os.freemem()` method returns the amount of free system memory in bytes as
193193
an integer.
194194

195+
## os.getPriority([pid])
196+
<!-- YAML
197+
added: REPLACEME
198+
-->
199+
200+
* `pid` {integer} The process ID to retrieve scheduling priority for.
201+
**Default** `0`.
202+
* Returns: {integer}
203+
204+
The `os.getPriority()` method returns the scheduling priority for the process
205+
specified by `pid`. If `pid` is not provided, or is `0`, the priority of the
206+
current process is returned.
207+
195208
## os.homedir()
196209
<!-- YAML
197210
added: v2.3.0
@@ -338,6 +351,26 @@ On POSIX systems, the operating system release is determined by calling
338351
[uname(3)][]. On Windows, `GetVersionExW()` is used. Please see
339352
https://en.wikipedia.org/wiki/Uname#Examples for more information.
340353

354+
## os.setPriority([pid, ]priority)
355+
<!-- YAML
356+
added: REPLACEME
357+
-->
358+
359+
* `pid` {integer} The process ID to set scheduling priority for.
360+
**Default** `0`.
361+
* `priority` {integer} The scheduling priority to assign to the process.
362+
363+
The `os.setPriority()` method attempts to set the scheduling priority for the
364+
process specified by `pid`. If `pid` is not provided, or is `0`, the priority
365+
of the current process is used.
366+
367+
The `priority` input must be an integer between `-20` (high priority) and `19`
368+
(low priority). Due to differences between Unix priority levels and Windows
369+
priority classes, `priority` is mapped to one of six priority constants in
370+
`os.constants.priority`. When retrieving a process priority level, this range
371+
mapping may cause the return value to be slightly different on Windows. To avoid
372+
confusion, it is recommended to set `priority` to one of the priority constants.
373+
341374
## os.tmpdir()
342375
<!-- YAML
343376
added: v0.9.9
@@ -1208,6 +1241,60 @@ information.
12081241
</tr>
12091242
</table>
12101243

1244+
### Priority Constants
1245+
<!-- YAML
1246+
added: REPLACEME
1247+
-->
1248+
1249+
The following process scheduling constants are exported by
1250+
`os.constants.priority`:
1251+
1252+
<table>
1253+
<tr>
1254+
<th>Constant</th>
1255+
<th>Description</th>
1256+
</tr>
1257+
<tr>
1258+
<td><code>PRIORITY_LOW</code></td>
1259+
<td>The lowest process scheduling priority. This corresponds to
1260+
<code>IDLE_PRIORITY_CLASS</code> on Windows, and a nice value of
1261+
<code>19</code> on all other platforms.</td>
1262+
</tr>
1263+
<tr>
1264+
<td><code>PRIORITY_BELOW_NORMAL</code></td>
1265+
<td>The process scheduling priority above <code>PRIORITY_LOW</code> and
1266+
below <code>PRIORITY_NORMAL</code>. This corresponds to
1267+
<code>BELOW_NORMAL_PRIORITY_CLASS</code> on Windows, and a nice value of
1268+
<code>10</code> on all other platforms.</td>
1269+
</tr>
1270+
<tr>
1271+
<td><code>PRIORITY_NORMAL</code></td>
1272+
<td>The default process scheduling priority. This corresponds to
1273+
<code>NORMAL_PRIORITY_CLASS</code> on Windows, and a nice value of
1274+
<code>0</code> on all other platforms.</td>
1275+
</tr>
1276+
<tr>
1277+
<td><code>PRIORITY_ABOVE_NORMAL</code></td>
1278+
<td>The process scheduling priority above <code>PRIORITY_NORMAL</code> and
1279+
below <code>PRIORITY_HIGH</code>. This corresponds to
1280+
<code>ABOVE_NORMAL_PRIORITY_CLASS</code> on Windows, and a nice value of
1281+
<code>-7</code> on all other platforms.</td>
1282+
</tr>
1283+
<tr>
1284+
<td><code>PRIORITY_HIGH</code></td>
1285+
<td>The process scheduling priority above <code>PRIORITY_ABOVE_NORMAL</code>
1286+
and below <code>PRIORITY_HIGHEST</code>. This corresponds to
1287+
<code>HIGH_PRIORITY_CLASS</code> on Windows, and a nice value of
1288+
<code>-14</code> on all other platforms.</td>
1289+
</tr>
1290+
<tr>
1291+
<td><code>PRIORITY_HIGHEST</code></td>
1292+
<td>The highest process scheduling priority. This corresponds to
1293+
<code>REALTIME_PRIORITY_CLASS</code> on Windows, and a nice value of
1294+
<code>-20</code> on all other platforms.</td>
1295+
</tr>
1296+
</table>
1297+
12111298
### libuv Constants
12121299

12131300
<table>

lib/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const constants = process.binding('constants');
2929
Object.assign(exports,
3030
constants.os.dlopen,
3131
constants.os.errno,
32+
constants.os.priority,
3233
constants.os.signals,
3334
constants.fs,
3435
constants.crypto);

lib/os.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const { deprecate } = require('internal/util');
2727
const isWindows = process.platform === 'win32';
2828

2929
const { codes: { ERR_SYSTEM_ERROR } } = require('internal/errors');
30+
const { validateInt32 } = require('internal/validators');
3031

3132
const {
3233
getCPUs,
@@ -37,10 +38,12 @@ const {
3738
getLoadAvg,
3839
getOSRelease: _getOSRelease,
3940
getOSType: _getOSType,
41+
getPriority: _getPriority,
4042
getTotalMem,
4143
getUserInfo: _getUserInfo,
4244
getUptime,
43-
isBigEndian
45+
isBigEndian,
46+
setPriority: _setPriority
4447
} = process.binding('os');
4548

4649
function getCheckedFunction(fn) {
@@ -206,17 +209,49 @@ function networkInterfaces() {
206209
return interfaceAddresses;
207210
}
208211

212+
function setPriority(pid, priority) {
213+
if (priority === undefined) {
214+
priority = pid;
215+
pid = 0;
216+
}
217+
218+
validateInt32(pid, 'pid');
219+
validateInt32(priority, 'priority', -20, 19);
220+
221+
const ctx = {};
222+
223+
if (_setPriority(pid, priority, ctx) !== 0)
224+
throw new ERR_SYSTEM_ERROR(ctx);
225+
}
226+
227+
function getPriority(pid) {
228+
if (pid === undefined)
229+
pid = 0;
230+
else
231+
validateInt32(pid, 'pid');
232+
233+
const ctx = {};
234+
const priority = _getPriority(pid, ctx);
235+
236+
if (priority === undefined)
237+
throw new ERR_SYSTEM_ERROR(ctx);
238+
239+
return priority;
240+
}
241+
209242
module.exports = {
210243
arch,
211244
cpus,
212245
endianness,
213246
freemem: getFreeMem,
247+
getPriority,
214248
homedir: getHomeDirectory,
215249
hostname: getHostname,
216250
loadavg,
217251
networkInterfaces,
218252
platform,
219253
release: getOSRelease,
254+
setPriority,
220255
tmpdir,
221256
totalmem: getTotalMem,
222257
type: getOSType,

src/node_constants.cc

+44
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,44 @@ void DefineSignalConstants(Local<Object> target) {
758758
#endif
759759
}
760760

761+
void DefinePriorityConstants(Local<Object> target) {
762+
#ifdef UV_PRIORITY_LOW
763+
# define PRIORITY_LOW UV_PRIORITY_LOW
764+
NODE_DEFINE_CONSTANT(target, PRIORITY_LOW);
765+
# undef PRIORITY_LOW
766+
#endif
767+
768+
#ifdef UV_PRIORITY_BELOW_NORMAL
769+
# define PRIORITY_BELOW_NORMAL UV_PRIORITY_BELOW_NORMAL
770+
NODE_DEFINE_CONSTANT(target, PRIORITY_BELOW_NORMAL);
771+
# undef PRIORITY_BELOW_NORMAL
772+
#endif
773+
774+
#ifdef UV_PRIORITY_NORMAL
775+
# define PRIORITY_NORMAL UV_PRIORITY_NORMAL
776+
NODE_DEFINE_CONSTANT(target, PRIORITY_NORMAL);
777+
# undef PRIORITY_NORMAL
778+
#endif
779+
780+
#ifdef UV_PRIORITY_ABOVE_NORMAL
781+
# define PRIORITY_ABOVE_NORMAL UV_PRIORITY_ABOVE_NORMAL
782+
NODE_DEFINE_CONSTANT(target, PRIORITY_ABOVE_NORMAL);
783+
# undef PRIORITY_ABOVE_NORMAL
784+
#endif
785+
786+
#ifdef UV_PRIORITY_HIGH
787+
# define PRIORITY_HIGH UV_PRIORITY_HIGH
788+
NODE_DEFINE_CONSTANT(target, PRIORITY_HIGH);
789+
# undef PRIORITY_HIGH
790+
#endif
791+
792+
#ifdef UV_PRIORITY_HIGHEST
793+
# define PRIORITY_HIGHEST UV_PRIORITY_HIGHEST
794+
NODE_DEFINE_CONSTANT(target, PRIORITY_HIGHEST);
795+
# undef PRIORITY_HIGHEST
796+
#endif
797+
}
798+
761799
void DefineOpenSSLConstants(Local<Object> target) {
762800
#ifdef OPENSSL_VERSION_NUMBER
763801
NODE_DEFINE_CONSTANT(target, OPENSSL_VERSION_NUMBER);
@@ -1338,6 +1376,10 @@ void DefineConstants(v8::Isolate* isolate, Local<Object> target) {
13381376
CHECK(sig_constants->SetPrototype(env->context(),
13391377
Null(env->isolate())).FromJust());
13401378

1379+
Local<Object> priority_constants = Object::New(isolate);
1380+
CHECK(priority_constants->SetPrototype(env->context(),
1381+
Null(env->isolate())).FromJust());
1382+
13411383
Local<Object> fs_constants = Object::New(isolate);
13421384
CHECK(fs_constants->SetPrototype(env->context(),
13431385
Null(env->isolate())).FromJust());
@@ -1361,6 +1403,7 @@ void DefineConstants(v8::Isolate* isolate, Local<Object> target) {
13611403
DefineErrnoConstants(err_constants);
13621404
DefineWindowsErrorConstants(err_constants);
13631405
DefineSignalConstants(sig_constants);
1406+
DefinePriorityConstants(priority_constants);
13641407
DefineSystemConstants(fs_constants);
13651408
DefineOpenSSLConstants(crypto_constants);
13661409
DefineCryptoConstants(crypto_constants);
@@ -1374,6 +1417,7 @@ void DefineConstants(v8::Isolate* isolate, Local<Object> target) {
13741417
os_constants->Set(OneByteString(isolate, "dlopen"), dlopen_constants);
13751418
os_constants->Set(OneByteString(isolate, "errno"), err_constants);
13761419
os_constants->Set(OneByteString(isolate, "signals"), sig_constants);
1420+
os_constants->Set(OneByteString(isolate, "priority"), priority_constants);
13771421
target->Set(OneByteString(isolate, "os"), os_constants);
13781422
target->Set(OneByteString(isolate, "fs"), fs_constants);
13791423
target->Set(OneByteString(isolate, "crypto"), crypto_constants);

src/node_os.cc

+43
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ using v8::Context;
5252
using v8::Float64Array;
5353
using v8::Function;
5454
using v8::FunctionCallbackInfo;
55+
using v8::Int32;
5556
using v8::Integer;
5657
using v8::Local;
5758
using v8::MaybeLocal;
@@ -405,6 +406,46 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
405406
}
406407

407408

409+
static void SetPriority(const FunctionCallbackInfo<Value>& args) {
410+
Environment* env = Environment::GetCurrent(args);
411+
412+
CHECK_EQ(args.Length(), 3);
413+
CHECK(args[0]->IsInt32());
414+
CHECK(args[1]->IsInt32());
415+
416+
const int pid = args[0].As<Int32>()->Value();
417+
const int priority = args[1].As<Int32>()->Value();
418+
const int err = uv_os_setpriority(pid, priority);
419+
420+
if (err) {
421+
CHECK(args[2]->IsObject());
422+
env->CollectUVExceptionInfo(args[2], err, "uv_os_setpriority");
423+
}
424+
425+
args.GetReturnValue().Set(err);
426+
}
427+
428+
429+
static void GetPriority(const FunctionCallbackInfo<Value>& args) {
430+
Environment* env = Environment::GetCurrent(args);
431+
432+
CHECK_EQ(args.Length(), 2);
433+
CHECK(args[0]->IsInt32());
434+
435+
const int pid = args[0].As<Int32>()->Value();
436+
int priority;
437+
const int err = uv_os_getpriority(pid, &priority);
438+
439+
if (err) {
440+
CHECK(args[1]->IsObject());
441+
env->CollectUVExceptionInfo(args[1], err, "uv_os_getpriority");
442+
return;
443+
}
444+
445+
args.GetReturnValue().Set(priority);
446+
}
447+
448+
408449
void Initialize(Local<Object> target,
409450
Local<Value> unused,
410451
Local<Context> context) {
@@ -420,6 +461,8 @@ void Initialize(Local<Object> target,
420461
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
421462
env->SetMethod(target, "getHomeDirectory", GetHomeDirectory);
422463
env->SetMethod(target, "getUserInfo", GetUserInfo);
464+
env->SetMethod(target, "setPriority", SetPriority);
465+
env->SetMethod(target, "getPriority", GetPriority);
423466
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
424467
Boolean::New(env->isolate(), IsBigEndian()));
425468
}

test/parallel/test-binding-constants.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ assert.deepStrictEqual(
1010

1111
assert.deepStrictEqual(
1212
Object.keys(constants.os).sort(), ['UV_UDP_REUSEADDR', 'dlopen', 'errno',
13-
'signals']
13+
'priority', 'signals']
1414
);
1515

1616
// Make sure all the constants objects don't inherit from Object.prototype

0 commit comments

Comments
 (0)