001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.runtime;
014
015import org.jikesrvm.annotations.GenerateImplementation;
016import org.jikesrvm.annotations.SysCallTemplate;
017import org.jikesrvm.scheduler.RVMThread;
018import org.vmmagic.pragma.Uninterruptible;
019import org.vmmagic.unboxed.Address;
020import org.vmmagic.unboxed.Word;
021import org.vmmagic.unboxed.Extent;
022import org.vmmagic.unboxed.Offset;
023
024/**
025 * Support for lowlevel (i.e. non-JNI) invocation of C functions with
026 * static addresses.
027 * <p>
028 * All methods of this class have the following signature:
029 * <pre>
030 * public abstract &lt;TYPE&gt; NAME(&lt;args to pass to sysNAME via native calling convention&gt;)
031 * </pre>
032 * which will call the corresponding method in system call trampoline
033 * with the added function address from the boot image.
034 * <p>
035 * NOTE: From the standpoint of the rest of the VM, an invocation
036 * to a method of SysCall is uninterruptible.
037 * <p>
038 * NOTE: There must be a matching field NAMEIP in BootRecord.java
039 *       for each method declared here.
040 */
041@Uninterruptible
042@GenerateImplementation("org.jikesrvm.runtime.SysCallImpl")
043public abstract class SysCall {
044
045  /**
046   * Actual implementation of the SysCall class. The implementation
047   * is generated from the code in this class during the build process.
048   */
049  public static final SysCall sysCall;
050
051  static {
052    try {
053      sysCall = (SysCall)Class.forName("org.jikesrvm.runtime.SysCallImpl").newInstance();
054    } catch (final Exception e) {
055      throw new Error(e);
056    }
057  }
058
059  // lowlevel write to console
060  @SysCallTemplate
061  public abstract void sysConsoleWriteChar(char v);
062
063  @SysCallTemplate
064  public abstract void sysConsoleWriteInteger(int value, int hexToo);
065
066  @SysCallTemplate
067  public abstract void sysConsoleWriteLong(long value, int hexToo);
068
069  @SysCallTemplate
070  public abstract void sysConsoleWriteDouble(double value, int postDecimalDigits);
071
072  // startup/shutdown
073  @SysCallTemplate
074  public abstract void sysExit(int value);
075  @SysCallTemplate
076  public abstract int sysArg(int argno, byte[] buf, int buflen);
077
078  // misc. info on the process -- used in startup/shutdown
079  @SysCallTemplate
080  public abstract int sysGetenv(byte[] varName, byte[] buf, int limit);
081
082  // memory
083
084  /**
085   * Copies memory.<p>
086   *
087   * Assumption: the memory regions do not overlap. Use
088   * {@link #sysMemmove(Address, Address, Extent)} if the regions might overlap.
089   * @param dst destination address
090   * @param src source address
091   * @param cnt number of bytes to copy
092   */
093  @SysCallTemplate
094  public abstract void sysCopy(Address dst, Address src, Extent cnt);
095
096  /**
097   * Copies memory without making any assumptions about the memory areas.
098   *
099   * @param dst destination address
100   * @param src source address
101   * @param cnt number of bytes to copy
102   */
103  @SysCallTemplate
104  public abstract void sysMemmove(Address dst, Address src, Extent cnt);
105
106  @SysCallTemplate
107  public abstract Address sysMalloc(int length);
108
109  @SysCallTemplate
110  public abstract Address sysCalloc(int length);
111
112  @SysCallTemplate
113  public abstract void sysFree(Address location);
114
115  @SysCallTemplate
116  public abstract void sysZeroNT(Address dst, Extent cnt);
117
118  @SysCallTemplate
119  public abstract void sysZero(Address dst, Extent cnt);
120
121  @SysCallTemplate
122  public abstract void sysZeroPages(Address dst, int cnt);
123
124  @SysCallTemplate
125  public abstract void sysSyncCache(Address address, int size);
126
127  /*
128   * Interface to performance events
129   */
130  @SysCallTemplate
131  public abstract int sysPerfEventInit(int events);
132  @SysCallTemplate
133  public abstract int sysPerfEventCreate(int id, byte[] name);
134  @SysCallTemplate
135  public abstract void sysPerfEventEnable();
136  @SysCallTemplate
137  public abstract void sysPerfEventDisable();
138  @SysCallTemplate
139  public abstract int sysPerfEventRead(int id, long[] values);
140
141  // files
142  @SysCallTemplate
143  public abstract int sysReadByte(int fd);
144
145  @SysCallTemplate
146  public abstract int sysWriteByte(int fd, int data);
147
148  @SysCallTemplate
149  public abstract int sysReadBytes(int fd, Address buf, int cnt);
150
151  @SysCallTemplate
152  public abstract int sysWriteBytes(int fd, Address buf, int cnt);
153
154  // mmap - memory mapping
155  @SysCallTemplate
156  public abstract Address sysMMap(Address start, Extent length, int protection, int flags, int fd, Offset offset);
157
158  @SysCallTemplate
159  public abstract Address sysMMapErrno(Address start, Extent length, int protection, int flags, int fd, Offset offset);
160
161  @SysCallTemplate
162  public abstract int sysMProtect(Address start, Extent length, int prot);
163
164  // threads
165  @SysCallTemplate
166  public abstract int sysNumProcessors();
167
168  /**
169   * Creates a native thread (aka "unix kernel thread", "pthread").
170   * @param ip the current instruction pointer
171   * @param fp the frame pointer
172   * @param tr the address of the RVMThread object for the thread
173   * @param jtoc value for the thread jtoc
174   * @return native thread's o/s handle
175   */
176  @SysCallTemplate
177  public abstract Word sysThreadCreate(Address ip, Address fp, Address tr, Address jtoc);
178
179  /**
180   * Tells you if the current system supportes sysNativeThreadBind().
181   * @return 1 if it's supported, 0 if it isn't
182   */
183  @SysCallTemplate
184  public abstract int sysThreadBindSupported();
185
186  @SysCallTemplate
187  public abstract void sysThreadBind(int cpuId);
188
189  @SysCallTemplate
190  public abstract void sysThreadYield();
191
192  @SysCallTemplate
193  public abstract Word sysGetThreadId();
194
195  @SysCallTemplate
196  public abstract Word sysGetThreadPriorityHandle();
197
198  @SysCallTemplate
199  public abstract int sysGetThreadPriority(Word thread, Word handle);
200
201  @SysCallTemplate
202  public abstract int sysSetThreadPriority(Word thread, Word handle, int priority);
203
204  // This implies that the RVMThread is somehow pinned, or else the
205  // pthread key value gets moved.  (hence RVMThread is @NonMoving)
206  @SysCallTemplate
207  public abstract int sysStashVMThread(RVMThread vmThread);
208  @SysCallTemplate
209  public abstract void sysThreadTerminate();
210  /**
211   * Allocate the space for a pthread_mutex (using malloc) and initialize
212   * it using pthread_mutex_init with the recursive mutex options.  Note:
213   * it is perfectly OK for the C code that implements this syscall to
214   * use some other locking mechanism (for example, on systems that don't
215   * have recursive mutexes you could imagine the recursive feature to be
216   * emulated).
217   *
218   * @return pointer to the created monitor for use in other monitor sys calls
219   */
220  @SysCallTemplate
221  public abstract Word sysMonitorCreate();
222  /**
223   * Destroy the monitor pointed to by the argument and free its memory
224   * by calling free.
225   *
226   * @param monitor the pointer to the monitor that is supposed to be
227   *  destroyed
228   */
229  @SysCallTemplate
230  public abstract void sysMonitorDestroy(Word monitor);
231  @SysCallTemplate
232  public abstract void sysMonitorEnter(Word monitor);
233  @SysCallTemplate
234  public abstract void sysMonitorExit(Word monitor);
235  @SysCallTemplate
236  public abstract void sysMonitorTimedWaitAbsolute(Word monitor, long whenWakeupNanos);
237  @SysCallTemplate
238  public abstract void sysMonitorWait(Word monitor);
239  @SysCallTemplate
240  public abstract void sysMonitorBroadcast(Word monitor);
241  // arithmetic
242  @SysCallTemplate
243  public abstract long sysLongDivide(long x, long y);
244
245  @SysCallTemplate
246  public abstract long sysLongRemainder(long x, long y);
247
248  @SysCallTemplate
249  public abstract float sysLongToFloat(long x);
250
251  @SysCallTemplate
252  public abstract double sysLongToDouble(long x);
253
254  @SysCallTemplate
255  public abstract int sysFloatToInt(float x);
256
257  @SysCallTemplate
258  public abstract int sysDoubleToInt(double x);
259
260  @SysCallTemplate
261  public abstract long sysFloatToLong(float x);
262
263  @SysCallTemplate
264  public abstract long sysDoubleToLong(double x);
265
266  @SysCallTemplate
267  public abstract double sysDoubleRemainder(double x, double y);
268
269  /**
270   * Used to parse command line arguments that are
271   * doubles and floats early in booting before it
272   * is safe to call Float.valueOf or Double.valueOf.
273   *
274   * This aborts in case of errors, with an appropriate error message.
275   *
276   * NOTE: this does not support the full Java spec of parsing a string
277   *       into a float.
278   * @param buf a null terminated byte[] that can be parsed
279   *            by strtof()
280   * @return the floating-point value produced by the call to strtof() on buf.
281   */
282  @SysCallTemplate
283  public abstract float sysPrimitiveParseFloat(byte[] buf);
284
285  /**
286   * Used to parse command line arguments that are
287   * bytes and ints early in booting before it
288   * is safe to call Byte.parseByte or Integer.parseInt.
289   *
290   * This aborts in case of errors, with an appropriate error message.
291   *
292   * @param buf a null terminated byte[] that can be parsed
293   *            by strtol()
294   * @return the int value produced by the call to strtol() on buf.
295   */
296  @SysCallTemplate
297  public abstract int sysPrimitiveParseInt(byte[] buf);
298
299  /**
300   * Primitive parsing of memory sizes, with proper error handling,
301   * and so on. For all the gory details, see the code in the
302   * bootloader.
303   * <p>
304   * Note: all byte array parameters for this method represent Strings.
305   *
306   * @param sizeName the option's name
307   * @param sizeFlag the flag's name, e.g. mx (as in "-Xmx")
308   * @param defaultFactor factor for modifying sizes, e.g. "K", "M" or "pages"
309   * @param roundTo round up to a multiple of this number
310   * @param argToken the full command line argument, e.g. "-Xmx200M"
311   * @param subArg the value for the argument, e.g. "200M"
312   * @return Negative values on error.
313   *      Otherwise, positive or zero values as bytes.
314   */
315  @SysCallTemplate
316  public abstract long sysParseMemorySize(byte[] sizeName, byte[] sizeFlag, byte[] defaultFactor, int roundTo,
317                                          byte[] argToken, byte[] subArg);
318
319  // time
320  @SysCallTemplate
321  public abstract long sysCurrentTimeMillis();
322
323  @SysCallTemplate
324  public abstract long sysNanoTime();
325
326  @SysCallTemplate
327  public abstract void sysNanoSleep(long howLongNanos);
328
329  // shared libraries
330  @SysCallTemplate
331  public abstract Address sysDlopen(byte[] libname);
332
333  @SysCallTemplate
334  public abstract Address sysDlsym(Address libHandler, byte[] symbolName);
335
336  // var args
337  @SysCallTemplate
338  public abstract Address sysVaCopy(Address va_list);
339  @SysCallTemplate
340  public abstract void sysVaEnd(Address va_list);
341  @SysCallTemplate
342  public abstract boolean sysVaArgJboolean(Address va_list);
343  @SysCallTemplate
344  public abstract byte sysVaArgJbyte(Address va_list);
345  @SysCallTemplate
346  public abstract char sysVaArgJchar(Address va_list);
347  @SysCallTemplate
348  public abstract short sysVaArgJshort(Address va_list);
349  @SysCallTemplate
350  public abstract int sysVaArgJint(Address va_list);
351  @SysCallTemplate
352  public abstract long sysVaArgJlong(Address va_list);
353  @SysCallTemplate
354  public abstract float sysVaArgJfloat(Address va_list);
355  @SysCallTemplate
356  public abstract double sysVaArgJdouble(Address va_list);
357  @SysCallTemplate
358  public abstract int sysVaArgJobject(Address va_list);
359
360  // system calls for alignment checking
361  @SysCallTemplate
362  public abstract void sysEnableAlignmentChecking();
363
364  @SysCallTemplate
365  public abstract void sysDisableAlignmentChecking();
366
367  @SysCallTemplate
368  public abstract void sysReportAlignmentChecking();
369
370  @SysCallTemplate
371  public abstract Address gcspyDriverAddStream(Address driver, int id);
372
373  @SysCallTemplate
374  public abstract void gcspyDriverEndOutput(Address driver);
375
376  @SysCallTemplate
377  public abstract void gcspyDriverInit(Address driver, int id, Address serverName, Address driverName, Address title,
378                                       Address blockInfo, int tileNum, Address unused, int mainSpace);
379
380  @SysCallTemplate
381  public abstract void gcspyDriverInitOutput(Address driver);
382
383  @SysCallTemplate
384  public abstract void gcspyDriverResize(Address driver, int size);
385
386  @SysCallTemplate
387  public abstract void gcspyDriverSetTileNameRange(Address driver, int i, Address start, Address end);
388
389  @SysCallTemplate
390  public abstract void gcspyDriverSetTileName(Address driver, int i, Address start, long value);
391
392  @SysCallTemplate
393  public abstract void gcspyDriverSpaceInfo(Address driver, Address info);
394
395  @SysCallTemplate
396  public abstract void gcspyDriverStartComm(Address driver);
397
398  @SysCallTemplate
399  public abstract void gcspyDriverStream(Address driver, int id, int len);
400
401  @SysCallTemplate
402  public abstract void gcspyDriverStreamByteValue(Address driver, byte value);
403
404  @SysCallTemplate
405  public abstract void gcspyDriverStreamShortValue(Address driver, short value);
406
407  @SysCallTemplate
408  public abstract void gcspyDriverStreamIntValue(Address driver, int value);
409
410  @SysCallTemplate
411  public abstract void gcspyDriverSummary(Address driver, int id, int len);
412
413  @SysCallTemplate
414  public abstract void gcspyDriverSummaryValue(Address driver, int value);
415
416  @SysCallTemplate
417  public abstract void gcspyIntWriteControl(Address driver, int id, int tileNum);
418
419  @SysCallTemplate
420  public abstract Address gcspyMainServerAddDriver(Address addr);
421
422  @SysCallTemplate
423  public abstract void gcspyMainServerAddEvent(Address server, int event, Address name);
424
425  @SysCallTemplate
426  public abstract Address gcspyMainServerInit(int port, int len, Address name, int verbose);
427
428  @SysCallTemplate
429  public abstract int gcspyMainServerIsConnected(Address server, int event);
430
431  @SysCallTemplate
432  public abstract Address gcspyMainServerOuterLoop();
433
434  @SysCallTemplate
435  public abstract void gcspyMainServerSafepoint(Address server, int event);
436
437  @SysCallTemplate
438  public abstract void gcspyMainServerSetGeneralInfo(Address server, Address info);
439
440  @SysCallTemplate
441  public abstract void gcspyMainServerStartCompensationTimer(Address server);
442
443  @SysCallTemplate
444  public abstract void gcspyMainServerStopCompensationTimer(Address server);
445
446  @SysCallTemplate
447  public abstract void gcspyStartserver(Address server, int wait, Address serverOuterLoop);
448
449  @SysCallTemplate
450  public abstract void gcspyStreamInit(Address stream, int id, int dataType, Address name, int minValue, int maxValue,
451                                       int zeroValue, int defaultValue, Address pre, Address post, int presentation,
452                                       int paintStyle, int maxStreamIndex, int red, int green, int blue);
453
454  @SysCallTemplate
455  public abstract void gcspyFormatSize(Address buffer, int size);
456
457  @SysCallTemplate
458  public abstract int gcspySprintf(Address str, Address format, Address value);
459}
460