# Turf: one C++ threading API, many backends underneath

> Turf is a configurable C++ platform adapter that defines a single API for threads, locks, atomics and timers, then implements it over POSIX, Win32, Mach, Linux, Boost and C++11, so you pick the backend at configure time rather than writing to whatever the platform gives you.

**preshing/turf** — Configurable C++ platform adapter

- Repository: https://github.com/preshing/turf
- Stars: 561 · Forks: 77
- Language: C++
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/preshing-turf

## What the abstraction actually covers

Turf is a configurable C++ platform adapter, and it defines a common API for a list of things that is worth reading as the list of things a concurrent data structure library actually needs. Thread creation is first. Then thread affinities, thread IDs, atomic operations, mutexes, condition variables, read-write locks, semaphores, events, timers, virtual memory, heap allocators and asserts. That list is the real specification of the project, and it tells you the intent: Turf is the layer a container or a lock-free structure sits on, and it is deliberately lower level than a task framework and higher level than the OS primitives themselves. Asserts being on that list is a small signal about the author's priorities, since an adapter that also carries the assertion helper is one that expects to be the bottom of your stack.

## The backends, and the point of being configurable

Turf then implements those things using POSIX, Win32, Mach, Linux, Boost, C++11 and possibly other platform APIs, and you configure Turf to use the API you want. That is the whole design in one sentence, and it is what separates Turf from a portability shim. A shim picks one implementation and hides the differences. Turf keeps several behind a switch, so the same source compiles against different primitives, and the project notes that Turf is configurable so you can compare implementations and even provide your own. That is the mode it is best suited to, and the one the author clearly had in mind, because a library like this is as much a benchmarking harness as it is a portability layer. A reader of the source can see what the same operation costs on each backend.

## Why not just use the standard library

The project answers this directly, and the reason is historical and practical rather than ideological. Junction was originally developed in C++11, but quickly ran into various limitations, and Turf was written to address those limitations. Four differences are listed. Turf exposes affinities, integer thread IDs, semaphores and a few other things that C++11 does not. Turf is configurable, so you can compare implementations and even provide your own, whereas the standard C++11 library is not configurable. Turf atomics have more flexible initialization, copy and cast rules than C++11 atomics. And Turf can be used by developers who do not have access to a C++11 compiler, which is the point that matters for the kind of project a portable adapter is often written for. The atomics rules are the subtlest of the four, because that is where the standard library was still settling when Turf was written.

## The consumer: Junction

Turf is used by Junction, a library of concurrent data structures in C++, and that relationship defines the scope of the project. Turf is not trying to be a general purpose portability layer for everything, it is the ground floor under one specific library of concurrent containers and synchronisation primitives. The practical consequence is that the API surface you will actually use is the subset Junction needs, and the practical benefit is that if you are working on Junction's data structures you do not have to care whether the platform underneath is POSIX threads, Win32 threads or Boost. The repository layout reflects the split, with a turf/ directory for the implementation, an extra/ directory, a samples/ directory and a CMakeLists.txt with a cmake/ directory alongside it.

## The samples, and what they are for

The samples directory is where the library's own tests of itself live, and the names describe the kind of verification they do. There is an AtomicTests directory, a RandomTest directory and a SynchroTests directory, so the suite covers the three areas the API spans, and a sample called AddSample.cmake showing how a new sample is wired into the build. The random test in particular is the interesting one, because concurrency primitives are the class of code where a passing deterministic test tells you very little, and a randomised test against a reference implementation is the standard way to get some confidence. The .clang-format file at the root tells you the project enforces a formatting style, which is the small signal that this is code intended to be read by other people.

## The licence, and the one obligation

Turf uses the Simplified BSD License, and the conditions are given plainly. You can use the source code freely in any project, including commercial applications, as long as you give credit by publishing the contents of the LICENSE file in your documentation somewhere. For a component that sits underneath your own libraries and therefore ends up in a lot of shipped binaries, that is a favourable position, and the credit requirement is easy to satisfy but easy to forget, since it is a documentation obligation rather than a notice in the source. The repository has a LICENSE file and a README, and the last push to the repository was on 2026-05-16, with the project publishing no GitHub releases, so there is no version stream to pin and you would be vendoring a specific commit.

## How to add it, and the feedback route

The integration instructions are not in Turf's own documentation, and the project says so: for now, refer to Junction's README for instructions. That is a reasonable arrangement when the two are released together, and it does mean you need to look in two places to get started. Feedback goes to GitHub issues on the Junction repository, or to the author directly through the contact form on his blog, and the project makes a point of saying that comments and feedback are welcome. The absence of an install section in Turf's own README also tells you something about the maturity of the project, which is a library that is stable enough to be depended on and small enough that the integration is a few lines in a parent project's build.

## Conclusion

Turf fits a C++ developer who wants one threading and synchronisation interface across platforms, or who wants to swap the implementation to compare two backends against each other, since the whole point is that the choice is made at configure time rather than hard coded. It does not fit a project that has already standardised on the standard library or on a mature third party library of concurrent data structures, because Turf is a layer over those rather than a replacement for them. It also does not fit a project that has no need to run on more than one platform, since the abstraction has a cost in indirection. Before you adopt it, read Junction's README for the actual integration instructions, because Turf's own documentation points there instead of repeating the steps, and decide which backend you want first, because that decision is the one the library is built to let you postpone.

## FAQ

### What does Turf abstract over?

It defines a common API for thread creation, thread affinities, thread IDs, atomic operations, mutexes, condition variables, read-write locks, semaphores, events, timers, virtual memory, heap allocators and asserts, then implements those over POSIX, Win32, Mach, Linux, Boost and C++11, with the backend chosen at configure time.

### Why was Turf written instead of using the C++11 standard library?

Because Junction was originally developed in C++11 and ran into limitations. Turf exposes affinities, integer thread IDs and semaphores that C++11 does not, is configurable so implementations can be compared or replaced, gives atomics more flexible initialization, copy and cast rules, and can be used by developers without a C++11 compiler.

### What is Turf used by?

It is used by Junction, a library of concurrent data structures in C++. Turf is the platform layer under that library rather than a general purpose portability shim, and its own documentation points at Junction's README for the integration steps.

### What licence does Turf use and what does it require?

The Simplified BSD Licence. The source can be used freely in any project, including commercial applications, as long as you give credit by publishing the contents of the LICENSE file somewhere in your documentation.

## Sources

- [Issues](https://github.com/preshing/turf/issues)
- [preshing/turf on GitHub](https://github.com/preshing/turf)
- [README](https://github.com/preshing/turf/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/preshing-turf
