1 | /* |
2 | * Copyright 2016-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #include <folly/portability/SysResource.h> |
18 | |
19 | #include <errno.h> |
20 | |
21 | #ifdef _WIN32 |
22 | #include <folly/portability/Windows.h> |
23 | |
24 | extern "C" { |
25 | int getrlimit(int type, rlimit* dst) { |
26 | if (type == RLIMIT_STACK) { |
27 | NT_TIB* tib = (NT_TIB*)NtCurrentTeb(); |
28 | dst->rlim_cur = (size_t)tib->StackBase - (size_t)tib->StackLimit; |
29 | dst->rlim_max = dst->rlim_cur; |
30 | return 0; |
31 | } |
32 | return -1; |
33 | } |
34 | |
35 | int getrusage(int /* who */, rusage* usage) { |
36 | // You get NOTHING! Good day to you sir. |
37 | ZeroMemory(usage, sizeof(rusage)); |
38 | return 0; |
39 | } |
40 | |
41 | int setrlimit(int /* type */, rlimit* /* src */) { |
42 | // Do nothing for setting them for now. |
43 | // We couldn't set the stack size at runtime even if we wanted to. |
44 | return 0; |
45 | } |
46 | |
47 | int getpriority(int which, int who) { |
48 | if (which != PRIO_PROCESS || who != 0) { |
49 | errno = EINVAL; |
50 | return -1; |
51 | } |
52 | |
53 | auto ret = GetPriorityClass(GetCurrentProcess()); |
54 | switch (ret) { |
55 | case 0: |
56 | errno = EACCES; |
57 | return -1; |
58 | case IDLE_PRIORITY_CLASS: |
59 | return 39; |
60 | case BELOW_NORMAL_PRIORITY_CLASS: |
61 | return 30; |
62 | case NORMAL_PRIORITY_CLASS: |
63 | return 20; |
64 | case ABOVE_NORMAL_PRIORITY_CLASS: |
65 | return 10; |
66 | case HIGH_PRIORITY_CLASS: |
67 | return 0; |
68 | case REALTIME_PRIORITY_CLASS: |
69 | // I'd return -1 if it weren't an error :( |
70 | // Realtime priority processes can't be set |
71 | // through these APIs because it's a terrible idea. |
72 | return 0; |
73 | default: |
74 | errno = EINVAL; |
75 | return -1; |
76 | } |
77 | } |
78 | |
79 | int setpriority(int which, int who, int value) { |
80 | if (which != PRIO_PROCESS || who != 0) { |
81 | errno = EINVAL; |
82 | return -1; |
83 | } |
84 | |
85 | auto newClass = [value] { |
86 | if (value >= 39) { |
87 | return IDLE_PRIORITY_CLASS; |
88 | } else if (value >= 30) { |
89 | return BELOW_NORMAL_PRIORITY_CLASS; |
90 | } else if (value >= 20) { |
91 | return NORMAL_PRIORITY_CLASS; |
92 | } else if (value >= 10) { |
93 | return ABOVE_NORMAL_PRIORITY_CLASS; |
94 | } else { |
95 | return HIGH_PRIORITY_CLASS; |
96 | } |
97 | }(); |
98 | |
99 | if (!SetPriorityClass(GetCurrentProcess(), newClass)) { |
100 | errno = EACCES; |
101 | return -1; |
102 | } |
103 | return 0; |
104 | } |
105 | } |
106 | #endif |
107 | |