restrict
has nothing to do with thread safety. In fact, the existing C standards have nothing to say on the topic of threads at all; from the point of view of the spec, there is no such thing as a "thread".
restrict
is a way to inform the compiler about aliasing. Pointers often make it hard for the compiler to generate efficient code, because the compiler cannot know at compile time whether two pointers actually refer to the same memory. Toy example:
void foo(int *x, int *y) {
*x = 5;
*y = 7;
printf("%d\n", *x);
}
When the compiler processes this function, it has no idea whether x
and y
refer to the same memory location. Therefore it does not know whether it will print 5
or 7
, and it has to emit code to actually read *x
before calling printf
.
But if you declare x
as int *restrict x
, the compiler can prove that this function prints 5
, so it can feed a compile-time constant to the printf
call.
Many such optimizations become possible with restrict
, especially when you are talking about operations on arrays.
But none of this has anything to do with threads. To get multi-treading applications right, you need proper synchronization primitives like mutexes, condition variables, and memory barriers... All of which are specific to your platform, and none of which have anything to do with restrict
.
[edit]
To answer your question about using restrict
as a form of documentation, I would say "no" to that, also.
You seem to be thinking that you should document when a variable can or cannot be concurrently accessed. But for shared data, the proper discipline is (almost always) to ensure that it is never concurrently accessed.
The relevant documentation for a variable is whether it is shared at all and which mutex protects it. Any code accessing that variable for any reason, even just to read it, needs to hold the mutex. The author should neither know nor care whether some other thread might or might not happen to be accessing the variable concurrently... Because that other thread will be obeying the same discipline, and the mutex guarantees there is no concurrent access.
This discipline is simple, it works, and it scales, which is why it is one of the dominant paradigms for sharing data between threads. (The other is message passing.) If you ever find yourself trying to reason "do I really need to lock the mutex this time?", you are almost certainly doing something wrong. It would be hard to overstate this point.