FreeBSD Platform Patches for J Source

These patches fix platform-specific issues when running J on FreeBSD. While J officially supports FreeBSD, some functionality requires adjustments for proper operation on this platform.


BLAS Library Selection (libblis)

Patch: libblis-build.patch

What It Does

Changes the BLAS library J links against on FreeBSD from OpenBLAS to BLIS (BLAS-like Library Instantiation Software).

Why?

FreeBSD’s pkg system provides BLIS as a readily available, well-optimized BLAS implementation. While OpenBLAS is also available, it fails to build correctly on modern FreeBSD.

Technical Details

The change modifies jsrc/cblas.c to use libblis.so instead of libopenblas.so.0:

// Before:
#elif defined(__FreeBSD__)
#define LIBCBLASNAME "libopenblas.so.0"

// After:
#elif defined(__FreeBSD__)
#define LIBCBLASNAME "libblis.so"

J dynamically loads the BLAS library at runtime for matrix operations. This change simply updates the library name that J searches for.

Prerequisites

Install BLIS on FreeBSD:

pkg install blis

Applying the Patch

cd /path/to/jsource
git apply libblis-build.patch

Delay Function CPU Fix (6!:3)

Patch: delay-cpu-fix.patch

What It Does

Fixes the 6!:3 (delay) foreign function to properly sleep without consuming 100% CPU on FreeBSD.

The Problem

Before this patch, executing a delay in J would consume an entire CPU core:

6!:3 (5)   NB. Sleep for 5 seconds - was using 100% CPU!

This occurred because the futex-based sleep implementation had two bugs:

  1. Wrong wait value: The futex wait was checking for waitval|1 instead of waitval, causing the wait to return immediately
  2. Premature exit: The loop was breaking on timeout instead of recalculating remaining time and continuing

Technical Details

The fix modifies jsrc/mt.c in the jtjsleep function:

// Bug 1 - Wrong comparison value:
// Before:
I i=jfutex_waitn(&ftx,waitval|1,MIN(ns,1000000000));

// After:
I i=jfutex_waitn(&ftx,waitval,MIN(ns,1000000000));

// Bug 2 - Premature exit on timeout:
// Before:
if(i==-1){r=0;break;} //timed out

// After:
if(i==-1){goto retime;} //timed out - recalculate remaining time and continue

How J’s Delay Works

J’s delay function uses a futex (fast userspace mutex) for efficient sleeping:

  1. The function calculates a target wake time
  2. It enters a loop that waits on a futex with a 1-second maximum timeout
  3. On each iteration, it checks for system locks and break signals
  4. On timeout, it recalculates remaining time and continues (the fix)
  5. The loop exits when the target time is reached or a break occurs

This design allows delays to be interruptible (you can press Ctrl+C) while still being efficient.

Impact

Metric Before After
CPU usage during 6!:3 (1) ~100% <1%
Delay accuracy Correct Correct
Interruptibility Yes Yes

Applying the Patch

cd /path/to/jsource
git apply delay-cpu-fix.patch

Applying All FreeBSD Patches

To apply both FreeBSD patches at once:

cd /path/to/jsource
git am /path/to/freebsd-platform/*/*.patch

Or apply them individually in any order (they are independent).