This commit is contained in:
2026-07-20 13:19:11 -05:00
parent 27833003ce
commit 7a4ca7eca7
4 changed files with 57 additions and 12 deletions
+10
View File
@@ -111,6 +111,16 @@ jobs:
run: | run: |
make "${{ matrix.target }}" make "${{ matrix.target }}"
file "dist/fossbench-${{ matrix.target }}.exe" file "dist/fossbench-${{ matrix.target }}.exe"
if [ "${{ matrix.target }}" = windows-i386 ]; then
pe="dist/fossbench-windows-i386.exe"
i686-w64-mingw32-objdump -p "$pe" > "$RUNNER_TEMP/windows-i386-pe.txt"
grep -Eq 'MajorSubsystemVersion[[:space:]]+5' "$RUNNER_TEMP/windows-i386-pe.txt"
grep -Eq 'MinorSubsystemVersion[[:space:]]+1' "$RUNNER_TEMP/windows-i386-pe.txt"
if grep -Eq 'GetTickCount64|InitializeCriticalSectionEx|CreateThreadpool|WaitOnAddress' "$RUNNER_TEMP/windows-i386-pe.txt"; then
echo 'Windows i386 release imports an API newer than Windows XP' >&2
exit 1
fi
fi
- name: Package artifact - name: Package artifact
run: | run: |
+7 -1
View File
@@ -118,6 +118,12 @@ endif
# Windows uses MinGW. # Windows uses MinGW.
CC_WINDOWS_AMD64 ?= x86_64-w64-mingw32-gcc CC_WINDOWS_AMD64 ?= x86_64-w64-mingw32-gcc
CC_WINDOWS_I386 ?= i686-w64-mingw32-gcc CC_WINDOWS_I386 ?= i686-w64-mingw32-gcc
# Keep the 32-bit executable loadable by the Windows XP loader and prevent the
# SDK headers from exposing APIs newer than XP. The code uses native Win32
# threads on Windows, so this target does not acquire a libwinpthread runtime
# dependency with a newer OS baseline.
WINDOWS_I386_XP_CFLAGS := -D_WIN32_WINNT=0x0501 -DWINVER=0x0501 -DNTDDI_VERSION=0x05010000
WINDOWS_I386_XP_LDFLAGS := -Wl,--major-subsystem-version,5,--minor-subsystem-version,1
NATIVE_BIN := $(DIST)/fossbench-$(OSNAME)-$(HOST_ARCHNAME) NATIVE_BIN := $(DIST)/fossbench-$(OSNAME)-$(HOST_ARCHNAME)
@@ -185,7 +191,7 @@ $(DIST)/fossbench-windows-amd64.exe: $(DRIVER) $(DRIVER_DEPS) $(ASM_AMD64) | $(D
@echo "built $@" @echo "built $@"
$(DIST)/fossbench-windows-i386.exe: $(DRIVER) $(DRIVER_DEPS) $(ASM_I386) | $(DIST) $(DIST)/fossbench-windows-i386.exe: $(DRIVER) $(DRIVER_DEPS) $(ASM_I386) | $(DIST)
$(CC_WINDOWS_I386) -march=pentium4 $(CFLAGS) $(PTHREAD) -static -o $@ $(DRIVER) $(ASM_I386) -lm -lwinhttp -ladvapi32 $(CC_WINDOWS_I386) -march=pentium4 $(WINDOWS_I386_XP_CFLAGS) $(CFLAGS) -static $(WINDOWS_I386_XP_LDFLAGS) -o $@ $(DRIVER) $(ASM_I386) -lm -lwinhttp -ladvapi32
@echo "built $@" @echo "built $@"
# Add a native rule if one was not already made above. # Add a native rule if one was not already made above.
+4 -3
View File
@@ -32,12 +32,13 @@ score weights. Version 0.1 and 0.2 scores are not comparable.
| PowerPC 32-bit, little-endian | scalar fallback with runtime-selected extensions | | PowerPC 32-bit, little-endian | scalar fallback with runtime-selected extensions |
| PowerPC 64-bit, little-endian | POWER8 with AltiVec/VSX | | PowerPC 64-bit, little-endian | POWER8 with AltiVec/VSX |
Linux, macOS, and Windows are supported. Send a patch if a supported target Linux, macOS, and Windows are supported. The Windows i386 release has a Windows
fails. XP (NT 5.1) compatibility baseline. Send a patch if a supported target fails.
## Build ## Build
GNU Make, a C compiler, pthreads, and the system math library are required. GNU Make, a C compiler, and the system math library are required. POSIX builds
also require pthreads; Windows builds use native Win32 threads.
Uploads use plain HTTP and require no TLS library. Uploads use plain HTTP and require no TLS library.
Build for the current machine: Build for the current machine:
+36 -8
View File
@@ -4,10 +4,19 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <pthread.h>
#include <unistd.h>
#include <ctype.h> #include <ctype.h>
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <tlhelp32.h>
# include <winhttp.h>
# include <process.h>
#else
# include <pthread.h>
# include <unistd.h>
#endif
#include "benchmark.h" #include "benchmark.h"
#include "hw_detect.h" #include "hw_detect.h"
#if defined(__linux__) #if defined(__linux__)
@@ -60,10 +69,6 @@
/* Get the current time. */ /* Get the current time. */
#if defined(_WIN32) #if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <tlhelp32.h>
# include <winhttp.h>
static double now_seconds(void) static double now_seconds(void)
{ {
LARGE_INTEGER f, t; LARGE_INTEGER f, t;
@@ -574,19 +579,28 @@ struct job {
uint64_t result; uint64_t result;
}; };
#if defined(_WIN32)
static unsigned WINAPI job_entry(void *arg)
#else
static void *job_entry(void *arg) static void *job_entry(void *arg)
#endif
{ {
struct job *j = arg; struct job *j = arg;
j->result = j->run(j->n, j->ws); j->result = j->run(j->n, j->ws);
return NULL; return 0;
} }
/* Run a kernel on all requested threads. */ /* Run a kernel on all requested threads. */
static uint64_t dispatch(run_fn run, uint64_t n, int threads) static uint64_t dispatch(run_fn run, uint64_t n, int threads)
{ {
struct job *jobs = xalloc((size_t)threads * sizeof *jobs); struct job *jobs = xalloc((size_t)threads * sizeof *jobs);
#if defined(_WIN32)
HANDLE *tids = threads > 1
? xalloc((size_t)(threads - 1) * sizeof *tids) : NULL;
#else
pthread_t *tids = threads > 1 pthread_t *tids = threads > 1
? xalloc((size_t)(threads - 1) * sizeof *tids) : NULL; ? xalloc((size_t)(threads - 1) * sizeof *tids) : NULL;
#endif
int i, spawned = 0; int i, spawned = 0;
uint64_t agg = 0; uint64_t agg = 0;
@@ -596,16 +610,30 @@ static uint64_t dispatch(run_fn run, uint64_t n, int threads)
jobs[i].ws = &g_ws[i]; jobs[i].ws = &g_ws[i];
} }
for (i = 1; i < threads; i++) { for (i = 1; i < threads; i++) {
#if defined(_WIN32)
tids[spawned] = (HANDLE)_beginthreadex(NULL, 0, job_entry, &jobs[i], 0, NULL);
if (tids[spawned] != NULL)
spawned++;
else
job_entry(&jobs[i]); /* Run it here if the thread fails. */
#else
if (pthread_create(&tids[spawned], NULL, job_entry, &jobs[i]) == 0) if (pthread_create(&tids[spawned], NULL, job_entry, &jobs[i]) == 0)
spawned++; spawned++;
else else
job_entry(&jobs[i]); /* Run it here if the thread fails. */ job_entry(&jobs[i]); /* Run it here if the thread fails. */
#endif
} }
job_entry(&jobs[0]); /* The main thread does the first job. */ job_entry(&jobs[0]); /* The main thread does the first job. */
for (i = 0; i < spawned; i++) for (i = 0; i < spawned; i++) {
#if defined(_WIN32)
WaitForSingleObject(tids[i], INFINITE);
CloseHandle(tids[i]);
#else
pthread_join(tids[i], NULL); pthread_join(tids[i], NULL);
#endif
}
for (i = 0; i < threads; i++) for (i = 0; i < threads; i++)
agg += jobs[i].result; agg += jobs[i].result;