001 // MemoryParameters.java, created by wbeebee 002 // Copyright (C) 2001 Wes Beebee <wbeebee@mit.edu> 003 // Licensed under the terms of the GNU GPL; see COPYING for details. 004 package javax.realtime; 005 006 import java.util.LinkedList; 007 import java.util.Iterator; 008 009 /** 010 * @author Wes Beebee <<a href="mailto:wbeebee@mit.edu">wbeebee@mit.edu</a>> 011 */ 012 013 /** Memory parameters can be given on the constructor of 014 * <code>RealtimeThread</code> and <code>AsyncEventHandler</code>. These 015 * can be used both for the purposes of admission control by the 016 * scheduler and for the purposes of pacing the garbage collector to 017 * satisfy all of the thread allocation rates. 018 * <p> 019 * When a reference to a <code>MemoryParameters</code> object is given 020 * as a parameter to a constructor, the <code>MemoryParameters</code> 021 * object becomes bound to the object being created. Changes to the 022 * values in the <code>MemoryParameters</code> object affect the 023 * constructed object. If given to more than one constructor, then 024 * changes to the values in the <code>MemoryParameters</code> object 025 * affect <i>all</i> of the associated objects. Note that this is a 026 * one-to-many relationship and <i>not</i> a many-to-many. 027 * <p> 028 * <b>Caution:</b> This class is explicitly unsafe in multithreaded 029 * situations when it is being changed. No synchronization is done. It 030 * is assumed that users of this class who are mutating instances will 031 * be doing their own synchronization at a higher level. 032 */ 033 public class MemoryParameters { 034 035 /** Specifies no maximum limit */ 036 public static final long NO_MAX = -1; 037 private long allocationRate; 038 private long maxImmortal; 039 private long maxMemoryArea; 040 private MemoryArea memoryArea; 041 042 LinkedList schList = new LinkedList(); 043 044 /** Create a <code>MemoryParameters</code> object with the given values. 045 * 046 * @param maxMemoryArea A limit on the amount of memory the thread may allocate 047 * in the memory area. Units are in bytes. If zere, no 048 * allocation allowed in the memory area. To specify no 049 * limit, use NO_MAX or a value less than zero. 050 * @param maxImmortal A limit on the amount of memory the thread may allocate 051 * in the immortal area. Units are in bytes. If zero, no 052 * allocation allowed in immortal memory. To specify no 053 * limit, use NO_MAX or a value less than zero 054 * @throws java.langIllegalArgumentException 055 */ 056 public MemoryParameters(long maxMemoryArea, long maxImmortal) 057 throws IllegalArgumentException { 058 this.maxMemoryArea = Math.max(maxMemoryArea, NO_MAX); 059 this.maxImmortal = Math.max(maxImmortal, NO_MAX); 060 this.allocationRate = NO_MAX; 061 } 062 063 /** Create a <code>MemoryParameters</code> object with the given values. 064 * 065 * @param maxMemoryArea A limit on the amount of memory the thread may allocate 066 * in the memory area. Units are in bytes. If zere, no 067 * allocation allowed in the memory area. To specify no 068 * limit, use NO_MAX or a value less than zero. 069 * @param maxImmortal A limit on the amount of memory the thread may allocate 070 * in the immortal area. Units are in bytes. If zero, no 071 * allocation allowed in immortal memory. To specify no 072 * limit, use NO_MAX or a value less than zero 073 * @param allocationRate A limit on the rate of allocation in the heap. Units are 074 * in bytes per second. If zero, no allocation is allowed 075 * in the heap. To specify no limit, use NO_MAX or a value 076 * less than zero. 077 * @throws java.langIllegalArgumentException 078 */ 079 public MemoryParameters(long maxMemoryArea, long maxImmortal, 080 long allocationRate) 081 throws IllegalArgumentException { 082 this.maxMemoryArea = Math.max(maxMemoryArea, NO_MAX); 083 this.maxImmortal = Math.max(maxImmortal, NO_MAX); 084 this.allocationRate = Math.max(allocationRate, NO_MAX); 085 } 086 087 public MemoryParameters(MemoryArea memoryArea) { 088 this.memoryArea = memoryArea; 089 } 090 091 /** Gets the allocation rate. Units are in bytes per second. 092 * 093 * @return The allocation in bytes per second. 094 */ 095 public long getAllocationRate() { 096 return allocationRate; 097 } 098 099 /** Gets the limit on the amount of memory the thread may allocate 100 * in the immortal area. Units are in bytes. 101 * 102 * @return The limit of immortal memory. 103 */ 104 public long getMaxImmortal() { 105 return maxImmortal; 106 } 107 108 /** Gets the limit on the amount of memory the thread may allocate 109 * in the memory area. Units are in bytes. 110 * 111 * @return The allocation limit in this area. 112 */ 113 public long getMaxMemoryArea() { 114 return maxMemoryArea; 115 } 116 117 /** Sets the limit on the rate of allocation in the heap. 118 * 119 * @param allocationRate Units are in bytes per second. If zero, no 120 * allocation is allowed in the heap. To specify 121 * no limit, use NO_MAX or a values less than zero. 122 */ 123 public void setAllocationRate(long rate) { 124 allocationRate = Math.max(rate, NO_MAX); 125 } 126 127 /** Sets the limit on the rate of allocation in the heap. If this 128 * <code>MemoryParameters</code> object is currently associated with 129 * one or more realtime threads that have been passed admission 130 * control, this change in allocation rate will be submitted to 131 * admission control. The scheduler (in conjuction with the garbage 132 * collector) will either admit all the affected threads with the new 133 * allocation rate, or leave the allocation rate unchanged and cause 134 * <code>setAllocationRateIfFeasible</code> to return <code>false</code>. 135 * 136 * @param allocationRate Units are in bytes per second. If zero, no 137 * allocation is allowed in the heap. To specify 138 * no limit, use NO_MAX or a value less than zero. 139 * @return True, if the request was fulfilled. 140 */ 141 public boolean setAllocationRateIfFeasible(int allocationRate) { 142 // How do memory parameters affect the feasibility of the task set? 143 setAllocationRate(allocationRate); 144 for (Iterator it = schList.iterator(); it.hasNext(); ) 145 ((Schedulable)it.next()).setMemoryParameters(this); 146 147 return true; 148 } 149 150 /** Sets the limit on the amount of memory the thread may allocate in the immortal area. 151 * 152 * @param maximum Units are in bytes. If zero, no allocation allowed in 153 * immortal. To specify no limit, use NO_MAX or a value 154 * less than zero. 155 * @return True if the value is set. False if any of the threads have 156 * already allocated more than the given value. in this case 157 * the call has no effect. 158 */ 159 public boolean setMaxImmortalIfFeasible(long maximum) { 160 // How do memory parameters affect the feasibility of the task set? 161 setMaxImmortal(maximum); 162 for (Iterator it = schList.iterator(); it.hasNext(); ) 163 ((Schedulable)it.next()).setMemoryParameters(this); 164 165 return true; 166 } 167 168 /** Sets the limit on the amount of memory the thread may allocate in the memory area. 169 * 170 * @param maximum Units are in bytes. If zero, no allocation allowed in 171 * the memory area. To specify no limit, use NO_MAX or a 172 * value less than zero. 173 * @return True if the value is set. False if any of the threads have already 174 * allocated more than the given value. In this case the call has no effect. 175 */ 176 public boolean setMaxMemoryAreaIfFeasible(long maximum) { 177 // How do memory parameters affect the feasibility of the task set? 178 setMaxMemoryArea(maximum); 179 for (Iterator it = schList.iterator(); it.hasNext(); ) 180 ((Schedulable)it.next()).setMemoryParameters(this); 181 182 return true; 183 } 184 185 public /* private ? */ void setMaxImmortal(long maximum) { 186 maxImmortal = maximum; 187 } 188 189 public /* private ? */ void setMaxMemoryArea(long maximum) { 190 maxMemoryArea = maximum; 191 } 192 193 public MemoryArea getMemoryArea() { 194 return memoryArea; 195 } 196 197 /** Informs <code>this</code> that there is one more instance of <code>Schedulable</code> 198 * that uses <code>this</code> as its <code>ReleaseParameters</code>. 199 */ 200 public boolean bindSchedulable(Schedulable sch) { 201 return schList.add(sch); 202 } 203 204 /** Informs <code>this</code> that <code>Schedulable sch</code> 205 * that uses <code>this</code> as its <code>ReleaseParameters</code>. 206 */ 207 public boolean unbindSchedulable(Schedulable sch) { 208 return schList.remove(sch); 209 } 210 }