1 /*
2 * Copyright (c) 2001-2017, Zoltan Farkas All Rights Reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Additionally licensed with:
19 *
20 * Licensed under the Apache License, Version 2.0 (the "License");
21 * you may not use this file except in compliance with the License.
22 * You may obtain a copy of the License at
23 *
24 * http://www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS,
28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29 * See the License for the specific language governing permissions and
30 * limitations under the License.
31 */
32 package org.spf4j.unix;
33
34 import com.sun.jna.Native;
35 import com.sun.jna.platform.unix.Resource;
36 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37 import org.spf4j.os.OperatingSystem;
38
39 /**
40 * Possible values of the first parameter to getrlimit()/setrlimit()
41 * A combination of com.sun.jna.platform.unix.Resource and MACOSX resource.h
42 * this class requires jna-platforn which is a optional dependency.
43 * @author zoly
44 */
45 @SuppressFBWarnings({"FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY", "MS_EXPOSE_REP"})
46 // class circularity should go away when deprecated methods from Runtime are removed.
47 public enum UnixResources {
48
49
50 /**
51 * 0 Per-process CPU limit, in seconds.
52 */
53 RLIMIT_CPU(0),
54 /**
55 * 1 Largest file that can be created, in bytes.
56 */
57 RLIMIT_FSIZE(1),
58 /**
59 * 2 Maximum size of data segment, in bytes.
60 */
61 RLIMIT_DATA(2),
62 /**
63 * 3 Maximum size of stack segment, in bytes.
64 */
65 RLIMIT_STACK(3),
66 /**
67 * 4 Largest core file that can be created, in bytes.
68 */
69 RLIMIT_CORE(4),
70 /**
71 * 5 Largest resident set size, in bytes. This affects swapping; processes that are exceeding their resident set size
72 * will be more likely to have physical memory taken from them.
73 */
74 RLIMIT_RSS(5),
75 /**
76 * 6 Number of processes.
77 */
78 RLIMIT_NPROC(6, 7),
79 /**
80 * 7 Number of open files.
81 */
82 RLIMIT_NOFILE(7, 8),
83 /**
84 * 8 Locked-in-memory address space.
85 */
86 RLIMIT_MEMLOCK(8, 6),
87 /**
88 * 9 Address space limit.
89 */
90 RLIMIT_AS(9, 5),
91 /**
92 * 10 Maximum number of file locks.
93 */
94 RLIMIT_LOCKS(10, -1),
95 /**
96 * 11 Maximum number of pending signals.
97 */
98 RLIMIT_SIGPENDING(11, -1),
99 /**
100 * 12 Maximum bytes in POSIX message queues.
101 */
102 RLIMIT_MSGQUEUE(12, -1),
103 /**
104 * 13 Maximum nice priority allowed to raise to. Nice levels 19 .. -20 correspond to 0 .. 39 values of this resource
105 * limit.
106 */
107 RLIMIT_NICE(13, -1),
108 /**
109 * 14
110 */
111 RLIMIT_RTPRIO(14, -1),
112 /**
113 * 15 Maximum CPU time in microseconds that a process scheduled under a real-time scheduling policy may consume
114 * without making a blocking system call before being forcibly de-scheduled.
115 */
116 RLIMIT_RTTIME(15, -1),
117 /**
118 * 16 Number of {@code rlimit} values
119 */
120 RLIMIT_NLIMITS(16, 9);
121
122 private final int macId;
123 private final int gnuId;
124
125 UnixResources(final int gnuId) {
126 this.macId = gnuId;
127 this.gnuId = gnuId;
128 }
129
130 UnixResources(final int gnuId, final int macId) {
131 this.macId = macId;
132 this.gnuId = gnuId;
133 }
134
135 public int getMacId() {
136 return macId;
137 }
138
139 public int getGnuId() {
140 return gnuId;
141 }
142
143 public long getSoftLimit() throws UnixException {
144 return getRLimit(this).rlim_cur;
145 }
146
147 public void setSoftLimit(final long limit) throws UnixException {
148 setRLimit(this, limit, getHardLimit());
149 }
150
151 public void setLimits(final long softLimit, final long hardlimit) throws UnixException {
152 setRLimit(this, softLimit, hardlimit);
153 }
154
155 public long getHardLimit() throws UnixException {
156 return getRLimit(this).rlim_max;
157 }
158
159 private static Resource.Rlimit getRLimit(final UnixResources resourceId) throws UnixException {
160 int id = OperatingSystem.isMacOsx() ? resourceId.macId : resourceId.gnuId;
161 if (id < 0) {
162 throw new UnixException("Unsupported " + id + " limit on " + OperatingSystem.getOsName(), 0);
163 }
164 final Resource.Rlimit limit = new Resource.Rlimit();
165 int err = CLibrary.INSTANCE.getrlimit(id, limit);
166 if (err != 0) {
167 int lastError = Native.getLastError();
168 throw new UnixException("Error code " + CLibrary.INSTANCE.strerror(lastError)
169 + " for getrlimit(" + id + ", " + limit + '\'', lastError);
170 }
171 return limit;
172 }
173
174 private static void setRLimit(final UnixResources resourceId, final long softValue, final long hardValue)
175 throws UnixException {
176 int id = OperatingSystem.isMacOsx() ? resourceId.macId : resourceId.gnuId;
177 if (id < 0) {
178 throw new UnixException("Unsupported " + id + " limit on " + OperatingSystem.getOsName(), 0);
179 }
180 final Resource.Rlimit limit = new Resource.Rlimit();
181 limit.rlim_cur = softValue;
182 limit.rlim_max = hardValue;
183 int err = CLibrary.INSTANCE.setrlimit(id, limit);
184 if (err != 0) {
185 int lastError = Native.getLastError();
186 throw new UnixException("Error " + CLibrary.INSTANCE.strerror(lastError)
187 + " for setrlimit(" + id + ", " + limit + '\'', lastError);
188 }
189 }
190
191 }