9 Drivers

The run-time system will always take a lock before running
any code in a driver.

By default, that lock will be at the driver level, meaning that
if several ports have been opened to the same driver, only code for
one port at the same time can be running.

A driver can be configured to instead have one lock for each port.

If a driver is used in a functional way (i.e. it holds no state,
but only does some heavy calculation and returns a result), several
ports with registered names can be opened beforehand and the port to
be used can be chosen based on the scheduler ID like this:

There are basically two ways to avoid copying a binary that is
sent to a driver.

If the Data argument for
port_control/3
is a binary, the driver will be passed a pointer to the contents of
the binary and the binary will not be copied.
If the Data argument is an iolist (list of binaries and lists),
all binaries in the iolist will be copied.

Therefore, if you want to send both a pre-existing binary and some
additional data to a driver without copying the binary, you must call
port_control/3 twice; once with the binary and once with the
additional data. However, that will only work if there is only one
process communicating with the port (because otherwise another process
could call the driver in-between the calls).

Another way to avoid copying binaries is to implement an outputv
callback (instead of an output callback) in the driver.
If a driver has an outputv callback, refc binaries passed
in an iolist in the Data argument for
port_command/2
will be passed as references to the driver.

The run-time system can represent binaries up to 64 bytes as
heap binaries. They will always be copied when sent in a messages,
but they will require less memory if they are not sent to another
process and garbage collection is cheaper.

If you know that the binaries you return are always small,
you should use driver API calls that do not require a pre-allocated
binary, for instance
driver_output()
or
driver_output_term()
using the ERL_DRV_BUF2BINARY format,
to allow the run-time to construct a heap binary.