Skip to content

Commit

Permalink
Merge pull request #90 from turbolent/threads
Browse files Browse the repository at this point in the history
Implement threads extension
  • Loading branch information
turbolent authored Nov 27, 2023
2 parents 4666cb1 + 7f824e6 commit 29ac02a
Show file tree
Hide file tree
Showing 117 changed files with 7,119 additions and 849 deletions.
135 changes: 52 additions & 83 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,69 +23,82 @@ jobs:
build: [release, debug]
threads: [true, false]
system:
- { target: gcc, cc: gcc, }
- { target: clang, cc: clang, }
- { target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static }
- { target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm-static }
- { target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static }
- { target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64-static }
- { target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static }
- { target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static }
- { target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x-static }
- { target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static }
- { target: gcc, cc: gcc }
- { target: clang, cc: clang }
- { target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static, linkAtomic: true }
- { target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm-static }
- { target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static }
- { target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64-static, linkAtomic: true }
- { target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static, linkAtomic: true }
- { target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static }
- { target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x-static }
- { target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static }

# Architectures with expected failures (mostly due to FP issues, e.g. NaN representation, conversion, arithemtic)
- { target: i386, toolchain: gcc-multilib, cc: clang -m32, qemu: qemu-i386-static }
- { target: hppa, toolchain: gcc-hppa-linux-gnu, cc: hppa-linux-gnu-gcc, qemu: qemu-hppa-static }
- { target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips-static }
- { target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel-static }
- { target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static }
- { target: mips64el, toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc, qemu: qemu-mips64el-static }
- { target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static }
- { target: i386, toolchain: gcc-multilib, cc: clang -m32, qemu: qemu-i386-static, linkAtomic: true }
- { target: hppa, toolchain: gcc-hppa-linux-gnu, cc: hppa-linux-gnu-gcc, qemu: qemu-hppa-static }
- { target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips-static, linkAtomic: true }
- { target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel-static, linkAtomic: true }
- { target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static }
- { target: mips64el, toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc, qemu: qemu-mips64el-static }
- { target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static }

# Disabled due to miscompilation or qemu issues (?)
# - { target: sh4, toolchain: gcc-sh4-linux-gnu, cc: sh4-linux-gnu-gcc, qemu: qemu-sh4-static }
# - { target: sparc64, toolchain: gcc-sparc64-linux-gnu, cc: sparc64-linux-gnu-gcc, qemu: qemu-sparc64-static }
# - { target: sh4, toolchain: gcc-sh4-linux-gnu, cc: sh4-linux-gnu-gcc, qemu: qemu-sh4-static }
# - { target: sparc64, toolchain: gcc-sparc64-linux-gnu, cc: sparc64-linux-gnu-gcc, qemu: qemu-sparc64-static }

# Disabled due to too large `switch'-statement
# - { target: m68k, toolchain: gcc-m68k-linux-gnu, cc: m68k-linux-gnu-gcc, qemu: qemu-m68k-static }
# - { target: m68k, toolchain: gcc-m68k-linux-gnu, cc: m68k-linux-gnu-gcc, qemu: qemu-m68k-static }

env:
CC: ${{ matrix.system.cc }}

steps:
- uses: actions/checkout@v3

- name: Install QEMU
if: ${{ matrix.system.qemu }}
run: |
sudo apt update
sudo apt install qemu-user-static
- name: Install ${{ matrix.system.toolchain }}
if: ${{ matrix.system.toolchain }}
run: |
sudo apt install ${{ matrix.system.toolchain }}
- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
w2c2:
- 'w2c2/**'
- 'futex/**'
- 'tests/**'
wasi:
- 'wasi/**'
- if: steps.changes.outputs.w2c2 == 'true'
name: Build w2c2
env:
LDFLAGS: -static
working-directory: ./w2c2
run: make BUILD=${{ matrix.build }} FEATURES="unistd libgen getopt glob ${{ matrix.threads && 'threads' || '' }}"

- if: steps.changes.outputs.w2c2 == 'true'
name: Build futex
working-directory: ./futex
run: make BUILD=${{ matrix.build }}

- if: steps.changes.outputs.w2c2 == 'true'
name: Run w2c2 tests
name: Run WebAssembly tests
env:
LDFLAGS: -static
LDFLAGS: -static ${{ matrix.system.linkAtomic && '-latomic' || '' }}
ARCH: ${{ matrix.system.target }}
working-directory: ./tests
shell: bash
run: make run-tests

- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
Expand All @@ -103,85 +116,40 @@ jobs:

steps:
- uses: actions/checkout@v3

- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
w2c2:
- 'w2c2/**'
- 'futex/**'
- 'tests/**'
wasi:
- 'wasi/**'
- if: steps.changes.outputs.w2c2 == 'true'
name: Build w2c2
working-directory: ./w2c2
run: make BUILD=${{ matrix.build }} FEATURES="unistd libgen getopt glob ${{ matrix.threads && 'threads' || '' }}"

- if: steps.changes.outputs.w2c2 == 'true'
name: Run tests
working-directory: ./tests
shell: bash
name: Build futex
working-directory: ./futex
run: make BUILD=${{ matrix.build }}

- if: steps.changes.outputs.w2c2 == 'true'
name: Run WebAssembly tests
env:
ARCH: ${{ matrix.system.target }}
working-directory: ./tests
shell: bash
run: make run-tests

- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
run: make BUILD=${{ matrix.build }} FEATURES="unistd sysuio systime sysresource strndup fcntl timespec lstat"

# Disabled due to sqrt issues
#
# windows-mingw:
# runs-on: windows-latest
# name: "Windows (mingw), ${{ matrix.system.target }} (build=${{ matrix.build }}, threads=${{ matrix.threads }})"
#
# strategy:
# fail-fast: false
# matrix:
# build: [release, debug]
# threads: [true, false]
# system:
# - { target: mingw64, env: x86_64 }
# - { target: mingw32, env: i686 }
#
# defaults:
# run:
# shell: msys2 {0}
#
# env:
# CC: gcc
#
# steps:
# - uses: actions/checkout@v3
# - uses: msys2/setup-msys2@v2
# with:
# msystem: ${{ matrix.system.target }}
# install: >-
# make
# gcc
# - uses: dorny/paths-filter@v2
# id: changes
# with:
# filters: |
# w2c2:
# - 'w2c2/**'
# wasi:
# - 'wasi/**'
# - if: steps.changes.outputs.w2c2 == 'true'
# name: Build w2c2
# env:
# LDFLAGS: -static
# working-directory: ./w2c2
# run: make BUILD=${{ matrix.build }} FEATURES="getopt ${{ matrix.threads && 'threads' || '' }}"
# - if: steps.changes.outputs.w2c2 == 'true'
# name: Run tests
# working-directory: ./tests
# shell: bash
# env:
# ARCH: ${{ matrix.system.target }}
# run: make run-tests
# - if: steps.changes.outputs.wasi == 'true'
# name: Build wasi
# working-directory: ./wasi
# run: make BUILD=${{ matrix.build }}
run: make BUILD=${{ matrix.build }} FEATURES="unistd sysuio systime sysresource strndup fcntl timespec lstat pthreads"

