{"size": 1962, "ext": "scrbl", "max_stars_repo_path": "share/pkgs/racket-doc/scribblings/reference/memory-order.scrbl", "max_stars_repo_name": "takikawa/racket-ppa", "max_stars_repo_stars_event_min_datetime": "2018-07-29T04:13:52.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-14T16:11:17.000Z", "max_issues_repo_path": "share/pkgs/racket-doc/scribblings/reference/memory-order.scrbl", "max_issues_repo_name": "takikawa/racket-ppa", "max_issues_repo_issues_event_min_datetime": "2017-08-25T20:26:37.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-26T17:48:40.000Z", "max_forks_repo_path": "share/pkgs/racket-doc/scribblings/reference/memory-order.scrbl", "max_forks_repo_name": "takikawa/racket-ppa", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 10, "max_issues_count": 15, "max_forks_count": null, "avg_line_length": 43.6, "max_line_length": 69, "alphanum_fraction": 0.7818552497}
#lang scribble/doc
@(require "mz.rkt"
          (for-label racket/unsafe/ops))

@title[#:tag "memory-order"]{Machine Memory Order}

Unlike Racket @tech{threads}, futures and places can expose the
underlying machine's memory model, including a weak memory ordering.
For example, when a future writes to multiple slots in a mutable
vector, it's possible on some platforms for another future to observe
the writes in a different order or not at all, unless the futures are
explicitly synchronized. Similarly, shared byte strings or
@tech{fxvectors} can expose the machine's memory model across places.

Racket ensures that a machine's memory model is not observed in a way
that unsafely exposes the implementation of primitive datatypes. For
example, it is not possible for one future to see a partially
constructed primitive value as a result of reading a vector that is
mutated by another future.

The @racket[box-cas!], @racket[vector-cas!],
@racket[unsafe-box*-cas!], @racket[unsafe-vector*-cas!], and
@racket[unsafe-struct*-cas!] operations all provide a machine-level
compare-and-set, so they can be used in ways that are specifically
supported by the a machine's memory model. The
@racket[(memory-order-acquire)] and @racket[(memory-order-release)]
operations similarly constrain machine-level stores and loads.
Synchronization operations such as place messages, future
@racket[touch]es, and @tech{future semaphores} imply suitable
machine-level acquire and release ordering.

@deftogether[(
@defproc[(memory-order-acquire) void?]
@defproc[(memory-order-release) void?]
)]{

Those operations implement a machine-level memory fence on platforms
where one is needed for synchronization. The
@racket[memory-order-acquire] operation ensures at least a load--load
and load--store fence at the machine level, and the
@racket[memory-order-release] operation ensures at least a
store--store and store--load fence at the machine level.

@history[#:added "7.7.0.11"]}
