View Javadoc
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 }