This patch adds support for the SIGINFO signal on BSD systems
(FreeBSD, OpenBSD, macOS). Pressing Ctrl+T while J is
running displays status information about the current execution,
following the same convention used by other BSD utilities like
dd, cp, and sleep.
Patch: siginfo.patch
When you press Ctrl+T during a long-running J computation, jconsole displays a single-line status showing:
running,
idle, or reentrant[ATTN] or
[BREAK] if an interrupt is pendingjconsole: running, 2.5s 1.0G (depth 1)
jconsole: idle, 45.2s 512.0K (depth 0)
jconsole: running myfunc in /tmp/test.ijs:5, 3m02s 2.1G (depth 3)
jconsole: idle, 1.2s 703.5K/1.0G hwm:128.7M (depth 0)
jconsole: [ATTN] running, 10.5s 4.2G (depth 2, 4 threads)
| Component | Description | Example |
|---|---|---|
| State | Current execution state | running, idle |
| Verb | Currently executing verb name | myfunc |
| Location | Script file and line | in /tmp/test.ijs:5 |
| Uptime | Session duration | 2.5s, 3m02s |
| Memory | Current usage | 1.0G, 512.0K |
| Limit | Memory limit (if set via 9!:21) |
/1.0G |
| HWM | High water mark (if >10% above current) | hwm:128.7M |
| Depth | Call stack depth | (depth 3) |
| Threads | Thread count (if >1) | 4 threads |
| Interrupt | Pending interrupt indicator | [ATTN], [BREAK] |
On BSD systems, SIGINFO is a standard mechanism for querying process status. Many Unix utilities support it:
This patch brings J in line with BSD conventions, making it easy to check on long-running computations without interrupting them.
The handler is registered alongside the existing SIGINT handler in
jsrc/jconsole.c:
#if defined(SIGINFO)
signal(SIGINFO, siginfo_handler);
#endifThe #if defined(SIGINFO) guard ensures the code only
compiles on systems that support SIGINFO (BSD variants). On Linux and
Windows, this code is simply not included.
Signal handlers must be async-signal-safe, meaning they can only call certain reentrant functions. This handler:
write() instead of printf() for
outputsnprintf() to format strings into stack
buffersMemory usage is read from J’s internal tracking:
I memused = jm->malloctotal + jm->malloctotalremote;
I memhwm = jm->malloctotalhwmk; // high water mark
I memlimit = jst->mmax; // allocation limitThe limit is only displayed if explicitly set (via
9!:21) to something smaller than the default maximum.
The handler accesses J’s internal structures to gather status information:
jm->recurstate — Execution state
(running/idle/reentrant)jm->curname — Currently executing verb namejm->sitop — Debug stack for script location and call
depthjm->currslistx — Index into script list for current
filejst->adbreak — Pending interrupt flagjst->tssbase — Session start timestampjst->wthreadhwmk — Number of worker threads +/ i. 5e9 NB. Sum of first 5 billion integersWhile this runs, press Ctrl+T:
jconsole: running, 2.0s 64.0G (depth 1)
9!:21 (1e9) NB. Set 1GB memory limit
+/ i. 1e7Press Ctrl+T after the computation:
jconsole: idle, 0.8s 703.5K/1.0G hwm:128.7M (depth 0)
This shows current usage (703.5K), the limit (1.0G), and the peak usage during the computation (128.7M).
slowfn =: 3 : '+/ i. y'
slowfn 1e8Press Ctrl+T:
jconsole: running slowfn, 1.5s 1.0G (depth 2)
| Platform | Supported |
|---|---|
| FreeBSD | Yes |
| OpenBSD | Yes |
| macOS | Yes |
| Linux | No (SIGINFO not available) |
| Windows | No (SIGINFO not available) |
On unsupported platforms, the patch has no effect — the code is simply not compiled.
cd /path/to/jsource
git apply siginfo.patchThen rebuild jconsole:
cd make2
./build_jconsole.shThe patch only modifies jsrc/jconsole.c and does not
affect libj or other components.
9!:21 — Set memory allocation
limit7!:1 — Query current memory usage6!:3 — Delay (sleep) function