world leader in high performance signal processing
Trace: » fixed-code

Atomic User Space Functions

The Blackfin ISA does not include any generally usable atomic instructions. While it does include a TESTSET instruction, there are some severe restrictions (and anomalies) that prevent it being used in general code.

As such, a software-only solution has been put together so that code running under Linux in user space can behave as if it has access to a variety of useful atomic functions. To be clear, this does not cover kernel code, or code running under other operating systems.

The types of atomic functions provided are exchange (xchg), compare and swap (cas), simple math (add/subtract), and binary operations (and/or/xor).


The atomic functions live in a specific memory address range (as documented in the ABI). When user space code needs to do an atomic operation, it calls the functions in this range. This code region is referred to as the fixed code region because the code lives at a fixed location.

If the user code happens to be interrupted by the kernel in the middle of one of these tiny functions, the kernel will automatically complete the function for the user code (register moves, data load/stores, etc…). This way, from the perspective of user space, the functions are always completed atomically. If the user code isn't interrupted by any asynchronous event, then the function completed atomically.

The atomic code is hand crafted to be as few instructions as possible so that the kernel rarely needs to do these modifications. However, when it does, it knows exactly which registers need to be changed, or which registers contain the memory addresses that need to be modified.

This check is placed at the end of the common interrupt return path. We see if the user space PC is in the middle of this atomic range. If it isn't, we continue on quickly (as this is the most common code path). If it is in the range, we perform further checks as necessary for each function. The base address is chosen because only code that is atomic should be executing below it (see the NULL pointer section in the Linux ABI).

Since these addresses are fixed in the Linux ABI, the toolchain uses them automatically when creating Linux applications.


Interrupt Return

file: arch/blackfin/mach-common/entry.S

scm failed with exit code 1:
file does not exist in git

Atomic Finisher

file: arch/blackfin/kernel/process.c

scm failed with exit code 1:
file does not exist in git

Fixed Code

file: arch/blackfin/kernel/fixed_code.S

scm failed with exit code 1:
file does not exist in git

Userspace Helpers

file: uClibc/libc/sysdeps/linux/bfin/bfin_fixed_code.h

scm failed with exit code 1:
file does not exist in git