Skip to content

Instantly share code, notes, and snippets.

View KJTsanaktsidis's full-sized avatar

KJ Tsanaktsidis KJTsanaktsidis

View GitHub Profile
#include <errno.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
int main_parent(pid_t child_pid) {
RUBY_T_MASK = 0x1f
RUBY_T_STRING = 0x05
RUBY_T_ARRAY = 0x07
RSTRING_EMBED_LEN_SHIFT = 0x0e
RSTRING_EMBED_LEN_MASK = 0x7c000
RSTRING_NOEMBED = 0x2000
RARRAY_EMBED_FLAG = 0x2000
RARRAY_EMBED_LEN_SHIFT = 0x0f
RARRAY_EMBED_LEN_MASK = 0x18000
RUBY_ID_SCOPE_SHIFT = 0x4
ruby 3.3.0dev (2023-03-14T07:07:59Z master ac65ce16e9) [aarch64-linux]
-------------- ----------- ---------- --------- ---------- ----------- ------------
bench interp (ms) stddev (%) yjit (ms) stddev (%) interp/yjit yjit 1st itr
activerecord 206.9 0.9 97.5 1.3 2.12 0.62
hexapdf 4940.6 1.0 2415.3 2.2 2.05 1.20
liquid-c 88.9 2.0 61.9 3.4 1.44 0.30
liquid-render 300.5 1.7 135.3 3.1 2.22 0.64
mail 209.0 0.6 104.6 3.7 2.00 0.32
psych-load 4474.7 0.3 1887.1 0.1 2.37 2.24
railsbench 2794.2 0.5 1544.4 1.5 1.81 0.74
ruby 3.3.0dev (2023-03-18T02:16:48Z ktsanaktsidis/yjit.. d09365c3b3) [aarch64-linux]
-------------- ----------- ---------- --------- ---------- ----------- ------------
bench interp (ms) stddev (%) yjit (ms) stddev (%) interp/yjit yjit 1st itr
activerecord 205.7 0.8 98.5 1.7 2.09 0.51
hexapdf 4967.0 0.8 2458.2 2.4 2.02 1.13
liquid-c 89.4 1.5 63.1 4.2 1.42 0.26
liquid-render 299.2 0.8 135.0 3.6 2.22 0.58
mail 208.0 0.5 105.5 4.8 1.97 0.29
psych-load 4492.7 0.1 1922.0 0.3 2.34 2.21
railsbench 2793.0 0.3 1556.0 1.5 1.80 0.70
(gdb) info threads
Id Target Id Frame
* 1 LWP 944671 of process 58279 _sigprocmask () at _sigprocmask.S:4
2 LWP 944703 of process 58279 "Timeout stdlib thre" thr_kill () at thr_kill.S:4
(gdb) bt
#0 _sigprocmask () at _sigprocmask.S:4
#1 0x000034cbaa077b44 in handle_signal (actp=actp@entry=0x34cba58367c0, sig=sig@entry=26, info=info@entry=0x34cba5836bb0, ucp=ucp@entry=0x34cba5836840) at /usr/src/lib/libthr/thread/thr_sig.c:288
#2 0x000034cbaa07711f in thr_sighandler (sig=26, info=0x0, _ucp=0x0) at /usr/src/lib/libthr/thread/thr_sig.c:246
#3 <signal handler called>
#4 _umtx_op_err () at /usr/src/lib/libthr/arch/amd64/amd64/_umtx_op_err.S:40
(gdb) info threads
Id Target Id Frame
* 1 LWP 100729 of process 15250 _umtx_op_err () at /usr/src/lib/libthr/arch/amd64/amd64/_umtx_op_err.S:40
2 LWP 105716 of process 15250 _umtx_op_err () at /usr/src/lib/libthr/arch/amd64/amd64/_umtx_op_err.S:40
(gdb) thread 1
[Switching to thread 1 (LWP 100729 of process 15250)]
#0 _umtx_op_err () at /usr/src/lib/libthr/arch/amd64/amd64/_umtx_op_err.S:40
40 in /usr/src/lib/libthr/arch/amd64/amd64/_umtx_op_err.S
(gdb) bt
#0 _umtx_op_err () at /usr/src/lib/libthr/arch/amd64/amd64/_umtx_op_err.S:40
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
Thread 1 locks the mutex
Thread 1 can get the resource
Thread 1 sleeps for a while ("sleep with resource #1")
Thread 2 tries to lock the mutex, gets put on the waitq
Thread 3 tries to lock the mutex, now the waitq is [2, 3]
Thread 1 returns the resource and unlocks the mutex
Thread 1 signals thread 2, since it's first on the waitq
Thread 2 is eligible for running now (according to ruby) but it's blocked waiting for the GVL
Thread 1 locks the mutex again
Thread 1 takes the resource again
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flame Graph</title>
<meta name="template_version" content="4.0.7"><script>!function(t){var n={};function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:r})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,n){if(1&n&&(t=e(t)),8&n)return t;if(4&n&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(e.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&n&&"string"!=typeof t)for(var i in t)e.d(r,i,function(n){return t[n]}.bind(null,i));return r},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,n){return Object.prototype.hasOwnProp
# frozen_string_literal: true
module TrapDetection
def trap(signal, action = nil, &block)
# A block might or might not be given, and action might be absent, a string, or
# a callable. It's actually legal to pass both action and block to Signal.trap, but
# in that case the block is ignored.
if action.respond_to?(:call)
action = Thunk.new(action)
end