From: Alastair Bridgewater Date: Wed, 4 Aug 2010 17:58:15 +0000 (+0000) Subject: "1.0.41.2": threads: Add memory-barrier framework. X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=65b5ab7e713d04e0d76bc0ee196374f6e57b922f;p=sbcl.git "1.0.41.2": threads: Add memory-barrier framework. * New file, src/code/barrier.lisp, containing the baseline implementation. * Added the barrier functions to the compiler function database. * Export the interface macro, BARRIER, from SB!THREAD and the underlying barrier functions from SB!VM. * Document a new architecture-dependent build-time feature, MEMORY-BARRIER-VOPS, for controlling the behavior and inlining of the interpreter stubs for the barrier functions. --- diff --git a/base-target-features.lisp-expr b/base-target-features.lisp-expr index 7bd7caf..ca1e90c 100644 --- a/base-target-features.lisp-expr +++ b/base-target-features.lisp-expr @@ -390,6 +390,10 @@ ;; :compare-and-swap-vops ;; The backend implements compare-and-swap VOPs. ;; + ;; :memory-barrier-vops + ;; Memory barriers (for multi-threaded synchronization) have been + ;; implemented for this platform. + ;; ;; operating system features: ;; :unix = We're intended to run under some Unix-like OS. (This is not ;; exclusive with the features which indicate which particular diff --git a/build-order.lisp-expr b/build-order.lisp-expr index 3c55c3b..bacec9f 100644 --- a/build-order.lisp-expr +++ b/build-order.lisp-expr @@ -467,6 +467,9 @@ ;; This has ASSEMBLY-UNIT-related stuff needed by core.lisp. ("src/compiler/early-assem") + ;; This has the BARRIER stuff that the threading support needs. + ("src/code/barrier") + ;; core.lisp contains DEFSTRUCT CORE-OBJECT, and "compiler/main.lisp" ;; does lots of (TYPEP FOO 'CORE-OBJECT), so it's nice to compile this ;; before "compiler/main.lisp" so that those can be coded efficiently diff --git a/package-data-list.lisp-expr b/package-data-list.lisp-expr index 6cfd99f..fe2b4c4 100644 --- a/package-data-list.lisp-expr +++ b/package-data-list.lisp-expr @@ -1928,6 +1928,8 @@ is a good idea, but see SB-SYS re. blurring of boundaries." "THREAD-ALIVE-P" "THREAD-NAME" "THREAD-YIELD" + ;; Memory barrier + "BARRIER" ;; Mutexes "GET-MUTEX" "GRAB-MUTEX" @@ -2470,6 +2472,8 @@ structure representations" "*PRIMITIVE-OBJECTS*" "+HIGHEST-NORMAL-GENERATION+" "+PSEUDO-STATIC-GENERATION+" + "%COMPILER-BARRIER" "%DATA-DEPENDENCY-BARRIER" + "%MEMORY-BARRIER" "%READ-BARRIER" "%WRITE-BARRIER" "AFTER-BREAKPOINT-TRAP" "ANY-REG-SC-NUMBER" "ARRAY-DATA-SLOT" "ARRAY-DIMENSIONS-OFFSET" "ARRAY-DISPLACED-P-SLOT" "ARRAY-DISPLACEMENT-SLOT" diff --git a/src/code/barrier.lisp b/src/code/barrier.lisp new file mode 100644 index 0000000..80ff65c --- /dev/null +++ b/src/code/barrier.lisp @@ -0,0 +1,79 @@ +;;;; Support for memory barriers required for multithreaded operation + +;;;; This software is part of the SBCL system. See the README file for +;;;; more information. +;;;; +;;;; This software is derived from the CMU CL system, which was +;;;; written at Carnegie Mellon University and released into the +;;;; public domain. The software is in the public domain and is +;;;; provided with absolutely no warranty. See the COPYING and CREDITS +;;;; files for more information. + +(in-package "SB!THREAD") + + +;;;; Interpreter stubs for the various barrier functions + +#!-memory-barrier-vops +(declaim (inline sb!vm:%compiler-barrier sb!vm:%memory-barrier + sb!vm:%read-barrier sb!vm:%write-barrier + sb!vm:%data-dependency-barrier)) +(defun sb!vm:%compiler-barrier () + #!+memory-barrier-vops (sb!vm:%compiler-barrier) + (values)) +(defun sb!vm:%memory-barrier () + #!+memory-barrier-vops (sb!vm:%memory-barrier) + (values)) +(defun sb!vm:%read-barrier () + #!+memory-barrier-vops (sb!vm:%read-barrier) + (values)) +(defun sb!vm:%write-barrier () + #!+memory-barrier-vops (sb!vm:%write-barrier) + (values)) +(defun sb!vm:%data-dependency-barrier () + #!+memory-barrier-vops (sb!vm:%data-dependency-barrier) + (values)) + + +;;;; The actual barrier macro and support +(defparameter *barrier-kind-functions* + '(:compiler sb!vm:%compiler-barrier :memory sb!vm:%memory-barrier + :read sb!vm:%read-barrier :write sb!vm:%write-barrier + :data-dependency sb!vm:%data-dependency-barrier)) + +(defun barrier-kind-function (kind) + (or (getf *barrier-kind-functions* kind) + (error "Unknown barrier kind ~S" kind))) + +(defmacro barrier ((kind) &body forms) + "Insert a barrier in the code stream, preventing some sort of +reordering. + +KIND should be one of: + + :COMPILER + Prevent the compiler from reordering memory access across the + barrier. + :MEMORY + Prevent the cpu from reordering any memory access across the + barrier. + :READ + Prevent the cpu from reordering any read access across the + barrier. + :WRITE + Prevent the cpu from reordering any write access across the + barrier. + :DATA-DEPENDENCY + Prevent the cpu from reordering dependent memory reads across the + barrier (requiring reads before the barrier to complete before any + reads after the barrier that depend on them). This is a weaker + form of the :READ barrier. + +FORMS is an implicit PROGN, evaluated before the barrier. BARRIER +returns the values of the last form in FORMS. + +The file \"memory-barriers.txt\" in the Linux kernel documentation is +highly recommended reading for anyone programming at this level." + `(multiple-value-prog1 + (progn ,@forms) + (,(barrier-kind-function kind)))) diff --git a/src/compiler/fndb.lisp b/src/compiler/fndb.lisp index 410266a..dfb0dcd 100644 --- a/src/compiler/fndb.lisp +++ b/src/compiler/fndb.lisp @@ -1577,6 +1577,16 @@ ()) (defknown style-warn (t &rest t) null ()) + +;;;; memory barriers + +(defknown sb!vm:%compiler-barrier () (values) ()) +(defknown sb!vm:%memory-barrier () (values) ()) +(defknown sb!vm:%read-barrier () (values) ()) +(defknown sb!vm:%write-barrier () (values) ()) +(defknown sb!vm:%data-dependency-barrier () (values) ()) + + ;;;; atomic ops (defknown %compare-and-swap-svref (simple-vector index t t) t (unsafe)) diff --git a/version.lisp-expr b/version.lisp-expr index fbe8c50..3bda1f8 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.41.1" +"1.0.41.2"