Skip to content

Commit d997f0b

Browse files
committed
Change Primitive.thread_run_blocking_nfi_system_call to take an interop isExecutable object
* That way we avoid the overhead of the block, and profiling reports the properly named method, and not "block (2 levels) in POSIX.attach_function_eagerly". * Let Ruby code do the loop for more flexibility and to simplify.
1 parent f01379b commit d997f0b

File tree

4 files changed

+27
-43
lines changed

4 files changed

+27
-43
lines changed

lib/truffle/truffle/ffi_backend/function.rb

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,9 @@ def call(*args, &block)
8282
end
8383

8484
if blocking
85-
result = Primitive.thread_run_blocking_nfi_system_call -> {
86-
r = @function.call(*args)
87-
if Integer === r and r == -1 and Errno.errno == Errno::EINTR::Errno
88-
Truffle::UNDEFINED # retry
89-
else
90-
r
91-
end
92-
}
85+
begin
86+
result = Primitive.thread_run_blocking_nfi_system_call(@function, args)
87+
end while Integer === result and result == -1 and Errno.errno == Errno::EINTR::Errno
9388
else
9489
result = @function.call(*args)
9590
end

src/main/java/org/truffleruby/core/thread/ThreadNodes.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.truffleruby.core.InterruptMode;
6060
import org.truffleruby.core.VMPrimitiveNodes.VMRaiseExceptionNode;
6161
import org.truffleruby.core.array.ArrayGuards;
62+
import org.truffleruby.core.array.ArrayToObjectArrayNode;
6263
import org.truffleruby.core.array.RubyArray;
6364
import org.truffleruby.core.array.library.ArrayStoreLibrary;
6465
import org.truffleruby.core.basicobject.RubyBasicObject;
@@ -104,7 +105,6 @@
104105
import com.oracle.truffle.api.nodes.Node;
105106
import com.oracle.truffle.api.object.Shape;
106107
import com.oracle.truffle.api.profiles.BranchProfile;
107-
import com.oracle.truffle.api.profiles.LoopConditionProfile;
108108
import com.oracle.truffle.api.source.SourceSection;
109109

110110
@CoreModule(value = "Thread", isClass = true)
@@ -833,36 +833,30 @@ protected RubyBasicObject getFiberLocals(RubyThread thread) {
833833

834834
/** Similar to {@link ThreadManager#runUntilResult(Node, ThreadManager.BlockingAction)} but purposed for blocking
835835
* native calls. If the {@link SafepointManager} needs to interrupt the thread, it will send a SIGVTALRM to abort
836-
* the blocking syscall and the action will return NotProvided if the syscall fails with errno=EINTR, meaning it was
837-
* interrupted. */
836+
* the blocking syscall and the syscall will return -1 with errno=EINTR, meaning it was interrupted. */
838837
@Primitive(name = "thread_run_blocking_nfi_system_call")
839838
public static abstract class ThreadRunBlockingSystemCallNode extends PrimitiveArrayArgumentsNode {
840839

841840
@Specialization
842-
protected Object runBlockingSystemCall(RubyProc block,
843-
@Cached("createCountingProfile()") LoopConditionProfile loopProfile,
844-
@Cached YieldNode yieldNode) {
841+
protected Object runBlockingSystemCall(Object executable, RubyArray argsArray,
842+
@Cached GetCurrentRubyThreadNode getCurrentRubyThreadNode,
843+
@CachedLibrary(limit = "1") InteropLibrary receivers,
844+
@Cached ArrayToObjectArrayNode arrayToObjectArrayNode,
845+
@Cached TranslateInteropExceptionNode translateInteropExceptionNode) {
846+
final Object[] args = arrayToObjectArrayNode.executeToObjectArray(argsArray);
847+
final RubyThread thread = getCurrentRubyThreadNode.execute();
848+
845849
final ThreadManager threadManager = getContext().getThreadManager();
846850
final UnblockingAction unblockingAction = threadManager.getNativeCallUnblockingAction();
847-
final RubyThread thread = threadManager.getCurrentThread();
848851
final UnblockingActionHolder actionHolder = threadManager.getActionHolder(Thread.currentThread());
849852

850853
final UnblockingAction oldAction = actionHolder.changeTo(unblockingAction);
854+
final ThreadStatus status = thread.status;
855+
thread.status = ThreadStatus.SLEEP;
851856
try {
852-
Object result;
853-
do {
854-
final ThreadStatus status = thread.status;
855-
thread.status = ThreadStatus.SLEEP;
856-
857-
try {
858-
result = yieldNode.executeDispatch(block);
859-
} finally {
860-
thread.status = status;
861-
}
862-
} while (loopProfile.profile(result == NotProvided.INSTANCE));
863-
864-
return result;
857+
return InteropNodes.execute(executable, args, receivers, translateInteropExceptionNode);
865858
} finally {
859+
thread.status = status;
866860
actionHolder.restore(oldAction);
867861
}
868862
}

src/main/ruby/truffleruby/core/posix.rb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,9 @@ def self.attach_function_eagerly(native_name, argument_types, return_type,
139139
end
140140

141141
if blocking
142-
result = Primitive.thread_run_blocking_nfi_system_call -> {
143-
r = bound_func.call(*args)
144-
if Integer === r and r == -1 and Errno.errno == EINTR
145-
undefined # retry
146-
else
147-
r
148-
end
149-
}
142+
begin
143+
result = Primitive.thread_run_blocking_nfi_system_call(bound_func, args)
144+
end while Integer === result and result == -1 and Errno.errno == EINTR
150145
else
151146
result = bound_func.call(*args)
152147
end
@@ -316,6 +311,7 @@ def self.unsetenv(name)
316311
attach_function :dup3, [:int, :int, :int], :int
317312
end
318313

314+
SELECT = method(:truffleposix_select)
319315

320316
def self.with_array_of_ints(ints)
321317
if ints.empty?
@@ -514,5 +510,4 @@ class << self
514510
end
515511
end
516512
end
517-
518513
end

src/main/ruby/truffleruby/core/truffle/io_operations.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,12 @@ def self.select(readables, readable_ios, writables, writable_ios, errorables, er
145145
to_fds(errorable_ios, errorables_pointer)
146146

147147
begin
148-
primitive_result = Primitive.thread_run_blocking_nfi_system_call -> do
149-
Truffle::POSIX.truffleposix_select(readables.size, readables_pointer,
150-
writables.size, writables_pointer,
151-
errorables.size, errorables_pointer,
152-
remaining_timeout)
153-
end
148+
primitive_result = Primitive.thread_run_blocking_nfi_system_call(Truffle::POSIX::SELECT, [
149+
readables.size, readables_pointer,
150+
writables.size, writables_pointer,
151+
errorables.size, errorables_pointer,
152+
remaining_timeout
153+
])
154154

155155
result =
156156
if primitive_result < 0

0 commit comments

Comments
 (0)