Skip to content

Commit

Permalink
[Truffle] Process.times
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Mar 24, 2015
1 parent 254f3c2 commit 72536b3
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 21 deletions.
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/process/times_tags.txt

This file was deleted.

Expand Up @@ -26,7 +26,7 @@ public abstract class ProcessNodes {
public static final int CLOCK_MONOTONIC = 1;
public static final int CLOCK_REALTIME = 2;

@CoreMethod(names = "clock_gettime", isModuleFunction = true, required = 1, optional = 1)
@CoreMethod(names = "clock_gettime", onSingleton = true, required = 1, optional = 1)
public abstract static class ClockGetTimeNode extends CoreMethodNode {

private final RubySymbol floatSecondSymbol;
Expand Down Expand Up @@ -86,7 +86,7 @@ static boolean isRealtime(int clock_id) {

}

@CoreMethod(names = "kill", isModuleFunction = true, required = 2)
@CoreMethod(names = "kill", onSingleton = true, required = 2)
public abstract static class KillNode extends CoreMethodNode {

public KillNode(RubyContext context, SourceSection sourceSection) {
Expand Down Expand Up @@ -115,7 +115,7 @@ public int kill(RubySymbol signalName, int pid) {

}

@CoreMethod(names = "pid", isModuleFunction = true)
@CoreMethod(names = "pid", onSingleton = true)
public abstract static class PidNode extends CoreMethodNode {

public PidNode(RubyContext context, SourceSection sourceSection) {
Expand Down
Expand Up @@ -9,6 +9,8 @@
*/
package org.jruby.truffle.nodes.rubinius;

import jnr.constants.platform.Sysconf;
import jnr.posix.Times;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.BasicObjectNodes;
import org.jruby.truffle.nodes.core.BasicObjectNodesFactory;
Expand All @@ -21,13 +23,7 @@
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.ThrowException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyNilClass;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubyThread;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.signal.ProcSignalHandler;
import org.jruby.truffle.runtime.signal.SignalOperations;

Expand All @@ -38,6 +34,9 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

/**
* Rubinius primitives associated with the VM.
*/
Expand Down Expand Up @@ -360,6 +359,80 @@ public Object doThrow(Object tag, Object value) {

}

@RubiniusPrimitive(name = "vm_time", needsSelf = false)
public abstract static class TimeNode extends RubiniusPrimitiveNode {

public TimeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public TimeNode(TimeNode prev) {
super(prev);
}

@Specialization
public long time() {
return System.currentTimeMillis() / 1000;
}

}

@RubiniusPrimitive(name = "vm_times", needsSelf = false)
public abstract static class TimesNode extends RubiniusPrimitiveNode {

public TimesNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public TimesNode(TimesNode prev) {
super(prev);
}

@Specialization
public RubyArray times() {
// Copied from org/jruby/RubyProcess.java - see copyright and license information there

Times tms = getContext().getRuntime().getPosix().times();
double utime = 0.0d, stime = 0.0d, cutime = 0.0d, cstime = 0.0d;
if (tms == null) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
if(bean.isCurrentThreadCpuTimeSupported()) {
cutime = utime = bean.getCurrentThreadUserTime();
cstime = stime = bean.getCurrentThreadCpuTime() - bean.getCurrentThreadUserTime();
}
} else {
utime = (double)tms.utime();
stime = (double)tms.stime();
cutime = (double)tms.cutime();
cstime = (double)tms.cstime();
}

long hz = getContext().getRuntime().getPosix().sysconf(Sysconf._SC_CLK_TCK);
if (hz == -1) {
hz = 60; //https://github.com/ruby/ruby/blob/trunk/process.c#L6616
}

utime /= hz;
stime /= hz;
cutime /= hz;
cstime /= hz;

// TODO CS 24-Mar-15 what are these?
final double tutime = 0;
final double tstime = 0;

return new RubyArray(getContext().getCoreLibrary().getArrayClass(), new double[]{
utime,
stime,
cutime,
cstime,
tutime,
tstime
}, 6);
}

}

@SuppressWarnings("restriction")
@RubiniusPrimitive(name = "vm_watch_signal", needsSelf = false)
public static abstract class VMWatchSignalPrimitiveNode extends RubiniusPrimitiveNode {
Expand Down
Expand Up @@ -86,7 +86,7 @@ public class CoreLibrary {
private final RubyClass numericClass;
private final RubyClass objectClass;
private final RubyClass procClass;
private final RubyModule processModule;
private final RubyClass processClass;
private final RubyClass rangeClass;
private final RubyClass rangeErrorClass;
private final RubyClass rationalClass;
Expand Down Expand Up @@ -248,7 +248,6 @@ public CoreLibrary(RubyContext context) {
// SystemStackError
systemStackErrorClass = defineClass(exceptionClass, "SystemStackError");


// Create core classes and modules

numericClass = defineClass("Numeric");
Expand Down Expand Up @@ -276,7 +275,7 @@ public CoreLibrary(RubyContext context) {
defineClass("Mutex", MutexNodes.createMutexAllocator(context.getEmptyShape()));
nilClass = defineClass("NilClass");
procClass = defineClass("Proc", new RubyProc.ProcAllocator());
processModule = defineModule("Process");
processClass = defineClass("Process");
rangeClass = defineClass("Range", new RubyRange.RangeAllocator());
regexpClass = defineClass("Regexp", new RubyRegexp.RegexpAllocator());
stringClass = defineClass("String", new RubyString.StringAllocator());
Expand Down Expand Up @@ -415,8 +414,8 @@ private void initializeConstants() {
fileClass.setConstant(null, "PATH_SEPARATOR", RubyString.fromJavaString(stringClass, File.pathSeparator));
fileClass.setConstant(null, "FNM_SYSCASE", 0);

processModule.setConstant(null, "CLOCK_MONOTONIC", ProcessNodes.CLOCK_MONOTONIC);
processModule.setConstant(null, "CLOCK_REALTIME", ProcessNodes.CLOCK_REALTIME);
processClass.setConstant(null, "CLOCK_MONOTONIC", ProcessNodes.CLOCK_MONOTONIC);
processClass.setConstant(null, "CLOCK_REALTIME", ProcessNodes.CLOCK_REALTIME);
}

private void initializeSignalConstants() {
Expand Down
6 changes: 5 additions & 1 deletion truffle/src/main/ruby/core.rb
Expand Up @@ -29,6 +29,7 @@
require_relative 'core/rubinius/bootstrap/gc'
require_relative 'core/rubinius/bootstrap/kernel'
require_relative 'core/rubinius/bootstrap/nil'
require_relative 'core/rubinius/bootstrap/process'
require_relative 'core/rubinius/bootstrap/regexp'
require_relative 'core/rubinius/bootstrap/rubinius'
require_relative 'core/rubinius/bootstrap/string'
Expand Down Expand Up @@ -65,6 +66,7 @@
require_relative 'core/rubinius/common/string'
require_relative 'core/rubinius/common/range'
require_relative 'core/rubinius/common/struct'
require_relative 'core/rubinius/common/process'
require_relative 'core/rubinius/common/symbol'
require_relative 'core/rubinius/common/regexp'
require_relative 'core/rubinius/common/signal'
Expand All @@ -75,13 +77,15 @@
require_relative 'core/rubinius/common/time'
require_relative 'core/rubinius/common/true'
require_relative 'core/rubinius/common/random'

require_relative 'core/rubinius/common/rational'
require_relative 'core/rubinius/common/rationalizer'
require_relative 'core/rubinius/common/complex'
require_relative 'core/rubinius/common/complexifier'
require_relative 'core/rubinius/common/gc'

# Load delta (ordered according to Rubinius' load_order.txt)
require_relative 'core/rubinius/delta/struct'

# Load JRuby+Truffle classes
require_relative 'core/array'
require_relative 'core/fixnum'
Expand Down
39 changes: 39 additions & 0 deletions truffle/src/main/ruby/core/rubinius/bootstrap/process.rb
@@ -0,0 +1,39 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Only part of Rubinius' process.rb

class Process
def self.time
Rubinius.primitive :vm_time
raise PrimitiveFailure, "Process.time primitive failed"
end

def self.cpu_times
Rubinius.primitive :vm_times
raise PrimitiveFailure, "Process.cpu_times primitive failed"
end
end
35 changes: 35 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/process.rb
@@ -0,0 +1,35 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Only part of Rubinius' process.rb

class Process

def self.times
Struct::Tms.new(*cpu_times)
end

end
5 changes: 2 additions & 3 deletions truffle/src/main/ruby/core/rubinius/common/random.rb
Expand Up @@ -23,10 +23,9 @@
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

# Only part of Rubinius' random.rb
# Extracted from https://github.com/rubinius/rubinius/blob/v2.4.1/kernel/common/random.rb
#

class Rubinius::Randomizer

def initialize
Expand Down
43 changes: 43 additions & 0 deletions truffle/src/main/ruby/core/rubinius/delta/struct.rb
@@ -0,0 +1,43 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Only part of Rubinius' struct.rb

class Struct
Struct.new 'Tms', :utime, :stime, :cutime, :cstime, :tutime, :tstime

class Tms
def initialize(utime=nil, stime=nil, cutime=nil, cstime=nil,
tutime=nil, tstime=nil)
@utime = utime
@stime = stime
@cutime = cutime
@cstime = cstime
@tutime = tutime
@tstime = tstime
end
end
end

0 comments on commit 72536b3

Please sign in to comment.