windows-msvc:
runs-on: windows-2019
Expand All @@ -197,13 +165,14 @@ jobs:
- 'w2c2/**'
wasi:
- 'wasi/**'
- if: steps.changes.outputs.w2c2 == 'true'
name: Build w2c2
working-directory: ./w2c2
run: |
cmake -Bbuild
cmake --build build
# TODO: run tests
- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
Expand Down
101 changes: 54 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ Working towards [WebAssembly as the Elusive Universal Binary](https://kripken.gi

## Features

- Implements the [WebAssembly Core Specification 1.0](https://www.w3.org/TR/wasm-core-1/), as well as
- Implements the [WebAssembly Core Specification 1.0](https://www.w3.org/TR/wasm-core-1/)
- Implements several extensions:
- [Threads and atomics](https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md)
- [Bulk memory operations](https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md)
- [Conditional data segment initialization](https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md)
- [Sign-extension operators](https://github.com/WebAssembly/sign-extension-ops/blob/master/proposals/sign-extension-ops/Overview.md)
- [Non-trapping Float-to-int Conversions](https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md)
- [Non-trapping float-to-int conversions](https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md)
- Passes 99.9% of the WebAssembly core semantics test suite
- Written in C89 and generates C89
- Support for many operating systems (e.g. Mac OS X, Mac OS 9, Haiku, Rhapsody, OPENSTEP, NeXTSTEP, DOS, Windows XP, etc.)
Expand All @@ -35,7 +38,10 @@ Working towards [WebAssembly as the Elusive Universal Binary](https://kripken.gi
- Function names, if function names are provided in the [`names` custom section](https://webassembly.github.io/spec/core/appendix/custom.html#function-names)
- Source line mapping, if DWARF line information is provided in the [`.debug_line` custom section](https://yurydelendik.github.io/webassembly-dwarf/).
Requires [libdwarf](https://github.com/davea42/libdwarf-code) to be installed. See instructions below.
- WASI implementation which is able to run clang and Python
- WASI implementation
- Able to run clang and Python
- Support for many operating systems and architectures, support for big-endian systems
- Implements the [threads proposal](https://github.com/webAssembly/wasi-threads)

## Performance

Expand Down Expand Up @@ -116,50 +122,51 @@ make run-tests

## WASI Status

- [x] args_get
- [x] args_sizes_get
- [x] clock_res_get
- [x] clock_time_get
- [x] environ_get
- [x] environ_sizes_get
- [ ] fd_advise
- [ ] fd_allocate
- [x] fd_close
- [x] fd_datasync
- [x] fd_fdstat_get
- [ ] fd_fdstat_set_flags
- [ ] fd_fdstat_set_rights
- [x] fd_filestat_get
- [ ] fd_filestat_set_size
- [ ] fd_filestat_set_times
- [x] fd_pread
- [x] fd_prestat_get
- [x] fd_prestat_dir_name
- [x] fd_pwrite
- [x] fd_read
- [x] fd_readdir
- [ ] fd_renumber
- [x] fd_seek
- [x] fd_sync
- [x] fd_tell
- [x] fd_write
- [x] path_create_directory
- [x] path_filestat_get
- [ ] path_filestat_set_times
- [ ] path_link
- [x] path_open
- [x] path_readlink
- [x] path_remove_directory
- [x] path_rename
- [x] path_symlink
- [x] path_unlink_file
- [ ] poll_oneoff
- [x] proc_exit
- [x] random_get
- [ ] sched_yield
- [ ] sock_recv
- [ ] sock_send
- [ ] sock_shutdown
- [x] `args_get`
- [x] `args_sizes_get`
- [x] `clock_res_get`
- [x] `clock_time_get`
- [x] `environ_get`
- [x] `environ_sizes_get`
- [ ] `fd_advise`
- [ ] `fd_allocate`
- [x] `fd_close`
- [x] `fd_datasync`
- [x] `fd_fdstat_get`
- [ ] `fd_fdstat_set_flags`
- [ ] `fd_fdstat_set_rights`
- [x] `fd_filestat_get`
- [ ] `fd_filestat_set_size`
- [ ] `fd_filestat_set_times`
- [x] `fd_pread`
- [x] `fd_prestat_get`
- [x] `fd_prestat_dir_name`
- [x] `fd_pwrite`
- [x] `fd_read`
- [x] `fd_readdir`
- [ ] `fd_renumber`
- [x] `fd_seek`
- [x] `fd_sync`
- [x] `fd_tell`
- [x] `fd_write`
- [x] `path_create_directory`
- [x] `path_filestat_get`
- [ ] `path_filestat_set_times`
- [ ] `path_link`
- [x] `path_open`
- [x] `path_readlink`
- [x] `path_remove_directory`
- [x] `path_rename`
- [x] `path_symlink`
- [x] `path_unlink_file`
- [ ] `poll_oneoff`
- [x] `proc_exit`
- [x] `random_get`
- [ ] `sched_yield`
- [ ] `sock_recv`
- [ ] `sock_send`
- [ ] `sock_shutdown`
- [x] `thread-spawn` (from the [threads proposal](https://github.com/webAssembly/wasi-threads))

## Development

Expand Down
22 changes: 22 additions & 0 deletions examples/threads/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
LDFLAGS += -lm -L../../wasi -lw2c2wasi -L../../futex -lw2c2futex
CFLAGS += -O0 -g
W2C2 ?= ../../w2c2/w2c2

ifeq ($(OS),Windows_NT)
CFLAGS += -DWASM_THREADS_WIN32
else
CFLAGS += -pthread -DWASM_THREADS_PTHREADS
endif

threads: threads.o main.o
$(CC) $^ -o threads $(LDFLAGS)

%.c: src/%.wasm
$(W2C2) -g $< $@

%.o: %.c
$(CC) -I../../w2c2 -c $(CFLAGS) $< -o $@

.PHONY: clean
clean:
rm -f *.o threads threads.h
Loading

0 comments on commit 29ac02a

Please sign in to comment.