17

Where can I get a definitive answer, whether my memcpy (using the eglibc implementation that comes with Ubuntu) is thread safe? - Honestly, I really did not find a clear YES or NO in the docs.

By the way, with "thread safe" I mean it is safe to use memcpy concurrently whenever it would be safe to copy the date byte for byte concurrently. This should be possible at least if read-only data are copied to regions that do not overlap.

Ideally I would like to see something like the lists at the bottom of this page in the ARM compiler docs.

Damodaran
  • 10,882
  • 10
  • 60
  • 81
not-a-user
  • 4,088
  • 3
  • 21
  • 37
  • 1
    I would be confident that any kind of `memcpy()` would be thread-safe as I cannot imagine a need to use anything other than auto/stack variables. – trojanfoe Nov 14 '13 at 10:01
  • Check these links: **http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0492c/Chddjdaj.html** and **http://bytes.com/topic/c/answers/811064-malloc-function-provided-stdlib-h-thread-safe** –  Nov 14 '13 at 10:02
  • @trojanfoe what about two threads copying to a single heap buffer? The individual bytes may come from one copy or the other, but the entire copy may result in interleaving. That smells like a race condition to me. – Adam Nov 14 '13 at 10:07
  • 4
    @Adam Yes, that would cause a problem for sure, but is outside the scope of `memcpy()` being thread-safe or not. The caller would need to understand the consequences of doing this and provide the necessary exclusive access to the buffer. – trojanfoe Nov 14 '13 at 10:10
  • 1
    @trojanfoe - ....what? Have you done many, (any), multithreaded apps? – Martin James Nov 14 '13 at 10:30

3 Answers3

15

You can find that list here, at chapter 2.9.1 Thread-Safety : http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_01

That is, this is a list over functions that posix does not require to be thread safe. All other functions are required to be thread safe. Posix includes the standard C library and the typical "unix" interfaces. (Full list here, http://pubs.opengroup.org/onlinepubs/9699919799/functions/contents.html)

memcpy() is specified by posix, but not part of the list in 2.9.1, and can therefore be considered thread safe.

The various environments on linux at least tries to implement posix to the best of its abilities - The functions on linux/glibc might be thread-safe even if posix doesn't require it to be - though this is rarely documented. For other functions/libraries than what posix covers, you are left with what their authors have documented...

From what I can tell, posix equates thread safety with reentrancy, and guarantees there is no internal data races. You, however, are responsible for the possible external data races - such as protecting yourself from calling e.g. memcpy() with memory that might be updated concurrently.

nos
  • 223,662
  • 58
  • 417
  • 506
  • Perfect. You probably mean chapter 2.9.1 of http://pubs.opengroup.org/onlinepubs/9699919799/functions/contents.html. – not-a-user Nov 14 '13 at 10:21
5

It depends on the function, and how you use it.

Take for example memcpy, it is generally thread safe, if you copy data where both source and destination is private to a single thread. If you write to data that can be read from/written to by another thread, it's no longer thread safe and you have to protect the access.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • You are right, and I am searching for documentation on how to use which function to be thread-safe. - I know _what_ `memcpy` does and that it _should_ be thread safe from that point of view, but I do not know _how_ it does it. And it is more complicated for other functions. If the specification of a function seems to allow for a thread-safe implementation, it still all depends on the actual code. - I can easily write a `memcpy` that is working fine, but is not thread-safe. – not-a-user Nov 14 '13 at 10:14
  • 2
    @temple The functions that don't save any state between calls are thread safe. Why would e.g. `memcpy` save any state between calls? There's simply no reason for it. Random number generation, certain string functions, yes they need to save state between calls, that's why you have two variants of theses functions (with an `_r` appended to the name) that are reentrant. – Some programmer dude Nov 14 '13 at 10:18
  • 1
    All right, still I do not search for plausibility, but for a specification or documentation. – not-a-user Nov 14 '13 at 10:23
2

If a glibc function is not thread-safe then the man page will say so, and there will (most likely) be a thread safe variant also documented.

See, for example, man strtok:

SYNOPSIS #include

   char *strtok(char *str, const char *delim);

   char *strtok_r(char *str, const char *delim, char **saveptr);

The _r (for "reentrant") is the thread-safe variant.

Unfortunately, the man pages do not make a habit of stating that a function is thread safe, but only mention thread-safety when it is an issue.

As with all functions, if you give it a pointer to a shared resource then it will become thread-unsafe. It is up to you to handle locking.

ams
  • 24,923
  • 4
  • 54
  • 75
  • the `_r` functions are GNU specific, so not portable :sadface: (if that matters to you) – Sam Aug 06 '14 at 21:20