Can NIF implementations use the regular C/C++ thread locking primitives or must they use the NIF APIs (enif_mutex_lock(..), enif_mutex_create(..),
etc.)

- 26,174
- 5
- 52
- 73

- 18,105
- 28
- 76
- 113
-
If it is any help to you, this is how `enif_mutex_lock()` is implemented: https://github.com/erlang/otp/blob/172e812c491680fbb175f56f7604d4098cdc9de4/erts/include/internal/ethr_mutex.h#L595. Looks like the thread is marked as being blocked. – Kijewski Nov 06 '14 at 06:53
-
Try writing a Port instead first -- most of the time you don't actually need a NIF. If you *must* write a NIF (and it should be a last resort) use the NIF APIs. Or *expect* your entire VM to go wonky because you got too clever. – zxq9 Nov 06 '14 at 08:57
-
@zxq9 From the official docs: "NIFs are simpler and more efficient way of calling C-code than using port drivers." – GabiMe Nov 06 '14 at 12:07
-
2@GabiMe And so it does. But as soon as you start talking about mutexes and locks and whatnot you totally blow away the purpose of the second bit: " NIFs are most suitable for synchronous functions like foo and bar in the example, that does some relatively short calculations without side effects and return the result." If this condition holds you don't need to worry about locking anything, and instead need to use ports. Meh... It will be a learning experience either way. – zxq9 Nov 06 '14 at 12:33
1 Answers
From nif docs
Threads and concurrency
A NIF is thread-safe without any explicit synchronization as long as it acts as a pure function and only reads the supplied arguments. As soon as you write towards a shared state either through static variables or enif_priv_data you need to supply your own explicit synchronization. This includes terms in process independent environments that are shared between threads. Resource objects will also require synchronization if you treat them as mutable.
So there is nothing forbidding you from doing whatever you want. You easily can write your own mutex/semafors and what not. And you can do it in C or C++ or Rust.
That said, there is nothing preventing from braking everything. If you break anything you break it in whole VM. I would try to use standard Erlang ways of doing things, especially while paling with threads. Those are verified methods, and I haven't found any reason for replacing them with anything else.

- 3,534
- 23
- 33
-
Ok, but why would Erlang provide the locking API in the first place? Is there any advantage in using it instead of regular locking? – GabiMe Nov 06 '14 at 11:54
-
Same reason C++ provides Lists and Vectors, so you wouldn't reimplement them, with potential bugs. There is some additional debugging information in Erlangs locks/mutexes. Other than that there are regular working locks (since irregular would not work, and there is not such thing as SuperLocks :) ). Other than that I agree with @zxq9 comments, if you wondering what should you use, use ports, and consider NIF's only when you **prove** inadequate. – mpm Nov 06 '14 at 15:12