From 57c3246511434f42214e113b8902af10ab9cca49 Mon Sep 17 00:00:00 2001 From: xsipewe Date: Tue, 21 Jun 2016 15:50:34 +0200 Subject: erts: Editorial changes --- erts/doc/src/erl_nif.xml | 3692 ++++++++++++++++++++++++++-------------------- 1 file changed, 2092 insertions(+), 1600 deletions(-) (limited to 'erts/doc/src/erl_nif.xml') diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index 8ed042f6f9..d154a1bd21 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -33,43 +33,52 @@ erl_nif.xml erl_nif - API functions for an Erlang NIF library + API functions for an Erlang NIF library.

A NIF library contains native implementation of some functions - of an Erlang module. The native implemented functions (NIFs) are - called like any other functions without any difference to the - caller. Each NIF must also have an implementation in Erlang that - will be invoked if the function is called before the NIF library - has been successfully loaded. A typical such stub implementation - is to throw an exception. But it can also be used as a fallback - implementation if the NIF library is not implemented for some - architecture.

- -

Use this functionality with extreme care!

+ of an Erlang module. The native implemented functions (NIFs) are + called like any other functions without any difference to the + caller. Each NIF must have an implementation in Erlang that + is invoked if the function is called before the NIF library + is successfully loaded. A typical such stub implementation + is to throw an exception. But it can also be used as a fallback + implementation if the NIF library is not implemented for some + architecture.

+ + + +

Use this functionality with extreme care.

A native function is executed as a direct extension of the - native code of the VM. Execution is not made in a safe environment. - The VM can not provide the same services as provided when - executing Erlang code, such as preemptive scheduling or memory - protection. If the native function doesn't behave well, the whole - VM will misbehave.

- -

A native function that crash will crash the whole VM.

-

An erroneously implemented native function might cause - a VM internal state inconsistency which may cause a crash of the VM, - or miscellaneous misbehaviors of the VM at any point after the call - to the native function.

-

A native function that do lengthy - work before returning will degrade responsiveness of the VM, - and may cause miscellaneous strange behaviors. Such strange behaviors - include, but are not limited to, extreme memory usage, and bad load - balancing between schedulers. Strange behaviors that might occur due - to lengthy work may also vary between OTP releases.

+ native code of the VM. Execution is not made in a safe environment. + The VM cannot provide the same services as provided when + executing Erlang code, such as pre-emptive scheduling or memory + protection. If the native function does not behave well, the whole + VM will misbehave.

+ + +

A native function that crash will crash the whole VM.

+
+ +

An erroneously implemented native function can cause a VM + internal state inconsistency, which can cause a crash of the VM, + or miscellaneous misbehaviors of the VM at any point after the + call to the native function.

+
+ +

A native function doing lengthy + work before returning degrades responsiveness of the VM, + and can cause miscellaneous strange behaviors. Such strange + behaviors include, but are not limited to, extreme memory usage, + and bad load balancing between schedulers. Strange behaviors that + can occur because of lengthy work can also vary between Erlang/OTP + releases.

+
-
+
+ +

A minimal example of a NIF library can look as follows:

-

A minimal example of a NIF library can look like this:

-

- + /* niftest.c */ #include "erl_nif.h" @@ -83,13 +92,11 @@ static ErlNifFunc nif_funcs[] = {"hello", 0, hello} }; -ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL) - +ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL) -

and the Erlang module would have to look something like - this:

-

- +

The Erlang module can look as follows:

+ + -module(niftest). -export([init/0, hello/0]). @@ -98,11 +105,11 @@ init() -> erlang:load_nif("./niftest", 0). hello() -> - "NIF library not loaded". - -

and compile and test something like this (on Linux):

-

- + "NIF library not loaded". + +

Compile and test can look as follows (on Linux):

+ + $> gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/ $> erl @@ -113,290 +120,310 @@ $> erl 3> niftest:init(). ok 4> niftest:hello(). -"Hello world!" - - -

A better solution for a real module is to take advantage of - the new directive on_load to automatically - load the NIF library when the module is loaded.

-

A NIF does not have to be exported, it can be local to the module. - Note however that unused local stub functions will be optimized - away by the compiler causing loading of the NIF library to fail.

+"Hello world!"
+ +

A better solution for a real module is to take advantage of the new + directive on load (see section + Running a + Function When a Module is Loaded in the Erlang Reference + Manual) to load the NIF library automatically when the module is + loaded.

+ + +

A NIF does not have to be exported, it can be local to the module. + However, unused local stub functions will be optimized + away by the compiler, causing loading of the NIF library to fail.

-

A loaded NIF library is tied to the Erlang module code version - that loaded it. If the module is upgraded with a new version, the - new Erlang code will have to load its own NIF library (or maybe choose not - to). The new code version can however choose to load the exact - same NIF library as the old code if it wants to. Sharing the same - dynamic library will mean that static data defined by the library - will be shared as well. To avoid unintentionally shared static - data, each Erlang module code can keep its own private data. This - private data can be set when the NIF library is loaded and - then retrieved by calling enif_priv_data.

-

There is no way to explicitly unload a NIF library. A library will be - automatically unloaded when the module code that it belongs to is purged - by the code server.

- +

A loaded NIF library is tied to the Erlang module code version + that loaded it. If the module is upgraded with a new version, the + new Erlang code need to load its own NIF library (or maybe choose not + to). The new code version can, however, choose to load the + same NIF library as the old code if it wants to. Sharing the + dynamic library means that static data defined by the library + is shared as well. To avoid unintentionally shared static + data, each Erlang module code can keep its own private data. This + private data can be set when the NIF library is loaded and + then retrieved by calling + enif_priv_data.

+ +

A NIF library cannot be loaded explicitly. A library is + automatically unloaded when the module code that it belongs to is purged + by the code server.

+
- FUNCTIONALITY -

All functions that a NIF library needs to do with Erlang are - performed through the NIF API functions. There are functions + Functionality +

All functions that a NIF library needs to do with Erlang are + performed through the NIF API functions. Functions exist for the following functionality:

+ Read and write Erlang terms -

Any Erlang terms can be passed to a NIF as function arguments and - be returned as function return values. The terms are of C-type - ERL_NIF_TERM - and can only be read or written using API functions. Most functions to read - the content of a term are prefixed enif_get_ and usually return - true (or false) if the term was of the expected type (or not). - The functions to write terms are all prefixed enif_make_ and usually - return the created ERL_NIF_TERM. There are also some functions - to query terms, like enif_is_atom, enif_is_identical and - enif_compare.

-

All terms of type ERL_NIF_TERM belong to an environment of type - ErlNifEnv. The lifetime of a term is - controlled by the lifetime of its environment object. All API functions that read - or write terms has the environment, that the term belongs to, as the first - function argument.

+ +

Any Erlang terms can be passed to a NIF as function arguments and + be returned as function return values. The terms are of C-type + ERL_NIF_TERM and can + only be read or written using API functions. Most functions to read + the content of a term are prefixed enif_get_ and usually return + true (or false) if the term is of the expected type (or + not). The functions to write terms are all prefixed enif_make_ + and usually + return the created ERL_NIF_TERM. There are also some functions + to query terms, like enif_is_atom, enif_is_identical, + and enif_compare.

+

All terms of type ERL_NIF_TERM belong to an environment of + type ErlNifEnv. The + lifetime of a term is controlled by the lifetime of its environment + object. All API functions that read or write terms has the + environment that the term belongs to as the first function + argument.

+
Binaries -

Terms of type binary are accessed with the help of the struct type - ErlNifBinary - that contains a pointer (data) to the raw binary data and the length - (size) of the data in bytes. Both data and size are - read-only and should only be written using calls to API functions. - Instances of ErlNifBinary are however always allocated by the user - (usually as local variables).

-

The raw data pointed to by data is only mutable after a call to - enif_alloc_binary or - enif_realloc_binary. - All other functions that operates on a binary will leave the data as read-only. - A mutable binary must in the end either be freed with - enif_release_binary - or made read-only by transferring it to an Erlang term with - enif_make_binary. - But it does not have to happen in the same NIF call. Read-only binaries - do not have to be released.

-

enif_make_new_binary - can be used as a shortcut to allocate and return a binary in the same NIF call.

-

Binaries are sequences of whole bytes. Bitstrings with an arbitrary - bit length have no support yet.

-
+ +

Terms of type binary are accessed with the help of struct type + ErlNifBinary, + which contains a pointer (data) to the raw binary data and the + length (size) of the data in bytes. Both data and + size are read-only and are only to be written using calls to + API functions. Instances of ErlNifBinary are, however, always + allocated by the user (usually as local variables).

+

The raw data pointed to by data is only mutable after a call + to + enif_alloc_binary or + + enif_realloc_binary. All other functions that + operate on a binary leave the data as read-only. + A mutable binary must in the end either be freed with + + enif_release_binary + or made read-only by transferring it to an Erlang term with + enif_make_binary. + However, it does not have to occur in the same NIF call. Read-only + binaries do not have to be released.

+

+ enif_make_new_binary can be used as a shortcut to + allocate and return a binary in the same NIF call.

+

Binaries are sequences of whole bytes. Bitstrings with an arbitrary + bit length have no support yet.

+
Resource objects -

The use of resource objects is a safe way to return pointers to - native data structures from a NIF. A resource object is - just a block of memory allocated with - enif_alloc_resource. - A handle ("safe pointer") to this memory block can then be returned to Erlang by the use of - enif_make_resource. - The term returned by enif_make_resource - is totally opaque in nature. It can be stored and passed between processes - on the same node, but the only real end usage is to pass it back as an argument to a NIF. - The NIF can then call enif_get_resource - and get back a pointer to the memory block that is guaranteed to still be - valid. A resource object will not be deallocated until the last handle term - has been garbage collected by the VM and the resource has been - released with enif_release_resource - (not necessarily in that order).

-

All resource objects are created as instances of some resource type. - This makes resources from different modules to be distinguishable. - A resource type is created by calling - enif_open_resource_type - when a library is loaded. Objects of that resource type can then later be allocated - and enif_get_resource verifies that the resource is of the expected type. - A resource type can have a user supplied destructor function that is - automatically called when resources of that type are released (by either - the garbage collector or enif_release_resource). Resource types - are uniquely identified by a supplied name string and the name of the - implementing module.

-

Here is a template example of how to create and return a resource object.

-

- - ERL_NIF_TERM term; - MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct)); - - /* initialize struct ... */ - - term = enif_make_resource(env, obj); - - if (keep_a_reference_of_our_own) { - /* store 'obj' in static variable, private data or other resource object */ - } - else { - enif_release_resource(obj); - /* resource now only owned by "Erlang" */ - } - return term; - -

Note that once enif_make_resource creates the term to - return to Erlang, the code can choose to either keep its own - native pointer to the allocated struct and release it later, or - release it immediately and rely solely on the garbage collector - to eventually deallocate the resource object when it collects - the term.

-

Another usage of resource objects is to create binary terms with - user defined memory management. - enif_make_resource_binary - will create a binary term that is connected to a resource object. The - destructor of the resource will be called when the binary is garbage - collected, at which time the binary data can be released. An example of - this can be a binary term consisting of data from a mmap'ed file. - The destructor can then do munmap to release the memory - region.

-

Resource types support upgrade in runtime by allowing a loaded NIF - library to takeover an already existing resource type and thereby - "inherit" all existing objects of that type. The destructor of the new - library will thereafter be called for the inherited objects and the - library with the old destructor function can be safely unloaded. Existing - resource objects, of a module that is upgraded, must either be deleted - or taken over by the new NIF library. The unloading of a library will be - postponed as long as there exist resource objects with a destructor - function in the library. -

+ +

The use of resource objects is a safe way to return pointers to + native data structures from a NIF. A resource object is + only a block of memory allocated with + + enif_alloc_resource. + A handle ("safe pointer") to this memory block can then be returned + to Erlang by the use of + + enif_make_resource. + The term returned by enif_make_resource is opaque in nature. + It can be stored and passed between processes on the same node, but + the only real end usage is to pass it back as an argument to a NIF. + The NIF can then call + enif_get_resource and get back a pointer to the + memory block, which is guaranteed to still be valid. A resource + object is not deallocated until the last handle term + is garbage collected by the VM and the resource is released with + + enif_release_resource + (not necessarily in that order).

+

All resource objects are created as instances of some resource + type. This makes resources from different modules to be + distinguishable. A resource type is created by calling + + enif_open_resource_type when a library is loaded. + Objects of that resource type can then later be allocated and + enif_get_resource verifies that the resource is of the + expected type. A resource type can have a user-supplied destructor + function, which is automatically called when resources of that type + are released (by either the garbage collector or + enif_release_resource). Resource types are uniquely identified + by a supplied name string and the name of the implementing module.

+ +

The following is a template example of how to create and return a + resource object.

+ +ERL_NIF_TERM term; +MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct)); + +/* initialize struct ... */ + +term = enif_make_resource(env, obj); + +if (keep_a_reference_of_our_own) { + /* store 'obj' in static variable, private data or other resource object */ +} +else { + enif_release_resource(obj); + /* resource now only owned by "Erlang" */ +} +return term; +

Notice that once enif_make_resource creates the term to + return to Erlang, the code can choose to either keep its own + native pointer to the allocated struct and release it later, or + release it immediately and rely only on the garbage collector + to deallocate the resource object eventually when it collects + the term.

+

Another use of resource objects is to create binary terms with + user-defined memory management. + + enif_make_resource_binary + creates a binary term that is connected to a resource object. The + destructor of the resource is called when the binary is garbage + collected, at which time the binary data can be released. An example + of this can be a binary term consisting of data from a mmap'ed + file. The destructor can then do munmap to release the memory + region.

+

Resource types support upgrade in runtime by allowing a loaded NIF + library to take over an already existing resource type and by that + "inherit" all existing objects of that type. The destructor of the + new library is thereafter called for the inherited objects and the + library with the old destructor function can be safely unloaded. + Existing resource objects, of a module that is upgraded, must either + be deleted or taken over by the new NIF library. The unloading of a + library is postponed as long as there exist resource objects with a + destructor function in the library.

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.

-

The library initialization callbacks load, reload and - upgrade are all thread-safe even for shared state data.

+ +

A NIF is thread-safe without any explicit synchronization as + long as it acts as a pure function and only reads the supplied + arguments. When you write to 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 also + require synchronization if you treat them as mutable.

+

The library initialization callbacks load, reload, and + upgrade are all thread-safe even for shared state data.

- Version Management -

- When a NIF library is built, information about NIF API version - is compiled into the library. When a NIF library is loaded the - runtime system verifies that the library is of a compatible version. - erl_nif.h defines ERL_NIF_MAJOR_VERSION, and - ERL_NIF_MINOR_VERSION. ERL_NIF_MAJOR_VERSION will be - incremented when NIF library incompatible changes are made to the - Erlang runtime system. Normally it will suffice to recompile the NIF - library when the ERL_NIF_MAJOR_VERSION has changed, but it - could, under rare circumstances, mean that NIF libraries have to - be slightly modified. If so, this will of course be documented. - ERL_NIF_MINOR_VERSION will be incremented when - new features are added. The runtime system uses the minor version - to determine what features to use. -

- The runtime system will normally refuse to load a NIF library if - the major versions differ, or if the major versions are equal and - the minor version used by the NIF library is greater than the one - used by the runtime system. Old NIF libraries with lower major - versions will however be allowed after a bump of the major version - during a transition period of two major releases. Such old NIF - libraries might however fail if deprecated features are used. -

- + +

When a NIF library is built, information about the NIF API version + is compiled into the library. When a NIF library is loaded, the + runtime system verifies that the library is of a compatible version. + erl_nif.h defines the following:

+ + ERL_NIF_MAJOR_VERSION + +

Incremented when NIF library incompatible changes are made to the + Erlang runtime system. Normally it suffices to recompile the NIF + library when the ERL_NIF_MAJOR_VERSION has changed, but it + can, under rare circumstances, mean that NIF libraries must be + slightly modified. If so, this will of course be documented.

+
+ ERL_NIF_MINOR_VERSION + +

Incremented when new features are added. The runtime system uses + the minor version to determine what features to use.

+
+
+

The runtime system normally refuses to load a NIF library if + the major versions differ, or if the major versions are equal and + the minor version used by the NIF library is greater than the one + used by the runtime system. Old NIF libraries with lower major + versions are, however, allowed after a bump of the major version + during a transition period of two major releases. Such old NIF + libraries can however fail if deprecated features are used.

+
Time Measurement -

Support for time measurement in NIF libraries:

- - ErlNifTime - ErlNifTimeUnit - enif_monotonic_time() - enif_time_offset() - enif_convert_time_unit() + +

Support for time measurement in NIF libraries:

+ + + ErlNifTime + + ErlNifTimeUnit + + enif_monotonic_time() + + enif_time_offset() + + enif_convert_time_unit()
- Long-running NIFs - -

- As mentioned in the warning text at - the beginning of this document it is of vital importance that a - native function return relatively quickly. It is hard to give an exact - maximum amount of time that a native function is allowed to work, but as a - rule of thumb a well-behaving native function should return to its caller - before a millisecond has passed. This can be achieved using different - approaches. If you have full control over the code to execute in the - native function, the best approach is to divide the work into multiple - chunks of work and call the native function multiple times. In some - cases this might however not always be possible, e.g. when calling - third-party libraries.

- -

The - enif_consume_timeslice() - function can be used to inform the runtime system about the length of the - NIF call. It should typically always be used unless the NIF executes very - quickly.

- -

If the NIF call is too lengthy one needs to handle this in one of the - following ways in order to avoid degraded responsiveness, scheduler load - balancing problems, and other strange behaviors:

- - - Yielding NIF - -

- If the functionality of a long-running NIF can be split so that - its work can be achieved through a series of shorter NIF calls, - the application can either make that series of NIF calls from the - Erlang level, or it can call a NIF that first performs a chunk of - the work, then invokes the - enif_schedule_nif - function to schedule another NIF call to perform the next chunk. - The final call scheduled in this manner can then return the - overall result. Breaking up a long-running function in - this manner enables the VM to regain control between calls to the - NIFs. -

-

- This approach is always preferred over the other alternatives - described below. This both from a performance perspective and - a system characteristics perspective. -

-
- - Threaded NIF - -

- This is accomplished by dispatching the work to another thread - managed by the NIF library, return from the NIF, and wait for the - result. The thread can send the result back to the Erlang - process using enif_send. - Information about thread primitives can be found below. -

-
- - Dirty NIF - - - -

- The dirty NIF functionality described here - is experimental. Dirty NIF support is available only when - the emulator is configured with dirty schedulers enabled. This - feature is currently disabled by default. The Erlang runtime - without SMP support do not support dirty schedulers even when - the dirty scheduler support has been enabled. To check at - runtime for the presence of dirty scheduler threads, code can - use the - enif_system_info() - API function. -

-
- -

- A NIF that cannot be split and cannot execute in a millisecond or - less is called a "dirty NIF" because it performs work that the - ordinary schedulers of the Erlang runtime system cannot handle cleanly. - Applications that make use of such functions must indicate to the - runtime that the functions are dirty so they can be handled - specially. This is handled by executing dirty jobs on a separate + +

As mentioned in the warning text + at the beginning of this manual page, it is of vital + importance that a native function returns relatively fast. It is + difficult to give an exact maximum amount of time that a native + function is allowed to work, but usually a well-behaving native + function is to return to its caller within 1 millisecond. This can be + achieved using different approaches. If you have full control over the + code to execute in the native function, the best approach is to + divide the work into multiple chunks of work and call the native + function multiple times. This is, however, not always possible, for + example when calling third-party libraries.

+

The + enif_consume_timeslice() function can be used to + inform the runtime system about the length of the NIF call. + It is typically always to be used unless the NIF executes very + fast.

+

If the NIF call is too lengthy, this must be handled in one of + the following ways to avoid degraded responsiveness, scheduler load + balancing problems, and other strange behaviors:

+ + Yielding NIF + +

If the functionality of a long-running NIF can be split so that + its work can be achieved through a series of shorter NIF calls, + the application has two options:

+ + +

Make that series of NIF calls from the Erlang level.

+
+ +

Call a NIF that first performs a chunk of the work, then + invokes the + enif_schedule_nif function to schedule + another NIF call to perform the next chunk. The final call + scheduled in this manner can then return the overall + result.

+
+
+

Breaking up a long-running function in this manner enables the + VM to regain control between calls to the NIFs.

+

This approach is always preferred over the other alternatives + described below. This both from a performance perspective and + a system characteristics perspective.

+
+ Threaded NIF + +

This is accomplished by dispatching the work to another thread + managed by the NIF library, return from the NIF, and wait for + the result. The thread can send the result back to the Erlang + process using + enif_send. + Information about thread primitives is provided below.

+
+ Dirty NIF + + +

The dirty NIF functionality described here + is experimental. Dirty NIF support is available only when + the emulator is configured with dirty schedulers enabled. This + feature is disabled by default. The Erlang runtime + without SMP support does not support dirty schedulers even when + the dirty scheduler support is enabled. To check at runtime for + the presence of dirty scheduler threads, code can use the + + enif_system_info() API function.

+
+

A NIF that cannot be split and cannot execute in a millisecond + or less is called a "dirty NIF", as it performs work that the + ordinary schedulers of the Erlang runtime system cannot handle cleanly. + Applications that make use of such functions must indicate to the + runtime that the functions are dirty so they can be handled + specially. This is handled by executing dirty jobs on a separate set of schedulers called dirty schedulers. A dirty NIF executing on a dirty scheduler does not have the same duration restriction as a normal NIF. -

- -

- It is important to classify the dirty job correct. An I/O bound +

+

+ It is important to classify the dirty job correct. An I/O bound job should be classified as such, and a CPU bound job should be classified as such. If you should classify CPU bound jobs as I/O bound jobs, dirty I/O schedulers might starve ordinary @@ -404,1240 +431,1636 @@ ok for I/O, and/or spend a limited amount of time moving data.

-

- To schedule a dirty NIF for execution, the appropriate - flags value can be set for the NIF in its - ErlNifFunc - entry, or the application can call - enif_schedule_nif, - passing to it a pointer to the dirty NIF to be executed and - indicating with the flags argument whether it expects the - operation to be CPU-bound or I/O-bound. A job that alternates - between I/O bound and CPU bound can be reclassified and - rescheduled using enif_schedule_nif so that it executes on - the correct type of dirty scheduler at all times. For more - information see the documentation of the erl command line - arguments +SDcpu, - and +SDio. -

- -

- While a process is executing a dirty NIF some operations that - communicate with it may take a very long time to complete. - Suspend, or garbage collection of a process executing a dirty - NIF cannot be done until the dirty NIF has returned, so other - processes waiting for such operations to complete might have to - wait for a very long time. Blocking multi scheduling, i.e., - calling - erlang:system_flag(multi_scheduling, - block), might also take a very long time to - complete. This since all ongoing dirty operations on all - dirty schedulers need to complete before the block - operation can complete. -

-

- A lot of operations communicating with a process executing a - dirty NIF can, however, complete while it is executing the - dirty NIF. For example, retrieving information about it via - process_info(), setting its group leader, - register/unregister its name, etc. -

-

- Termination of a process executing a dirty NIF can only be - completed up to a certain point while it is executing the - dirty NIF. All Erlang resources such as its registered name, - its ETS tables, etc will be released. All links and monitors - will be triggered. The actual execution of the NIF will - however not be stopped. The NIF can safely continue - execution, allocate heap memory, etc, but it is of course better - to stop executing as soon as possible. The NIF can check - whether current process is alive or not using - enif_is_current_process_alive. - Communication using - enif_send, - and enif_port_command - will also be dropped when the sending process is not alive. - Deallocation of certain internal resources such as process - heap, and process control block will be delayed until the - dirty NIF has completed. -

-

Currently known issues that are planned to be fixed:

- - -

- Since purging of a module currently might need to garbage - collect a process in order to determine if it has - references to the module, a process executing a dirty - NIF might delay purging for a very long time. Delaying - a purge operation implies delaying all code - loading operations which might cause severe problems for - the system as a whole. -

-
-
- -
-
- +

+ To schedule a dirty NIF for execution, the application has two options:

+ + +

Set the appropriate flags value for the dirty NIF in its + ErlNifFunc + entry.

+
+ +

Call + enif_schedule_nif, pass to it a pointer + to the dirty NIF to be executed, and indicate with argument + flags whether it expects the operation to be CPU-bound + or I/O-bound.

+
+
+

A job that alternates between I/O bound and CPU bound can be + reclassified and rescheduled using enif_schedule_nif so + that it executes on the correct type of dirty scheduler at all + times. For more information see the documentation of the + erl command line arguments + +SDcpu, + and +SDio.

+

While a process executes a dirty NIF, some operations that + communicate with it can take a very long time to complete. + Suspend or garbage collection of a process executing a dirty + NIF cannot be done until the dirty NIF has returned. Thus, other + processes waiting for such operations to complete might + have to wait for a very long time. Blocking multi-scheduling, that + is, calling + erlang:system_flag(multi_scheduling, block), can + also take a very long time to complete. This becaue all ongoing + dirty operations on all dirty schedulers must complete before + the block operation can complete.

+

Many operations communicating with a process executing a + dirty NIF can, however, complete while it executes the + dirty NIF. For example, retrieving information about it through + + erlang:process_info, setting its group leader, + register/unregister its name, and so on.

+

Termination of a process executing a dirty NIF can only be + completed up to a certain point while it executes the dirty NIF. + All Erlang resources, such as its registered name and its ets + tables, are released. All links and monitors are triggered. The + execution of the NIF is, however, not stopped. The NIF + can safely continue execution, allocate heap memory, and so on, + but it is of course better to stop executing as soon as possible. + The NIF can check whether a current process is alive using + + enif_is_current_process_alive. Communication + using enif_send and + + enif_port_command is also dropped when the + sending process is not alive. Deallocation of certain internal + resources, such as process heap and process control block, is + delayed until the dirty NIF has completed.

+

Known issue that are planned to be fixed:

+ + +

As purging of a module might need to garbage + collect a process to determine if it has + references to the module, a process executing a dirty + NIF can delay purging for a very long time. Delaying + a purge operation implies delaying all code + loading operations, which can cause severe problems for + the system as a whole.

+
+
+
+
+
- INITIALIZATION + Initialization - ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload) -

This is the magic macro to initialize a NIF library. It - should be evaluated in global file scope.

-

MODULE is the name of the Erlang module as an - identifier without string quotations. It will be stringified by - the macro.

-

funcs is a static array of function descriptors for - all the implemented NIFs in this library.

-

load, reload, upgrade and unload - are pointers to functions. One of load, reload or - upgrade will be called to initialize the library. - unload is called to release the library. They are all - described individually below.

-

If compiling a nif for static inclusion via --enable-static-nifs you - have to define STATIC_ERLANG_NIF before the ERL_NIF_INIT declaration.

+ ERL_NIF_INIT(MODULE, + ErlNifFunc funcs[], load, reload, upgrade, unload) + +

This is the magic macro to initialize a NIF library. It + is to be evaluated in global file scope.

+

MODULE is the name of the Erlang module as an + identifier without string quotations. It is stringified by + the macro.

+

funcs is a static array of function descriptors for + all the implemented NIFs in this library.

+

load, reload, upgrade and unload + are pointers to functions. One of load, reload, or + upgrade is called to initialize the library. + unload is called to release the library. All are + described individually below.

+

If compiling a NIF for static inclusion through + --enable-static-nifs, you must define STATIC_ERLANG_NIF + before the ERL_NIF_INIT declaration.

- - int (*load)(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) -

load is called when the NIF library is loaded - and there is no previously loaded library for this module.

+ int (*load)(ErlNifEnv* env, void** priv_data, + ERL_NIF_TERM load_info) + +

load is called when the NIF library is loaded + and no previously loaded library exists for this module.

*priv_data can be set to point to some private data - that the library needs in order to keep a state between NIF - calls. enif_priv_data will return this pointer. - *priv_data will be initialized to NULL when load is - called.

+ that the library needs to keep a state between NIF + calls. enif_priv_data returns this pointer. + *priv_data is initialized to NULL when load is + called.

load_info is the second argument to erlang:load_nif/2.

-

The library will fail to load if load returns - anything other than 0. load can be NULL in case no - initialization is needed.

-
- - int (*upgrade)(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info) -

upgrade is called when the NIF library is loaded - and there is old code of this module with a loaded NIF library.

-

Works the same as load. The only difference is that - *old_priv_data already contains the value set by the - last call to load or reload for the old module - code. *priv_data will be initialized to NULL when upgrade - is called. It is allowed to write to both *priv_data and *old_priv_data.

-

The library will fail to load if upgrade returns - anything other than 0 or if upgrade is NULL.

+ marker="erlang#load_nif-2">erlang:load_nif/2.

+

The library fails to load if load returns + anything other than 0. load can be NULL if + initialization is not needed.

- - void (*unload)(ErlNifEnv* env, void* priv_data) -

unload is called when the module code that - the NIF library belongs to is purged as old. New code - of the same module may or may not exist. Note that unload is not - called for a replaced library as a consequence of reload.

+ int (*upgrade)(ErlNifEnv* env, void** + priv_data, void** old_priv_data, ERL_NIF_TERM load_info) + +

upgrade is called when the NIF library is loaded + and there is old code of this module with a loaded NIF library.

+

Works as load, except that *old_priv_data already + contains the value set by the last call to load or + reload for the old module code. *priv_data is + initialized to NULL when upgrade is called. It is + allowed to write to both *priv_data and + *old_priv_data.

+

The library fails to load if upgrade returns + anything other than 0 or if upgrade is NULL.

- - int (*reload)(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) - - -

The reload mechanism is deprecated. It was only intended - as a development feature. Do not use it as an upgrade method for - live production systems. It might be removed in future releases. Be sure - to pass reload as NULL to ERL_NIF_INIT - to disable it when not used.

-
-

reload is called when the NIF library is loaded - and there is already a previously loaded library for this - module code.

-

Works the same as load. The only difference is that - *priv_data already contains the value set by the - previous call to load or reload.

-

The library will fail to load if reload returns - anything other than 0 or if reload is NULL.

+ void (*unload)(ErlNifEnv* env, void* + priv_data) + +

unload is called when the module code that + the NIF library belongs to is purged as old. New code of the same + module may or may not exist. Notice that unload is not + called for a replaced library as a consequence of reload.

+
+ int (*reload)(ErlNifEnv* env, void** + priv_data, ERL_NIF_TERM load_info) + + +

The reload mechanism is deprecated. It was only intended + as a development feature. Do not use it as an upgrade method for + live production systems. It can be removed in future releases. + Ensure to pass reload as NULL to + ERL_NIF_INIT + to disable it when not used.

+
+

reload is called when the NIF library is loaded and a + previously loaded library already exists for this module code.

+

Works as load, except that + *priv_data already contains the value set by the + previous call to load or reload.

+

The library fails to load if reload returns + anything other than 0 or if reload is NULL.

-
- DATA TYPES - + Data Types - ERL_NIF_TERM - + ERL_NIF_TERM +

Variables of type ERL_NIF_TERM can refer to any Erlang term. - This is an opaque type and values of it can only by used either as - arguments to API functions or as return values from NIFs. All - ERL_NIF_TERM's belong to an environment - (ErlNifEnv). A term can not be - destructed individually, it is valid until its environment is destructed.

+ This is an opaque type and values of it can only by used either as + arguments to API functions or as return values from NIFs. All + ERL_NIF_TERMs belong to an environment + (ErlNifEnv). + A term cannot be destructed individually, it is valid until its + environment is destructed.

- ErlNifEnv + ErlNifEnv -

ErlNifEnv represents an environment that can host Erlang terms. - All terms in an environment are valid as long as the environment is valid. - ErlNifEnv is an opaque type and pointers to it can only be passed - on to API functions. There are two types of environments; process - bound and process independent.

-

A process bound environment is passed as the first argument to all NIFs. - All function arguments passed to a NIF will belong to that environment. - The return value from a NIF must also be a term belonging to the same - environment. - In addition a process bound environment contains transient information - about the calling Erlang process. The environment is only valid in the - thread where it was supplied as argument until the NIF returns. It is - thus useless and dangerous to store pointers to process bound - environments between NIF calls.

-

A process independent environment is created by calling - enif_alloc_env. It can be - used to store terms between NIF calls and to send terms with - enif_send. A process - independent environment with all its terms is valid until you explicitly - invalidates it with enif_free_env - or enif_send.

+

ErlNifEnv represents an environment that can host Erlang + terms. All terms in an environment are valid as long as the + environment is valid. ErlNifEnv is an opaque type; pointers to + it can only be passed on to API functions. Two types of environments + exist:

+ + Process-bound environment + +

Passed as the first argument to all NIFs. All function arguments + passed to a NIF belong to that environment. The return value from + a NIF must also be a term belonging to the same environment.

+

A process-bound environment contains transient information + about the calling Erlang process. The environment is only valid + in the thread where it was supplied as argument until the NIF + returns. It is thus useless and dangerous to store pointers to + process-bound environments between NIF calls.

+
+ Process-independent environment + +

Created by calling + enif_alloc_env. This environment can be + used to store terms between NIF calls and to send terms with + enif_send. A + process-independent environment with all its terms is valid until + you explicitly invalidate it with + enif_free_env + or enif_send.

+
+

All contained terms of a list/tuple/map must belong to the same - environment as the list/tuple/map itself. Terms can be copied between - environments with - enif_make_copy.

+ environment as the list/tuple/map itself. Terms can be copied between + environments with + enif_make_copy.

- ErlNifFunc - -

- + ErlNifFunc + + typedef struct { const char* name; unsigned arity; ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); unsigned flags; -} ErlNifFunc; - -

Describes a NIF by its name, arity and implementation. - fptr is a pointer to the function that implements the - NIF. The argument argv of a NIF will contain the - function arguments passed to the NIF and argc is the - length of the array, i.e. the function arity. argv[N-1] - will thus denote the Nth argument to the NIF. Note that the - argc argument allows for the same C function to - implement several Erlang functions with different arity (but - same name probably). For a regular NIF, flags is 0 (and - so its value can be omitted for statically initialized ErlNifFunc - instances), or it can be used to indicate that the NIF is a dirty NIF that should be executed - on a dirty scheduler thread (note that the dirty NIF functionality - described here is experimental and that you have to enable - support for dirty schedulers when building OTP in order to try the - functionality out). If the dirty NIF is expected to be - CPU-bound, its flags field should be set to - ERL_NIF_DIRTY_JOB_CPU_BOUND, or for I/O-bound jobs, - ERL_NIF_DIRTY_JOB_IO_BOUND.

-

If one of the - ERL_NIF_DIRTY_JOB_*_BOUND flags is set, and the runtime - system has no support for dirty schedulers, the runtime system - will refuse to load the NIF library.

+} ErlNifFunc;
+

Describes a NIF by its name, arity, and implementation.

+ + fptr + +

A pointer to the function that implements the NIF.

+
+ argv + +

Contains the function arguments passed to the NIF.

+
+ argc + +

The array length, that is, the function arity. argv[N-1] + thus denotes the Nth argument to the NIF. Notice that the argument + argc allows for the same C function to implement several + Erlang functions with different arity (but probably with the same + name).

+
+ flags + +

Is 0 for a regular NIF (and so its value can be omitted + for statically initialized ErlNifFunc instances).

+

flags can be used to indicate that the NIF is a + dirty NIF that is to be + executed on a dirty scheduler thread.

+

The dirty NIF functionality described here is + experimental. You have to enable support for dirty + schedulers when building OTP to try out the functionality.

+

If the dirty NIF is expected to be CPU-bound, its flags + field is to be set to ERL_NIF_DIRTY_JOB_CPU_BOUND or + ERL_NIF_DIRTY_JOB_IO_BOUND.

+ +

If one of the ERL_NIF_DIRTY_JOB_*_BOUND flags is set, + and the runtime system has no support for dirty schedulers, + the runtime system refuses to load the NIF library.

+
+
+
- ErlNifBinary - -

- + ErlNifBinary + + typedef struct { unsigned size; unsigned char* data; -} ErlNifBinary; - +} ErlNifBinary;

ErlNifBinary contains transient information about an inspected binary term. data is a pointer to a buffer of size bytes with the raw content of the binary.

-

Note that ErlNifBinary is a semi-opaque type and you are +

Notice that ErlNifBinary is a semi-opaque type and you are only allowed to read fields size and data.

- - ErlNifBinaryToTerm + ErlNifBinaryToTerm -

An enumeration of the options that can be given to - enif_binary_to_term. - For default behavior, use the value 0.

- - ERL_NIF_BIN2TERM_SAFE -

Use this option when receiving data from untrusted sources.

-
+

An enumeration of the options that can be specified to + + enif_binary_to_term. + For default behavior, use value 0.

+

When receiving data from untrusted sources, use option + ERL_NIF_BIN2TERM_SAFE.

- - ErlNifPid - -

ErlNifPid is a process identifier (pid). In contrast to - pid terms (instances of ERL_NIF_TERM), ErlNifPid's are self - contained and not bound to any - environment. ErlNifPid - is an opaque type.

-
- ErlNifPort - -

ErlNifPort is a port identifier. In contrast to - port id terms (instances of ERL_NIF_TERM), ErlNifPort's are self - contained and not bound to any - environment. ErlNifPort - is an opaque type.

-
- - ErlNifResourceType - -

Each instance of ErlNifResourceType represent a class of - memory managed resource objects that can be garbage collected. + ErlNifPid + +

A process identifier (pid). In contrast to pid terms (instances of + ERL_NIF_TERM), ErlNifPids are self-contained and not + bound to any environment. + ErlNifPid is an opaque type.

+
+ ErlNifPort + +

A port identifier. In contrast to port ID terms (instances of + ERL_NIF_TERM), ErlNifPorts are self-contained and not + bound to any environment. + ErlNifPort is an opaque type.

+
+ ErlNifResourceType + +

Each instance of ErlNifResourceType represents a class of + memory-managed resource objects that can be garbage collected. Each resource type has a unique name and a destructor function that is called when objects of its type are released.

-
- ErlNifResourceDtor - -

- -typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj); - -

The function prototype of a resource destructor function.

-
- ErlNifCharEncoding - -

- + + ErlNifResourceDtor + + +typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj); +

The function prototype of a resource destructor function.

+
+ ErlNifCharEncoding + + typedef enum { ERL_NIF_LATIN1 -}ErlNifCharEncoding; - -

The character encoding used in strings and atoms. The only - supported encoding is currently ERL_NIF_LATIN1 for - iso-latin-1 (8-bit ascii).

-
- ErlNifSysInfo - -

Used by enif_system_info - to return information about the runtime system. Contains currently - the exact same content as ErlDrvSysInfo.

-
- ErlNifSInt64 -

A native signed 64-bit integer type.

- ErlNifUInt64 -

A native unsigned 64-bit integer type.

- - ErlNifTime +}ErlNifCharEncoding;
+

The character encoding used in strings and atoms. The only + supported encoding is ERL_NIF_LATIN1 for + ISO Latin-1 (8-bit ASCII).

+
+ ErlNifSysInfo + +

Used by + enif_system_info to return information about the + runtime system. Contains the same content as + + ErlDrvSysInfo.

+
+ ErlNifSInt64 + +

A native signed 64-bit integer type.

+
+ ErlNifUInt64 + +

A native unsigned 64-bit integer type.

+
+ ErlNifTime

A signed 64-bit integer type for representation of time.

- ErlNifTimeUnit + ErlNifTimeUnit

An enumeration of time units supported by the NIF API:

- - ERL_NIF_SEC -

Seconds

- ERL_NIF_MSEC -

Milliseconds

- ERL_NIF_USEC -

Microseconds

- ERL_NIF_NSEC -

Nanoseconds

-
+ + ERL_NIF_SEC + Seconds + ERL_NIF_MSEC + Milliseconds + ERL_NIF_USEC + Microseconds + ERL_NIF_NSEC + Nanoseconds +
- - ErlNifUniqueInteger + ErlNifUniqueInteger

An enumeration of the properties that can be requested from - enif_unique_integer. - For default properties, use the value 0.

+ + enif_unique_integer. + For default properties, use value 0.

- ERL_NIF_UNIQUE_POSITIVE -

Return only positive integers

- ERL_NIF_UNIQUE_MONOTONIC -

Return only - strictly - monotonically increasing integer corresponding to creation time

-
+ ERL_NIF_UNIQUE_POSITIVE + +

Return only positive integers.

+
+ ERL_NIF_UNIQUE_MONOTONIC + +

Return only + strictly monotonically increasing integer corresponding + to creation time.

+
+
-
void *enif_alloc(size_t size) - Allocate dynamic memory -

Allocate memory of size bytes. Return NULL if allocation failed.

+ Allocate dynamic memory. + +

Allocates memory of size bytes.

+

Returns NULL if the allocation fails.

+
- intenif_alloc_binary(size_t size, ErlNifBinary* bin) - Create a new binary -

Allocate a new binary of size size - bytes. Initialize the structure pointed to by bin to - refer to the allocated binary. The binary must either be released by - enif_release_binary - or ownership transferred to an Erlang term with - enif_make_binary. - An allocated (and owned) ErlNifBinary can be kept between NIF - calls.

-

Return true on success or false if allocation failed.

+ int + enif_alloc_binary(size_t size, ErlNifBinary* bin) + + Create a new binary. + +

Allocates a new binary of size size bytes. + Initializes the structure pointed to by bin to + refer to the allocated binary. The binary must either be released by + + enif_release_binary + or ownership transferred to an Erlang term with + enif_make_binary. + An allocated (and owned) ErlNifBinary can be kept between NIF + calls.

+

Returns true on success, or false if allocation + fails.

ErlNifEnv *enif_alloc_env() - Create a new environment -

Allocate a new process independent environment. The environment can - be used to hold terms that is not bound to any process. Such terms can - later be copied to a process environment with - enif_make_copy - or be sent to a process as a message with enif_send.

-

Return pointer to the new environment.

-
-
- - - void *enif_alloc_resource(ErlNifResourceType* type, unsigned size) - Allocate a memory managed resource object -

Allocate a memory managed resource object of type type and size size bytes.

-
- - - size_tenif_binary_to_term(ErlNifEnv *env, const unsigned char* data, size_t size, ERL_NIF_TERM *term, ErlNifBinaryToTerm opts) - Create a term from the external format - -

Create a term that is the result of decoding the binary data - at data, which must be encoded according to the Erlang external term format. - No more than size bytes are read from data. Argument opts - correspond to the second argument to - erlang:binary_to_term/2, and must be either 0 or - ERL_NIF_BIN2TERM_SAFE.

-

On success, store the resulting term at *term and return - the actual number of bytes read. Return zero if decoding fails or if opts - is invalid.

-

See also: - ErlNifBinaryToTerm, - erlang:binary_to_term/2 and - enif_term_to_binary. -

-
+ Create a new environment. + +

Allocates a new process-independent environment. The environment can + be used to hold terms that are not bound to any process. Such terms + can later be copied to a process environment with + enif_make_copy or + be sent to a process as a message with + enif_send.

+

Returns pointer to the new environment.

+
- - voidenif_clear_env(ErlNifEnv* env) - Clear an environment for reuse -

Free all terms in an environment and clear it for reuse. The environment must - have been allocated with enif_alloc_env. -

+ void *enif_alloc_resource(ErlNifResourceType* + type, unsigned size) + Allocate a memory-managed resource object. + +

Allocates a memory-managed resource object of type type and + size size bytes.

+
- - intenif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs) - Compare two terms -

Return an integer less than, equal to, or greater than - zero if lhs is found, respectively, to be less than, - equal, or greater than rhs. Corresponds to the Erlang - operators ==, /=, =<, <, - >= and > (but not =:= or =/=).

+ size_tenif_binary_to_term(ErlNifEnv *env, + const unsigned char* data, size_t size, ERL_NIF_TERM *term, + ErlNifBinaryToTerm opts) + Create a term from the external format. + +

Creates a term that is the result of decoding the binary data at + data, which must be encoded according to the Erlang external + term format. No more than size bytes are read from data. + Argument opts corresponds to the second argument to + + erlang:binary_to_term/2 and must be either 0 + or ERL_NIF_BIN2TERM_SAFE.

+

On success, stores the resulting term at *term and returns + the number of bytes read. Returns 0 if decoding fails or if + opts is invalid.

+

See also + ErlNifBinaryToTerm, + + erlang:binary_to_term/2, and + + enif_term_to_binary.

+
- voidenif_cond_broadcast(ErlNifCond *cnd) - -

Same as erl_drv_cond_broadcast. -

+ voidenif_clear_env(ErlNifEnv* env) + + Clear an environment for reuse. + +

Frees all terms in an environment and clears it for reuse. + The environment must have been allocated with + enif_alloc_env.

+
- ErlNifCond *enif_cond_create(char *name) - -

Same as erl_drv_cond_create. -

+ int + enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs) + + Compare two terms. + +

Returns an integer < 0 if lhs < rhs, + 0 if lhs = rhs, and > 0 if + lhs > rhs. Corresponds to the Erlang + operators ==, /=, =<, <, + >=, and > (but not =:= or + =/=).

+
- voidenif_cond_destroy(ErlNifCond *cnd) - -

Same as erl_drv_cond_destroy. -

+ void + enif_cond_broadcast(ErlNifCond *cnd) + + +

Same as + erl_drv_cond_broadcast.

+
- voidenif_cond_signal(ErlNifCond *cnd) - -

Same as erl_drv_cond_signal. -

+ ErlNifCond * + enif_cond_create(char *name) + + +

Same as + erl_drv_cond_create.

+
- voidenif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx) - -

Same as erl_drv_cond_wait. -

+ void + enif_cond_destroy(ErlNifCond *cnd) + + +

Same as + erl_drv_cond_destroy.

+
- intenif_consume_timeslice(ErlNifEnv *env, int percent) - -

Give the runtime system a hint about how much CPU time the current NIF call has consumed - since last hint, or since the start of the NIF if no previous hint has been given. - The time is given as a percent of the timeslice that a process is allowed to execute Erlang - code until it may be suspended to give time for other runnable processes. - The scheduling timeslice is not an exact entity, but can usually be - approximated to about 1 millisecond.

-

Note that it is up to the runtime system to determine if and how to use this information. - Implementations on some platforms may use other means in order to determine consumed - CPU time. Lengthy NIFs should regardless of this frequently call enif_consume_timeslice - in order to determine if it is allowed to continue execution or not.

+ void + enif_cond_signal(ErlNifCond *cnd) + + +

Same as + erl_drv_cond_signal.

+
+
-

Returns 1 if the timeslice is exhausted, or 0 otherwise. If 1 is returned the NIF should return - as soon as possible in order for the process to yield.

-

Argument percent must be an integer between 1 and 100. This function - must only be called from a NIF-calling thread and argument env must be - the environment of the calling process.

-

This function is provided to better support co-operative scheduling, improve system responsiveness, - and make it easier to prevent misbehaviors of the VM due to a NIF monopolizing a scheduler thread. - It can be used to divide length work into - a number of repeated NIF-calls without the need to create threads. - See also the warning text at the beginning of this document.

- + + void + enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx) + + + +

Same as + erl_drv_cond_wait.

+
+ + int + enif_consume_timeslice(ErlNifEnv *env, int percent) + + + +

Gives the runtime system a hint about how much CPU time the current + NIF call has consumed since the last hint, or since the start of the + NIF if no previous hint has been specified. The time is specified as a + percent of the timeslice that a process is allowed to execute + Erlang code until it can be suspended to give time for other runnable + processes. The scheduling timeslice is not an exact entity, but can + usually be approximated to about 1 millisecond.

+

Notice that it is up to the runtime system to determine if and how + to use this information. Implementations on some platforms can use + other means to determine consumed CPU time. Lengthy NIFs should + regardless of this frequently call enif_consume_timeslice to + determine if it is allowed to continue execution.

+

Argument percent must be an integer between 1 and 100. This + function must only be called from a NIF-calling thread, and argument + env must be the environment of the calling process.

+

Returns 1 if the timeslice is exhausted, otherwise 0. + If 1 is returned, the NIF is to return as soon as possible in + order for the process to yield.

+

This function is provided to better support co-operative scheduling, + improve system responsiveness, and make it easier to prevent + misbehaviors of the VM because of a NIF monopolizing a scheduler + thread. It can be used to divide + length work into a number of repeated NIF calls without the + need to create threads.

+

See also the warning text at + the beginning of this manual page.

+
+
- ErlNifTimeenif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to) - Convert time unit of a time value + ErlNifTimeenif_convert_time_unit(ErlNifTime + val, ErlNifTimeUnit from, ErlNifTimeUnit to) + Convert time unit of a time value. - -

Arguments:

- - val - Value to convert time unit for. - from - Time unit of val. - to - Time unit of returned value. - -

Converts the val value of time unit from to - the corresponding value of time unit to. The result is - rounded using the floor function.

-

Returns ERL_NIF_TIME_ERROR if called with an invalid - time unit argument.

-

See also: - ErlNifTime and - ErlNifTimeUnit. -

+ +

Converts the val value of time unit from to + the corresponding value of time unit to. The result is + rounded using the floor function.

+ + val + Value to convert time unit for. + from + Time unit of val. + to + Time unit of returned value. + +

Returns ERL_NIF_TIME_ERROR if called with an invalid + time unit argument.

+

See also ErlNifTime + and + ErlNifTimeUnit.

- ERL_NIF_TERMenif_cpu_time(ErlNifEnv *) + ERL_NIF_TERM + enif_cpu_time(ErlNifEnv *) -

Returns the CPU time in the same format as erlang:timestamp(). - The CPU time is the time the current logical cpu has spent executing since - some arbitrary point in the past. - If the OS does not support fetching of this value enif_cpu_time - invokes enif_make_badarg. -

+

Returns the CPU time in the same format as + + erlang:timestamp(). + The CPU time is the time the current logical CPU has spent executing + since some arbitrary point in the past. If the OS does not support + fetching this value, enif_cpu_time invokes + + enif_make_badarg.

- intenif_equal_tids(ErlNifTid tid1, ErlNifTid tid2) - -

Same as erl_drv_equal_tids. -

+ int + enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2) + + + +

Same as + erl_drv_equal_tids.

+
voidenif_free(void* ptr) - Free dynamic memory -

Free memory allocated by enif_alloc.

+ Free dynamic memory. + +

Frees memory allocated by + enif_alloc.

+
- voidenif_free_env(ErlNifEnv* env) - Free an environment allocated with enif_alloc_env -

Free an environment allocated with enif_alloc_env. - All terms created in the environment will be freed as well.

+ void + enif_free_env(ErlNifEnv* env) + Free an environment allocated with enif_alloc_env. + +

Frees an environment allocated with + enif_alloc_env. + All terms created in the environment are freed as well.

+
- intenif_get_atom(ErlNifEnv* env, ERL_NIF_TERM term, char* buf, unsigned size, ErlNifCharEncoding encode) - Get the text representation of an atom term -

Write a null-terminated string, in the buffer pointed to by - buf of size size, consisting of the string - representation of the atom term with encoding - encode. Return - the number of bytes written (including terminating null character) or 0 if - term is not an atom with maximum length of - size-1.

+ intenif_get_atom(ErlNifEnv* env, ERL_NIF_TERM + term, char* buf, unsigned size, ErlNifCharEncoding encode) + + Get the text representation of an atom term. + +

Writes a NULL-terminated string in the buffer pointed to by + buf of size size, consisting of the string + representation of the atom term with encoding + encode.

+

Returns the number of bytes written (including terminating + NULL character) or 0 if term is not an atom with + maximum length of size-1.

+
- intenif_get_atom_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len, ErlNifCharEncoding encode) - Get the length of atom term -

Set *len to the length (number of bytes excluding - terminating null character) of the atom term with encoding - encode. Return true on success or false if term is not an - atom.

+ intenif_get_atom_length(ErlNifEnv* env, + ERL_NIF_TERM term, unsigned* len, ErlNifCharEncoding encode) + + Get the length of atom term. + +

Sets *len to the length (number of bytes excluding + terminating NULL character) of the atom term with + encoding encode.

+

Returns true on success, or false if term is not + an atom.

+
- intenif_get_double(ErlNifEnv* env, ERL_NIF_TERM term, double* dp) - Read a floating-point number term -

Set *dp to the floating point value of - term. Return true on success or false if term is not a float.

+ intenif_get_double(ErlNifEnv* env, + ERL_NIF_TERM term, double* dp) + Read a floating-point number term. + +

Sets *dp to the floating-point value of term.

+

Returns true on success, or false if term is not + a float.

+
- intenif_get_int(ErlNifEnv* env, ERL_NIF_TERM term, int* ip) - Read an integer term -

Set *ip to the integer value of - term. Return true on success or false if term is not an - integer or is outside the bounds of type int.

+ intenif_get_int(ErlNifEnv* env, ERL_NIF_TERM + term, int* ip) + Read an integer term. + +

Sets *ip to the integer value of term.

+

Returns true on success, or false if term is not + an integer or is outside the bounds of type int.

+
- intenif_get_int64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifSInt64* ip) - Read a 64-bit integer term -

Set *ip to the integer value of - term. Return true on success or false if term is not an - integer or is outside the bounds of a signed 64-bit integer.

+ intenif_get_int64(ErlNifEnv* env, ERL_NIF_TERM + term, ErlNifSInt64* ip) + Read a 64-bit integer term. + +

Sets *ip to the integer value of term.

+

Returns true on success, or false if term is not + an integer or is outside the bounds of a signed 64-bit integer.

+
- intenif_get_local_pid(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPid* pid) - Read an local pid term -

If term is the pid of a node local process, initialize the - pid variable *pid from it and return true. Otherwise return false. - No check if the process is alive is done.

+ intenif_get_local_pid(ErlNifEnv* env, + ERL_NIF_TERM term, ErlNifPid* pid) + Read a local pid term. + +

If term is the pid of a node local process, this function + initializes the pid variable *pid from it and returns + true. Otherwise returns false. No check is done if the + process is alive.

+
- intenif_get_local_port(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPort* port_id) - Read an local port term -

If term identifies a node local port, initialize the - port variable *port_id from it and return true. Otherwise return false. - No check if the port is alive is done.

+ intenif_get_local_port(ErlNifEnv* env, + ERL_NIF_TERM term, ErlNifPort* port_id) + Read a local port term. + +

If term identifies a node local port, this function + initializes the port variable *port_id from it and returns + true. Otherwise returns false. No check is done if the + port is alive.

+
- intenif_get_list_cell(ErlNifEnv* env, ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail) - Get head and tail from a list -

Set *head and *tail from - list and return true, or return false if list is not a - non-empty list.

+ intenif_get_list_cell(ErlNifEnv* env, + ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail) + + Get head and tail from a list. + +

Sets *head and *tail from list list.

+

Returns true on success, or false if the list is + empty.

+
- intenif_get_list_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len) - Get the length of list term -

Set *len to the length of list term and return true, - or return false if term is not a proper list.

+ intenif_get_list_length(ErlNifEnv* env, + ERL_NIF_TERM term, unsigned* len) + Get the length of list term. + +

Sets *len to the length of list term.

+

Returns true on success, or false if term is + not a proper list.

+
- intenif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip) - Read an long integer term -

Set *ip to the long integer value of term and - return true, or return false if term is not an integer or is - outside the bounds of type long int.

+ intenif_get_long(ErlNifEnv* env, ERL_NIF_TERM + term, long int* ip) + Read a long integer term. + +

Sets *ip to the long integer value of term.

+

Returns true on success, or false if term is + not an integer or is outside the bounds of type long int.

+
- intenif_get_map_size(ErlNifEnv* env, ERL_NIF_TERM term, size_t *size) - Read the size of a map term -

Set *size to the number of key-value pairs in the map term and - return true, or return false if term is not a map.

+ intenif_get_map_size(ErlNifEnv* env, + ERL_NIF_TERM term, size_t *size) + Read the size of a map term. + +

Sets *size to the number of key-value pairs in the map + term.

+

Returns true on success, or false if term is + not a map.

+
- intenif_get_map_value(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value) - Get the value of a key in a map -

Set *value to the value associated with key in the - map map and return true. Return false if map is not a map - or if map does not contain key.

+ intenif_get_map_value(ErlNifEnv* env, + ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value) + + Get the value of a key in a map. + +

Sets *value to the value associated with key in the + map map.

+

Returns true on success, or false if map is not + a map or if map does not contain key.

+
- - intenif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp) - Get the pointer to a resource object -

Set *objp to point to the resource object referred to by term.

-

Return true on success or false if term is not a handle to a resource object - of type type.

+ + + intenif_get_resource(ErlNifEnv* env, + ERL_NIF_TERM term, ErlNifResourceType* type, void** objp) + + Get the pointer to a resource object. + +

Sets *objp to point to the resource object referred to by + term.

+

Returns true on success, or false if term is + not a handle to a resource object of type type.

+
- intenif_get_string(ErlNifEnv* env, - ERL_NIF_TERM list, char* buf, unsigned size, - ErlNifCharEncoding encode) - Get a C-string from a list -

Write a null-terminated string, in the buffer pointed to by - buf with size size, consisting of the characters - in the string list. The characters are written using encoding - encode. - Return the number of bytes written (including terminating null - character), or -size if the string was truncated due to - buffer space, or 0 if list is not a string that can be - encoded with encode or if size was less than 1. - The written string is always null-terminated unless buffer - size is less than 1.

+ intenif_get_string(ErlNifEnv* env, + ERL_NIF_TERM list, char* buf, unsigned size, + ErlNifCharEncoding encode) + Get a C-string from a list. + +

Writes a NULL-terminated string in the buffer pointed to by + buf with size size, consisting of the characters + in the string list. The characters are written using encoding + encode.

+

Returns one of the following:

+ + The number of bytes written (including terminating NULL + character) + -size if the string was truncated because of buffer + space + 0 if list is not a string that can be encoded + with encode or if size was < 1. + +

The written string is always NULL-terminated, unless buffer + size is < 1.

+
- intenif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM term, int* arity, const ERL_NIF_TERM** array) - Inspect the elements of a tuple -

If term is a tuple, set *array to point - to an array containing the elements of the tuple and set - *arity to the number of elements. Note that the array - is read-only and (*array)[N-1] will be the Nth element of - the tuple. *array is undefined if the arity of the tuple - is zero.

Return true on success or false if term is not a - tuple.

+ intenif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM + term, int* arity, const ERL_NIF_TERM** array) + Inspect the elements of a tuple. + +

If term is a tuple, this function sets *array to point + to an array containing the elements of the tuple, and sets + *arity to the number of elements. Notice that the array + is read-only and (*array)[N-1] is the Nth element of + the tuple. *array is undefined if the arity of the tuple + is zero.

+

Returns true on success, or false if term is + not a tuple.

+
- intenif_get_uint(ErlNifEnv* env, ERL_NIF_TERM term, unsigned int* ip) - Read an unsigned integer term -

Set *ip to the unsigned integer value of term and - return true, or return false if term is not an unsigned integer or - is outside the bounds of type unsigned int.

+ intenif_get_uint(ErlNifEnv* env, ERL_NIF_TERM + term, unsigned int* ip) + Read an unsigned integer term. + +

Sets *ip to the unsigned integer value of term.

+

Returns true on success, or false if term is + not an unsigned integer or is outside the bounds of type + unsigned int.

+
- intenif_get_uint64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifUInt64* ip) - Read an unsigned 64-bit integer term -

Set *ip to the unsigned integer value of term and - return true, or return false if term is not an unsigned integer or - is outside the bounds of an unsigned 64-bit integer.

+ intenif_get_uint64(ErlNifEnv* env, + ERL_NIF_TERM term, ErlNifUInt64* ip) + Read an unsigned 64-bit integer term. + +

Sets *ip to the unsigned integer value of term.

+

Returns true on success, or false if term is + not an unsigned integer or is outside the bounds of an unsigned + 64-bit integer.

+
- intenif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip) - Read an unsigned integer term -

Set *ip to the unsigned long integer value of term - and return true, or return false if term is not an unsigned integer or is - outside the bounds of type unsigned long.

+ intenif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM + term, unsigned long* ip) + Read an unsigned integer term. + +

Sets *ip to the unsigned long integer value of + term.

+

Returns true on success, or false if term is + not an unsigned integer or is outside the bounds of type + unsigned long.

+
- intenif_getenv(const char* key, char* value, size_t *value_size) - Get the value of an environment variable -

Same as erl_drv_getenv.

+ intenif_getenv(const char* key, char* value, + size_t *value_size) + Get the value of an environment variable. + +

Same as + erl_drv_getenv.

+
- intenif_has_pending_exception(ErlNifEnv* env, ERL_NIF_TERM* reason) - Check if an exception has been raised -

Return true if a pending exception is associated - with the environment env. If reason is a null pointer, ignore it. - Otherwise, if there's a pending exception associated with env, set the ERL_NIF_TERM - to which reason points to the value of the exception's term. For example, if - enif_make_badarg is called to set a - pending badarg exception, a subsequent call to enif_has_pending_exception(env, &reason) - will set reason to the atom badarg, then return true.

-

See also: enif_make_badarg - and enif_raise_exception.

+ intenif_has_pending_exception(ErlNifEnv* env, + ERL_NIF_TERM* reason) + Check if an exception has been raised. + +

Returns true if a pending exception is associated with the + environment env. If reason is a NULL pointer, + ignore it. Otherwise, if a pending exception associated with + env exists, set ERL_NIF_TERM to which reason + points to the value of the exception's term. For example, if + + enif_make_badarg is called to set a pending + badarg exception, a later call to + enif_has_pending_exception(env, &reason) sets + reason to the atom badarg, then return true.

+

See also + enif_make_badarg and + + enif_raise_exception.

- intenif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin) - Inspect the content of a binary -

Initialize the structure pointed to by bin with - information about the binary term - bin_term. Return true on success or false if bin_term is not a binary.

+ intenif_inspect_binary(ErlNifEnv* env, + ERL_NIF_TERM bin_term, ErlNifBinary* bin) + Inspect the content of a binary. + +

Initializes the structure pointed to by bin with information + about binary term bin_term.

+

Returns true on success, or false if bin_term + is not a binary.

+
- intenif_inspect_iolist_as_binary(ErlNifEnv* - env, ERL_NIF_TERM term, ErlNifBinary* bin) - - Inspect the content of an iolist -

Initialize the structure pointed to by bin with one - continuous buffer with the same byte content as iolist. As with - inspect_binary, the data pointed to by bin is transient and does - not need to be released. Return true on success or false if iolist is not an - iolist.

+ intenif_inspect_iolist_as_binary(ErlNifEnv* + env, ERL_NIF_TERM term, ErlNifBinary* bin) + Inspect the content of an iolist. + +

Initializes the structure pointed to by bin with a + continuous buffer with the same byte content as iolist. As + with inspect_binary, the data pointed to by bin is + transient and does not need to be released.

+

Returns true on success, or false if iolist is + not an iolist.

- intenif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is an atom -

Return true if term is an atom.

+ int + enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is an atom. + +

Returns true if term is an atom.

+
- intenif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a binary -

Return true if term is a binary

+ int + enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is a binary. + +

Returns true if term is a binary.

+
- intenif_is_current_process_alive(ErlNifEnv* env) - Determine if currently executing process is alive or not. -

Return true if currently executing process is currently alive; otherwise - false.

-

This function can only be used from a NIF-calling thread, and with an - environment corresponding to currently executing processes.

+ int + enif_is_current_process_alive(ErlNifEnv* env) + + Determine if currently executing process is alive. + +

Returns true if the currently executing process is currently + alive, otherwise false.

+

This function can only be used from a NIF-calling thread, and with + an environment corresponding to currently executing processes.

+
- intenif_is_empty_list(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is an empty list -

Return true if term is an empty list.

+ intenif_is_empty_list(ErlNifEnv* env, + ERL_NIF_TERM term) + Determine if a term is an empty list. + +

Returns true if term is an empty list.

+
- intenif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is an exception + intenif_is_exception(ErlNifEnv* env, + ERL_NIF_TERM term) + Determine if a term is an exception. -

Return true if term is an exception.

+

Return true if term is an exception.

+
- intenif_is_fun(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a fun -

Return true if term is a fun.

+ intenif_is_fun(ErlNifEnv* env, ERL_NIF_TERM + term) + Determine if a term is a fun. + +

Returns true if term is a fun.

+
- intenif_is_identical(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs) - Erlang operator =:= -

Return true if the two terms are identical. Corresponds to the - Erlang operators =:= and - =/=.

+ intenif_is_identical(ERL_NIF_TERM lhs, + ERL_NIF_TERM rhs) + Erlang operator =:=. + +

Returns true if the two terms are identical. Corresponds to + the Erlang operators =:= and =/=.

+
- intenif_is_list(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a list -

Return true if term is a list.

+ int + enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is a list. + +

Returns true if term is a list.

+
- intenif_is_map(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a map -

Return true if term is a map, false otherwise.

+ intenif_is_map(ErlNifEnv* env, ERL_NIF_TERM + term) + Determine if a term is a map. + +

Returns true if term is a map, otherwise + false.

+
- intenif_is_number(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a number (integer or float) -

Return true if term is a number.

+ intenif_is_number(ErlNifEnv* env, ERL_NIF_TERM + term) + Determine if a term is a number (integer or float). + +

Returns true if term is a number.

+
- intenif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a pid -

Return true if term is a pid.

+ int + enif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is a pid. + +

Returns true if term is a pid.

+
- intenif_is_port(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a port -

Return true if term is a port.

+ int + enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is a port. + +

Returns true if term is a port.

+
- intenif_is_port_alive(ErlNifEnv* env, ErlNifPort *port_id) - Determine if a local port is alive or not. -

Return true if port_id is currently alive.

-

This function is only thread-safe when the emulator with SMP support is used. - It can only be used in a non-SMP emulator from a NIF-calling thread.

+ intenif_is_port_alive(ErlNifEnv* env, + ErlNifPort *port_id) + Determine if a local port is alive. + +

Returns true if port_id is alive.

+

This function is only thread-safe when the emulator with SMP support + is used. It can only be used in a non-SMP emulator from a NIF-calling + thread.

+
- intenif_is_process_alive(ErlNifEnv* env, ErlNifPid *pid) - Determine if a local process is alive or not. -

Return true if pid is currently alive.

-

This function is only thread-safe when the emulator with SMP support is used. - It can only be used in a non-SMP emulator from a NIF-calling thread.

+ intenif_is_process_alive(ErlNifEnv* env, + ErlNifPid *pid) + Determine if a local process is alive. + +

Returns true if pid is alive.

+

This function is only thread-safe when the emulator with SMP support + is used. It can only be used in a non-SMP emulator from a NIF-calling + thread.

+
- intenif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a reference -

Return true if term is a reference.

+ int + enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is a reference. + +

Returns true if term is a reference.

+
- intenif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term) - Determine if a term is a tuple -

Return true if term is a tuple.

+ int + enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term) + + Determine if a term is a tuple. + +

Returns true if term is a tuple.

+
- intenif_keep_resource(void* obj) - Add a reference to a resource object -

Add a reference to resource object obj obtained from - enif_alloc_resource. - Each call to enif_keep_resource for an object must be balanced by - a call to enif_release_resource - before the object will be destructed.

+ int + enif_keep_resource(void* obj) + + Add a reference to a resource object. + +

Adds a reference to resource object obj obtained from + + enif_alloc_resource. Each call to + enif_keep_resource for an object must be balanced by a call to + + enif_release_resource + before the object is destructed.

+
- ERL_NIF_TERMenif_make_atom(ErlNifEnv* env, const char* name) - Create an atom term -

Create an atom term from the null-terminated C-string name - with iso-latin-1 encoding. If the length of name exceeds the maximum length - allowed for an atom (255 characters), enif_make_atom invokes - enif_make_badarg. -

+ ERL_NIF_TERM + enif_make_atom(ErlNifEnv* env, const char* name) + + Create an atom term. + +

Creates an atom term from the NULL-terminated C-string + name with ISO Latin-1 encoding. If the length of name + exceeds the maximum length allowed for an atom (255 characters), + enif_make_atom invokes + enif_make_badarg.

+
- ERL_NIF_TERMenif_make_atom_len(ErlNifEnv* env, const char* name, size_t len) - Create an atom term -

Create an atom term from the string name with length len. - Null-characters are treated as any other characters. If len is greater than the maximum length - allowed for an atom (255 characters), enif_make_atom invokes - enif_make_badarg. -

+ ERL_NIF_TERMenif_make_atom_len(ErlNifEnv* env, + const char* name, size_t len) + Create an atom term. + +

Create an atom term from the string name with length + len. NULL characters are treated as any other + characters. If len exceeds the maximum length + allowed for an atom (255 characters), enif_make_atom invokes + + enif_make_badarg.

+
- ERL_NIF_TERMenif_make_badarg(ErlNifEnv* env) - Make a badarg exception -

Make a badarg exception to be returned from a NIF, and associate - it with the environment env. Once a NIF or any function - it calls invokes enif_make_badarg, the runtime ensures that a - badarg exception is raised when the NIF returns, even if the NIF - attempts to return a non-exception term instead. - The return value from enif_make_badarg may be used only as the - return value from the NIF that invoked it (directly or indirectly) - or be passed to - enif_is_exception, but - not to any other NIF API function.

-

See also: enif_has_pending_exception - and enif_raise_exception. -

-

In earlier versions (older than erts-7.0, OTP 18) the return value - from enif_make_badarg had to be returned from the NIF. This - requirement is now lifted as the return value from the NIF is ignored - if enif_make_badarg has been invoked.

+ ERL_NIF_TERM + enif_make_badarg(ErlNifEnv* env) + Make a badarg exception. + +

Makes a badarg exception to be returned from a NIF, and + associates it with environment env. Once a NIF or any function + it calls invokes enif_make_badarg, the runtime ensures that a + badarg exception is raised when the NIF returns, even if the + NIF attempts to return a non-exception term instead.

+

The return value from enif_make_badarg can be used only as + the return value from the NIF that invoked it (directly or indirectly) + or be passed to + enif_is_exception, but not to any other NIF API + function.

+

See also + enif_has_pending_exception and + + enif_raise_exception.

+ +

Before ERTS 7.0 (Erlang/OTP 18), the return value + from enif_make_badarg had to be returned from the NIF. This + requirement is now lifted as the return value from the NIF is + ignored if enif_make_badarg has been invoked.

+
+
- ERL_NIF_TERMenif_make_binary(ErlNifEnv* env, ErlNifBinary* bin) - Make a binary term -

Make a binary term from bin. Any ownership of - the binary data will be transferred to the created term and - bin should be considered read-only for the rest of the NIF - call and then as released.

+ ERL_NIF_TERM + enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin) + + Make a binary term. + +

Makes a binary term from bin. Any ownership of + the binary data is transferred to the created term and + bin is to be considered read-only for the rest of the NIF + call and then as released.

+
- ERL_NIF_TERMenif_make_copy(ErlNifEnv* dst_env, ERL_NIF_TERM src_term) - Make a copy of a term -

Make a copy of term src_term. The copy will be created in - environment dst_env. The source term may be located in any - environment.

+ ERL_NIF_TERMenif_make_copy(ErlNifEnv* dst_env, + ERL_NIF_TERM src_term) + Make a copy of a term. + +

Makes a copy of term src_term. The copy is created in + environment dst_env. The source term can be located in any + environment.

+
- ERL_NIF_TERMenif_make_double(ErlNifEnv* env, double d) - Create a floating-point term -

Create a floating-point term from a double. If the double argument is - not finite or is NaN, enif_make_double invokes - enif_make_badarg. -

+ ERL_NIF_TERM + enif_make_double(ErlNifEnv* env, double d) + Create a floating-point term. + +

Creates a floating-point term from a double. If argument + double is not finite or is NaN, enif_make_double + invokes + enif_make_badarg.

+
- intenif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding encode) - Create an existing atom term -

Try to create the term of an already existing atom from - the null-terminated C-string name with encoding - encode. If the atom - already exists store the term in *atom and return true, otherwise - return false. If the length of name exceeds the maximum length - allowed for an atom (255 characters), enif_make_existing_atom - returns false.

+ intenif_make_existing_atom(ErlNifEnv* env, + const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding + encode) + Create an existing atom term. + +

Tries to create the term of an already existing atom from + the NULL-terminated C-string name with encoding + encode.

+

If the atom already exists, this function stores the term in + *atom and returns true, otherwise false. + Also returns false if the length of name exceeds the + maximum length allowed for an atom (255 characters).

+
- intenif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding encoding) - Create an existing atom term -

Try to create the term of an already existing atom from the - string name with length len and encoding - encode. Null-characters - are treated as any other characters. If the atom already exists store the term - in *atom and return true, otherwise return false. If len is greater - than the maximum length allowed for an atom (255 characters), - enif_make_existing_atom_len returns false.

+ intenif_make_existing_atom_len(ErlNifEnv* env, + const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding + encoding) + Create an existing atom term. + +

Tries to create the term of an already existing atom from the + string name with length len and encoding + encode. NULL + characters are treated as any other characters.

+

If the atom already exists, this function stores the term in + *atom and returns true, otherwise false. + Also returns false if len exceeds the maximum length + allowed for an atom (255 characters).

+
- - ERL_NIF_TERMenif_make_int(ErlNifEnv* env, int i) - Create an integer term -

Create an integer term.

+ ERL_NIF_TERM + enif_make_int(ErlNifEnv* env, int i) + Create an integer term. + +

Creates an integer term.

+
- ERL_NIF_TERMenif_make_int64(ErlNifEnv* env, ErlNifSInt64 i) - Create an integer term -

Create an integer term from a signed 64-bit integer.

+ ERL_NIF_TERM + enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i) + + Create an integer term. + +

Creates an integer term from a signed 64-bit integer.

+
- ERL_NIF_TERMenif_make_list(ErlNifEnv* env, unsigned cnt, ...) - Create a list term -

Create an ordinary list term of length cnt. Expects - cnt number of arguments (after cnt) of type ERL_NIF_TERM as the - elements of the list. An empty list is returned if cnt is 0.

+ ERL_NIF_TERM + enif_make_list(ErlNifEnv* env, unsigned cnt, ...) + + Create a list term. + +

Creates an ordinary list term of length cnt. Expects + cnt number of arguments (after cnt) of type + ERL_NIF_TERM as the elements of the list.

+

Returns an empty list if cnt is 0.

+
- ERL_NIF_TERMenif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1) - ERL_NIF_TERMenif_make_list2(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2) - ERL_NIF_TERMenif_make_list3(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3) - ERL_NIF_TERMenif_make_list4(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4) - ERL_NIF_TERMenif_make_list5(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5) - ERL_NIF_TERMenif_make_list6(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6) - ERL_NIF_TERMenif_make_list7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7) - ERL_NIF_TERMenif_make_list8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8) - ERL_NIF_TERMenif_make_list9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9) - Create a list term -

Create an ordinary list term with length indicated by the - function name. Prefer these functions (macros) over the variadic - enif_make_list to get a compile time error if the number of - arguments does not match.

+ ERL_NIF_TERM + enif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1) + + ERL_NIF_TERMenif_make_list2(ErlNifEnv* env, + ERL_NIF_TERM e1, ERL_NIF_TERM e2) + ERL_NIF_TERMenif_make_list3(ErlNifEnv* env, + ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3) + ERL_NIF_TERMenif_make_list4(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4) + ERL_NIF_TERMenif_make_list5(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5) + ERL_NIF_TERMenif_make_list6(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6) + ERL_NIF_TERMenif_make_list7(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7) + ERL_NIF_TERMenif_make_list8(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8) + ERL_NIF_TERMenif_make_list9(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9) + Create a list term. + +

Creates an ordinary list term with length indicated by the + function name. Prefer these functions (macros) over the variadic + enif_make_list to get a compile-time error if the number of + arguments does not match.

+
- ERL_NIF_TERMenif_make_list_cell(ErlNifEnv* env, ERL_NIF_TERM head, ERL_NIF_TERM tail) - Create a list cell -

Create a list cell [head | tail].

+ ERL_NIF_TERMenif_make_list_cell(ErlNifEnv* + env, ERL_NIF_TERM head, ERL_NIF_TERM tail) + Create a list cell. + +

Creates a list cell [head | tail].

+
- ERL_NIF_TERMenif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt) - Create a list term from an array -

Create an ordinary list containing the elements of array arr - of length cnt. An empty list is returned if cnt is 0.

+ ERL_NIF_TERM + enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM + arr[], unsigned cnt) + Create a list term from an array. + +

Creates an ordinary list containing the elements of array arr + of length cnt.

+

Returns an empty list if cnt is 0.

+
- ERL_NIF_TERMenif_make_long(ErlNifEnv* env, long int i) - Create an integer term from a long int -

Create an integer term from a long int.

+ ERL_NIF_TERM + enif_make_long(ErlNifEnv* env, long int i) + Create an integer term from a long int. + +

Creates an integer term from a long int.

+
- intenif_make_map_put(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value, ERL_NIF_TERM* map_out) - Insert key-value pair in map -

Make a copy of map map_in and insert key with - value. If key already exists in map_in, the old - associated value is replaced by value. If successful set - *map_out to the new map and return true. Return false if - map_in is not a map.

-

The map_in term must belong to the environment env.

+ intenif_make_map_put(ErlNifEnv* env, + ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value, + ERL_NIF_TERM* map_out) + Insert key-value pair in map. + +

Makes a copy of map map_in and inserts key with + value. If key already exists in map_in, the old + associated value is replaced by value.

+

If successful, this function sets *map_out to the new map and + returns true. Returns false if map_in is not a + map.

+

The map_in term must belong to environment env.

+
- intenif_make_map_remove(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out) - Remove key from map -

If map map_in contains key, make a copy of - map_in in *map_out and remove key and associated - value. If map map_in does not contain key, set - *map_out to map_in. Return true for success or false if - map_in is not a map.

-

The map_in term must belong to the environment env.

+ intenif_make_map_remove(ErlNifEnv* env, + ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out) + + Remove key from map. + +

If map map_in contains key, this function makes a copy + of map_in in *map_out, and removes key and the + associated value. If map map_in does not contain key, + *map_out is set to map_in.

+

Returns true on success, or false if map_in is + not a map.

+

The map_in term must belong to environment env.

+
- intenif_make_map_update(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM new_value, ERL_NIF_TERM* map_out) - Replace value for key in map -

Make a copy of map map_in and replace the old associated - value for key with new_value. If successful set - *map_out to the new map and return true. Return false if - map_in is not a map or if it does no contain key.

-

The map_in term must belong to the environment env.

+ intenif_make_map_update(ErlNifEnv* env, + ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM new_value, + ERL_NIF_TERM* map_out) + Replace value for key in map. + +

Makes a copy of map map_in and replace the old associated + value for key with new_value.

+

If successful, this function sets *map_out to the new map and + returns true. Returns false if map_in is not a + map or if it does not contain key.

+

The map_in term must belong to environment env.

+
- unsigned char *enif_make_new_binary(ErlNifEnv* env, size_t size, ERL_NIF_TERM* termp) - Allocate and create a new binary term -

Allocate a binary of size size bytes and create an owning - term. The binary data is mutable until the calling NIF returns. This is a - quick way to create a new binary without having to use - ErlNifBinary. The drawbacks are - that the binary can not be kept between NIF calls and it can not be - reallocated.

Return a pointer to the raw binary data and set - *termp to the binary term.

+ unsigned char *enif_make_new_binary(ErlNifEnv* + env, size_t size, ERL_NIF_TERM* termp) + Allocate and create a new binary term. + +

Allocates a binary of size size bytes and creates an owning + term. The binary data is mutable until the calling NIF returns. + This is a quick way to create a new binary without having to use + ErlNifBinary. + The drawbacks are that the binary cannot be kept between NIF calls + and it cannot be reallocated.

+

Returns a pointer to the raw binary data and sets + *termp to the binary term.

+
- ERL_NIF_TERMenif_make_new_map(ErlNifEnv* env) - Make an empty map term -

Make an empty map term.

+ ERL_NIF_TERM + enif_make_new_map(ErlNifEnv* env) + Make an empty map term. + +

Makes an empty map term.

+
- ERL_NIF_TERMenif_make_pid(ErlNifEnv* env, const ErlNifPid* pid) - Make a pid term -

Make a pid term from *pid.

+ ERL_NIF_TERM + enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid) + + Make a pid term. + +

Makes a pid term from *pid.

+
- ERL_NIF_TERMenif_make_ref(ErlNifEnv* env) - Create a reference -

Create a reference like erlang:make_ref/0.

+ ERL_NIF_TERM + enif_make_ref(ErlNifEnv* env) + Create a reference. + +

Creates a reference like + erlang:make_ref/0.

+
- ERL_NIF_TERMenif_make_resource(ErlNifEnv* env, void* obj) - Create an opaque handle to a resource object -

Create an opaque handle to a memory managed resource object - obtained by enif_alloc_resource. - No ownership transfer is done, as the resource object still needs to be released by - enif_release_resource, - but note that the call to enif_release_resource can occur - immediately after obtaining the term from enif_make_resource, - in which case the resource object will be deallocated when the - term is garbage collected. See the - example of creating and - returning a resource object for more details.

-

Note that the only defined behaviour of using a resource term in - an Erlang program is to store it and send it between processes on the - same node. Other operations such as matching or term_to_binary - will have unpredictable (but harmless) results.

+ ERL_NIF_TERM + enif_make_resource(ErlNifEnv* env, void* obj) + + Create an opaque handle to a resource object. + +

Creates an opaque handle to a memory-managed resource object + obtained by + enif_alloc_resource. No ownership transfer is done, + as the resource object still needs to be released by + + enif_release_resource. However, notice that the call + to enif_release_resource can occur immediately after obtaining + the term from enif_make_resource, in which case the resource + object is deallocated when the term is garbage collected. For more + details, see the example of + creating and returning a resource object in the User's + Guide.

+

Notice that the only defined behavior of using a resource term in + an Erlang program is to store it and send it between processes on the + same node. Other operations, such as matching or + term_to_binary, have unpredictable (but harmless) results.

+
- ERL_NIF_TERMenif_make_resource_binary(ErlNifEnv* env, void* obj, const void* data, size_t size) - Create a custom binary term -

Create a binary term that is memory managed by a resource object - obj obtained by enif_alloc_resource. - The returned binary term will consist of size bytes pointed to - by data. This raw binary data must be kept readable and unchanged - until the destructor of the resource is called. The binary data may be - stored external to the resource object in which case it is the responsibility - of the destructor to release the data.

-

Several binary terms may be managed by the same resource object. The - destructor will not be called until the last binary is garbage collected. - This can be useful as a way to return different parts of a larger binary - buffer.

-

As with enif_make_resource, - no ownership transfer is done. The resource still needs to be released with - enif_release_resource.

+ ERL_NIF_TERM + enif_make_resource_binary(ErlNifEnv* env, void* obj, const + void* data, size_t size) + Create a custom binary term. + +

Creates a binary term that is memory-managed by a resource object + obj obtained by + enif_alloc_resource. The returned binary term + consists of size bytes pointed to by data. This raw + binary data must be kept readable and unchanged until the destructor + of the resource is called. The binary data can be stored external to + the resource object, in which case the destructor is responsible + for releasing the data.

+

Several binary terms can be managed by the same resource object. The + destructor is not called until the last binary is garbage collected. + This can be useful to return different parts of a larger binary + buffer.

+

As with + enif_make_resource, no ownership transfer is done. + The resource still needs to be released with + + enif_release_resource.

- intenif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in, ERL_NIF_TERM *list_out) - Create the reverse of a list -

Set *list_out to the reverse list of the list list_in and return true, - or return false if list_in is not a list. This function should only be used on - short lists as a copy will be created of the list which will not be released until after the - nif returns.

-

The list_in term must belong to the environment env.

+ int + enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in, + ERL_NIF_TERM *list_out) + Create the reverse of a list. + +

Sets *list_out to the reverse list of the list list_in + and returns true, or returns false if list_in is + not a list.

+

This function is only to be used on short lists, as a copy is + created of the list, which is not released until after the NIF + returns.

+

The list_in term must belong to environment env.

+
- ERL_NIF_TERMenif_make_string(ErlNifEnv* env, const char* string, ErlNifCharEncoding encoding) - Create a string -

Create a list containing the characters of the - null-terminated string string with encoding encoding.

+ ERL_NIF_TERMenif_make_string(ErlNifEnv* env, + const char* string, ErlNifCharEncoding encoding) + Create a string. + +

Creates a list containing the characters of the + NULL-terminated string string with encoding + encoding.

+
- ERL_NIF_TERMenif_make_string_len(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding encoding) - Create a string -

Create a list containing the characters of the string string with - length len and encoding encoding. - Null-characters are treated as any other characters.

+ ERL_NIF_TERMenif_make_string_len(ErlNifEnv* + env, const char* string, size_t len, ErlNifCharEncoding + encoding) + Create a string. + +

Creates a list containing the characters of the string string + with length len and encoding + encoding. + NULL characters are treated as any other characters.

+
- ERL_NIF_TERMenif_make_sub_binary(ErlNifEnv* - env, ERL_NIF_TERM bin_term, size_t pos, size_t size) - Make a subbinary term -

Make a subbinary of binary bin_term, starting at - zero-based position pos with a length of size bytes. - bin_term must be a binary or bitstring and - pos+size must be less or equal to the number of whole - bytes in bin_term.

+ ERL_NIF_TERMenif_make_sub_binary(ErlNifEnv* + env, ERL_NIF_TERM bin_term, size_t pos, size_t size) + Make a subbinary term. + +

Makes a subbinary of binary bin_term, starting at + zero-based position pos with a length of size bytes. + bin_term must be a binary or bitstring. pos+size must + be less or equal to the number of whole bytes in bin_term.

+
- ERL_NIF_TERMenif_make_tuple(ErlNifEnv* env, unsigned cnt, ...) - Create a tuple term -

Create a tuple term of arity cnt. Expects - cnt number of arguments (after cnt) of type ERL_NIF_TERM as the - elements of the tuple.

+ ERL_NIF_TERMenif_make_tuple(ErlNifEnv* env, + unsigned cnt, ...) + Creates a tuple term. + +

Creates a tuple term of arity cnt. Expects cnt number + of arguments (after cnt) of type ERL_NIF_TERM as the + elements of the tuple.

+
- ERL_NIF_TERMenif_make_tuple1(ErlNifEnv* env, ERL_NIF_TERM e1) - ERL_NIF_TERMenif_make_tuple2(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2) - ERL_NIF_TERMenif_make_tuple3(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3) - ERL_NIF_TERMenif_make_tuple4(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4) - ERL_NIF_TERMenif_make_tuple5(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5) - ERL_NIF_TERMenif_make_tuple6(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6) - ERL_NIF_TERMenif_make_tuple7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7) - ERL_NIF_TERMenif_make_tuple8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8) - ERL_NIF_TERMenif_make_tuple9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9) - Create a tuple term -

Create a tuple term with length indicated by the - function name. Prefer these functions (macros) over the variadic - enif_make_tuple to get a compile time error if the number of - arguments does not match.

+ ERL_NIF_TERMenif_make_tuple1(ErlNifEnv* env, + ERL_NIF_TERM e1) + ERL_NIF_TERMenif_make_tuple2(ErlNifEnv* env, + ERL_NIF_TERM e1, ERL_NIF_TERM e2) + ERL_NIF_TERMenif_make_tuple3(ErlNifEnv* env, + ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3) + ERL_NIF_TERMenif_make_tuple4(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4) + ERL_NIF_TERMenif_make_tuple5(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5) + ERL_NIF_TERMenif_make_tuple6(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6) + ERL_NIF_TERMenif_make_tuple7(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7) + ERL_NIF_TERMenif_make_tuple8(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8) + ERL_NIF_TERMenif_make_tuple9(ErlNifEnv* env, + ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9) + Create a tuple term. + +

Creates a tuple term with length indicated by the + function name. Prefer these functions (macros) over the variadic + enif_make_tuple to get a compile-time error if the number of + arguments does not match.

+
- ERL_NIF_TERMenif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt) - Create a tuple term from an array -

Create a tuple containing the elements of array arr - of length cnt.

+ ERL_NIF_TERM + enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM + arr[], unsigned cnt) + Create a tuple term from an array. + +

Creates a tuple containing the elements of array arr + of length cnt.

+
- ERL_NIF_TERMenif_make_uint(ErlNifEnv* env, unsigned int i) - Create an unsigned integer term -

Create an integer term from an unsigned int.

+ ERL_NIF_TERM + enif_make_uint(ErlNifEnv* env, unsigned int i) + + Create an unsigned integer term. + +

Creates an integer term from an unsigned int.

+
- ERL_NIF_TERMenif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i) - Create an unsigned integer term -

Create an integer term from an unsigned 64-bit integer.

+ ERL_NIF_TERM + enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i) + + Create an unsigned integer term. + +

Creates an integer term from an unsigned 64-bit integer.

+
- ERL_NIF_TERMenif_make_ulong(ErlNifEnv* env, unsigned long i) - Create an integer term from an unsigned long int -

Create an integer term from an unsigned long int.

+ ERL_NIF_TERM + enif_make_ulong(ErlNifEnv* env, unsigned long i) + + Create an integer term from an unsigned long int. + +

Creates an integer term from an unsigned long int.

+
- ERL_NIF_TERMenif_make_unique_integer(ErlNifEnv *env, ErlNifUniqueInteger properties) + ERL_NIF_TERMenif_make_unique_integer(ErlNifEnv + *env, ErlNifUniqueInteger properties) -

Returns a unique integer with the same properties as given by erlang:unique_integer/1.

+

Returns a unique integer with the same properties as specified by + + erlang:unique_integer/1.

env is the environment to create the integer in.

-

- ERL_NIF_UNIQUE_POSITIVE and ERL_NIF_UNIQUE_MONOTONIC can - be passed as the second argument to change the properties of the - integer returned. It is possible to combine them by or:ing the - two values together. -

-

See also: - ErlNifUniqueInteger. -

+

ERL_NIF_UNIQUE_POSITIVE and ERL_NIF_UNIQUE_MONOTONIC + can be passed as the second argument to change the properties of the + integer returned. They can be combined by OR:ing the two values + together.

+

See also + ErlNifUniqueInteger.

- intenif_map_iterator_create(ErlNifEnv *env, ERL_NIF_TERM map, ErlNifMapIterator *iter, ErlNifMapIteratorEntry entry) - Create a map iterator -

Create an iterator for the map map by initializing the - structure pointed to by iter. The entry argument determines - the start position of the iterator: ERL_NIF_MAP_ITERATOR_FIRST or - ERL_NIF_MAP_ITERATOR_LAST. Return true on success or false if - map is not a map.

-

A map iterator is only useful during the lifetime of the environment - env that the map belongs to. The iterator must be destroyed by - calling - enif_map_iterator_destroy.

- + intenif_map_iterator_create(ErlNifEnv *env, + ERL_NIF_TERM map, ErlNifMapIterator *iter, ErlNifMapIteratorEntry + entry) + Create a map iterator. + +

Creates an iterator for the map map by initializing the + structure pointed to by iter. Argument entry determines + the start position of the iterator: ERL_NIF_MAP_ITERATOR_FIRST + or ERL_NIF_MAP_ITERATOR_LAST.

+

Returns true on success, or false if map is not a + map.

+

A map iterator is only useful during the lifetime of environment + env that the map belongs to. The iterator must be + destroyed by calling + enif_map_iterator_destroy:

+ ERL_NIF_TERM key, value; ErlNifMapIterator iter; enif_map_iterator_create(env, my_map, &iter, ERL_NIF_MAP_ITERATOR_FIRST); @@ -1646,643 +2069,712 @@ while (enif_map_iterator_get_pair(env, &iter, &key, &value)) { do_something(key,value); enif_map_iterator_next(env, &iter); } -enif_map_iterator_destroy(env, &iter); - -

The key-value pairs of a map have no defined iteration - order. The only guarantee is that the iteration order of a single map - instance is preserved during the lifetime of the environment that the map - belongs to.

-
+enif_map_iterator_destroy(env, &iter);
+ +

The key-value pairs of a map have no defined iteration order. + The only guarantee is that the iteration order of a single map + instance is preserved during the lifetime of the environment that + the map belongs to.

+
- voidenif_map_iterator_destroy(ErlNifEnv *env, ErlNifMapIterator *iter) - Destroy a map iterator + voidenif_map_iterator_destroy(ErlNifEnv *env, + ErlNifMapIterator *iter) + Destroy a map iterator. -

Destroy a map iterator created by - enif_map_iterator_create. -

+

Destroys a map iterator created by + + enif_map_iterator_create.

- intenif_map_iterator_get_pair(ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value) - Get key and value at current map iterator position + intenif_map_iterator_get_pair(ErlNifEnv *env, + ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM + *value) + Get key and value at current map iterator position. -

Get key and value terms at current map iterator position. - On success set *key and *value and return true. - Return false if the iterator is positioned at head (before first entry) - or tail (beyond last entry).

+

Gets key and value terms at the current map iterator position.

+

On success, sets *key and *value and returns + true. Returns false if the iterator is positioned at + head (before first entry) or tail (beyond last entry).

- intenif_map_iterator_is_head(ErlNifEnv *env, ErlNifMapIterator *iter) - Check if map iterator is positioned before first + intenif_map_iterator_is_head(ErlNifEnv *env, + ErlNifMapIterator *iter) + Check if map iterator is positioned before first. -

Return true if map iterator iter is positioned - before first entry.

+

Returns true if map iterator iter is positioned + before the first entry.

- intenif_map_iterator_is_tail(ErlNifEnv *env, ErlNifMapIterator *iter) - Check if map iterator is positioned after last + intenif_map_iterator_is_tail(ErlNifEnv *env, + ErlNifMapIterator *iter) + Check if map iterator is positioned after last. -

Return true if map iterator iter is positioned - after last entry.

+

Returns true if map iterator iter is positioned + after the last entry.

- intenif_map_iterator_next(ErlNifEnv *env, ErlNifMapIterator *iter) - Increment map iterator to point to next entry + intenif_map_iterator_next(ErlNifEnv *env, + ErlNifMapIterator *iter) + Increment map iterator to point to next entry. -

Increment map iterator to point to next key-value entry. - Return true if the iterator is now positioned at a valid key-value entry, - or false if the iterator is positioned at the tail (beyond the last - entry).

+

Increments map iterator to point to the next key-value entry.

+

Returns true if the iterator is now positioned at a valid + key-value entry, or false if the iterator is positioned at + the tail (beyond the last entry).

- intenif_map_iterator_prev(ErlNifEnv *env, ErlNifMapIterator *iter) - Decrement map iterator to point to previous entry + intenif_map_iterator_prev(ErlNifEnv *env, + ErlNifMapIterator *iter) + Decrement map iterator to point to previous entry. -

Decrement map iterator to point to previous key-value entry. - Return true if the iterator is now positioned at a valid key-value entry, - or false if the iterator is positioned at the head (before the first - entry).

+

Decrements map iterator to point to the previous key-value entry.

+

Returns true if the iterator is now positioned at a valid + key-value entry, or false if the iterator is positioned at + the head (before the first entry).

- ErlNifTimeenif_monotonic_time(ErlNifTimeUnit time_unit) - Get Erlang Monotonic Time + ErlNifTime + enif_monotonic_time(ErlNifTimeUnit time_unit) + + Get Erlang monotonic time. - -

Arguments:

- - time_unit - Time unit of returned value. - -

- Returns the current - Erlang - monotonic time. Note that it is not uncommon with - negative values. -

-

Returns ERL_NIF_TIME_ERROR if called with an invalid - time unit argument, or if called from a thread that is not a - scheduler thread.

-

See also: - ErlNifTime and - ErlNifTimeUnit. -

+ +

Returns the current + + Erlang monotonic time. Notice that it is not uncommon with + negative values.

+

time_unit is the time unit of the returned value.

+

Returns ERL_NIF_TIME_ERROR if called with an invalid time + unit argument, or if called from a thread that is not a scheduler + thread.

+

See also ErlNifTime + and ErlNifTimeUnit. +

ErlNifMutex * - enif_mutex_create(char *name) - - -

Same as erl_drv_mutex_create. -

+ enif_mutex_create(char *name) + + +

Same as + erl_drv_mutex_create.

void - enif_mutex_destroy(ErlNifMutex *mtx) - - -

Same as erl_drv_mutex_destroy. -

+ enif_mutex_destroy(ErlNifMutex *mtx) + + +

Same as + erl_drv_mutex_destroy.

void - enif_mutex_lock(ErlNifMutex *mtx) - - -

Same as erl_drv_mutex_lock. -

+ enif_mutex_lock(ErlNifMutex *mtx) + + +

Same as + erl_drv_mutex_lock.

- - int + int enif_mutex_trylock(ErlNifMutex *mtx) - - -

Same as erl_drv_mutex_trylock. -

+ + +

Same as + erl_drv_mutex_trylock.

void - enif_mutex_unlock(ErlNifMutex *mtx) - - -

Same as erl_drv_mutex_unlock. -

+ enif_mutex_unlock(ErlNifMutex *mtx)
+ + +

Same as + erl_drv_mutex_unlock.

ERL_NIF_TERM - enif_now_time(ErlNifEnv *env) - - -

Retuns an erlang:now() timestamp. - The enif_now_time function is deprecated.

+ enif_now_time(ErlNifEnv *env) + + +

Returns an + erlang:now() time stamp.

+

This function is deprecated.

ErlNifResourceType * - enif_open_resource_type(ErlNifEnv* env, - const char* module_str, const char* name, - ErlNifResourceDtor* dtor, ErlNifResourceFlags flags, ErlNifResourceFlags* tried) - Create or takeover a resource type - -

Create or takeover a resource type identified by the string - name and give it the destructor function pointed to by dtor. - Argument flags can have the following values:

- - ERL_NIF_RT_CREATE - Create a new resource type that does not already exist. - ERL_NIF_RT_TAKEOVER - Open an existing resource type and take over ownership of all its instances. - The supplied destructor dtor will be called both for existing instances - as well as new instances not yet created by the calling NIF library. - -

The two flag values can be combined with bitwise-or. The name of the - resource type is local to the calling module. Argument module_str - is not (yet) used and must be NULL. The dtor may be NULL - in case no destructor is needed.

-

On success, return a pointer to the resource type and *tried - will be set to either ERL_NIF_RT_CREATE or - ERL_NIF_RT_TAKEOVER to indicate what was actually done. - On failure, return NULL and set *tried to flags. - It is allowed to set tried to NULL.

-

Note that enif_open_resource_type is only allowed to be called in the three callbacks - load, reload - and upgrade.

+ enif_open_resource_type(ErlNifEnv* env, const char* + module_str, const char* name, ErlNifResourceDtor* dtor, + ErlNifResourceFlags flags, ErlNifResourceFlags* tried) + + Create or takeover a resource type. + +

Creates or takes over a resource type identified by the string + name and gives it the destructor function pointed to by + dtor. + Argument flags can have the following values:

+ + ERL_NIF_RT_CREATE + Creates a new resource type that does not already exist. + ERL_NIF_RT_TAKEOVER + Opens an existing resource type and takes over ownership of all + its instances. The supplied destructor dtor is called both + for existing instances and new instances not yet created by the + calling NIF library. + +

The two flag values can be combined with bitwise OR. The resource + type name is local to the calling module. Argument module_str + is not (yet) used and must be NULL. dtor can be + NULL if no destructor is needed.

+

On success, the function returns a pointer to the resource type and + *tried is set to either ERL_NIF_RT_CREATE or + ERL_NIF_RT_TAKEOVER to indicate what was done. On failure, + returns NULL and sets *tried to flags. + It is allowed to set tried to NULL.

+

Notice that enif_open_resource_type is only allowed to be + called in the three callbacks + load, + reload, and + upgrade.

- int - enif_port_command(ErlNifEnv* env, const ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg) - Send a port_command to to_port - -

This function works the same as erlang:port_command/2 - except that it is always completely asynchronous.

- - env - The environment of the calling process. May not be NULL. - *to_port - The port id of the receiving port. The port id should refer to a - port on the local node. - msg_env - The environment of the message term. Can be a process - independent environment allocated with - enif_alloc_env or NULL. - msg - The message term to send. The same limitations apply as on the - payload to erlang:port_command/2. - -

Using a msg_env of NULL is an optimization which groups together - calls to enif_alloc_env, enif_make_copy, enif_port_command - and enif_free_env into one call. This optimization is only usefull - when a majority of the terms are to be copied from env to the msg_env.

-

This function return true if the command was successfully sent; otherwise, - false. The call may return false if it detects that the command failed for some - reason. For example, *to_port does not refer to a local port, if currently - executing process, i.e. the sender, is not alive, or if msg is invalid.

-

See also: enif_get_local_port.

+ intenif_port_command(ErlNifEnv* env, const + ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg) + + Send a port_command to to_port. + +

Works as + erlang:port_command/2, + except that it is always completely asynchronous.

+ + env + The environment of the calling process. Must not be + NULL. + *to_port + The port ID of the receiving port. The port ID is to refer to a + port on the local node. + msg_env + The environment of the message term. Can be a process-independent + environment allocated with + enif_alloc_env or NULL. + msg + The message term to send. The same limitations apply as on the + payload to + erlang:port_command/2. + +

Using a msg_env of NULL is an optimization, which + groups together calls to enif_alloc_env, enif_make_copy, + enif_port_command, and enif_free_env into one call. + This optimization is only useful when a majority of the terms are to + be copied from env to msg_env.

+

Returns true if the command is successfully sent. Returns + false if the command fails, for example:

+ + *to_port does not refer to a local port. + The currently executing process (that is, the sender) is not + alive. + msg is invalid. + +

See also + enif_get_local_port.

void * - enif_priv_data(ErlNifEnv* env) - Get the private data of a NIF library + enif_priv_data(ErlNifEnv* env) + Get the private data of a NIF library. -

Return the pointer to the private data that was set by load, - reload or upgrade.

-

Was previously named enif_get_data.

+

Returns the pointer to the private data that was set by + load, + reload, or + upgrade.

+

Was previously named enif_get_data.

- ERL_NIF_TERM - enif_raise_exception(ErlNifEnv* env, ERL_NIF_TERM reason) - Raise a NIF error exception + ERL_NIF_TERMenif_raise_exception(ErlNifEnv* + env, ERL_NIF_TERM reason) + Raise a NIF error exception. -

Create an error exception with the term reason to be returned from a NIF, - and associate it with the environment env. Once a NIF or any function it calls - invokes enif_raise_exception, the runtime ensures that the exception it creates - is raised when the NIF returns, even if the NIF attempts to return a non-exception - term instead. The return value from enif_raise_exception may be used only as - the return value from the NIF that invoked it (directly or indirectly) or be passed - to enif_is_exception, but - not to any other NIF API function.

-

See also: enif_has_pending_exception - and enif_make_badarg.

+

Creates an error exception with the term reason to be + returned from a NIF, and associates it with environment env. + Once a NIF or any function it calls invokes + enif_raise_exception, the runtime ensures that the exception + it creates is raised when the NIF returns, even if the NIF attempts + to return a non-exception term instead.

+

The return value from enif_raise_exception can only be used + as the return value from the NIF that invoked it (directly or + indirectly) or be passed to + enif_is_exception, but not to any other NIF API + function.

+

See also + enif_has_pending_exception and + + enif_make_badarg.

int - enif_realloc_binary(ErlNifBinary* bin, size_t size) - Change the size of a binary + enif_realloc_binary(ErlNifBinary* bin, size_t size) + + Change the size of a binary. -

Change the size of a binary bin. The source binary - may be read-only, in which case it will be left untouched and - a mutable copy is allocated and assigned to *bin. Return true on success, - false if memory allocation failed.

+

Changes the size of a binary bin. The source binary + can be read-only, in which case it is left untouched and + a mutable copy is allocated and assigned to *bin.

+

Returns true on success, or false if memory allocation + failed.

void - enif_release_binary(ErlNifBinary* bin) - Release a binary + enif_release_binary(ErlNifBinary* bin) + Release a binary. -

Release a binary obtained from enif_alloc_binary.

+

Releases a binary obtained from + + enif_alloc_binary.

void - enif_release_resource(void* obj) - Release a resource object + enif_release_resource(void* obj) + Release a resource object. -

Remove a reference to resource object objobtained from - enif_alloc_resource. - The resource object will be destructed when the last reference is removed. - Each call to enif_release_resource must correspond to a previous - call to enif_alloc_resource or - enif_keep_resource. - References made by enif_make_resource - can only be removed by the garbage collector.

+

Removes a reference to resource object objobtained from + + enif_alloc_resource. + The resource object is destructed when the last reference is removed. + Each call to enif_release_resource must correspond to a + previous call to enif_alloc_resource or + + enif_keep_resource. + References made by + enif_make_resource + can only be removed by the garbage collector.

ErlNifRWLock * - enif_rwlock_create(char *name) - - -

Same as erl_drv_rwlock_create. -

+ enif_rwlock_create(char *name) + + +

Same as + erl_drv_rwlock_create.

void - enif_rwlock_destroy(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_destroy. -

+ enif_rwlock_destroy(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_destroy.

void - enif_rwlock_rlock(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_rlock. -

+ enif_rwlock_rlock(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_rlock.

void - enif_rwlock_runlock(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_runlock. -

+ enif_rwlock_runlock(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_runlock.

void - enif_rwlock_rwlock(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_rwlock. -

+ enif_rwlock_rwlock(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_rwlock.

void - enif_rwlock_rwunlock(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_rwunlock. -

+ enif_rwlock_rwunlock(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_rwunlock.

int - enif_rwlock_tryrlock(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_tryrlock. -

+ enif_rwlock_tryrlock(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_tryrlock.

int - enif_rwlock_tryrwlock(ErlNifRWLock *rwlck) - - -

Same as erl_drv_rwlock_tryrwlock. -

+ enif_rwlock_tryrwlock(ErlNifRWLock *rwlck) + + +

Same as + erl_drv_rwlock_tryrwlock.

- ERL_NIF_TERM - enif_schedule_nif(ErlNifEnv* env, const char* fun_name, int flags, ERL_NIF_TERM (*fp)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]), int argc, const ERL_NIF_TERM argv[]) - Schedule a NIF for execution - -

Schedule NIF fp to execute. This function allows an application to break up long-running - work into multiple regular NIF calls or to schedule a dirty NIF - to execute on a dirty scheduler thread (note that the dirty NIF functionality described here is - experimental and that you have to enable support for dirty schedulers when building OTP in - order to try the functionality out).

-

The fun_name argument provides a name for the NIF being scheduled for execution. If it cannot - be converted to an atom, enif_schedule_nif returns a badarg exception.

-

The flags argument must be set to 0 for a regular NIF, or if the emulator was built the - experimental dirty scheduler support enabled, flags can be set to either ERL_NIF_DIRTY_JOB_CPU_BOUND - if the job is expected to be CPU-bound, or ERL_NIF_DIRTY_JOB_IO_BOUND for jobs that will - be I/O-bound. If dirty scheduler threads are not available in the emulator, a try to schedule such a job - will result in a badarg exception.

- -

The argc and argv arguments can either be the originals passed into the calling NIF, or - they can be values created by the calling NIF.

-

The calling NIF must use the return value of enif_schedule_nif as its own return value.

-

Be aware that enif_schedule_nif, as its name implies, only schedules the - NIF for future execution. The calling NIF does not block waiting for the scheduled NIF to - execute and return, which means that the calling NIF can't expect to receive the scheduled NIF + ERL_NIF_TERMenif_schedule_nif(ErlNifEnv* env, + const char* fun_name, int flags, ERL_NIF_TERM (*fp)(ErlNifEnv* env, int + argc, const ERL_NIF_TERM argv[]), int argc, const ERL_NIF_TERM + argv[]) + Schedule a NIF for execution. + +

Schedules NIF fp to execute. This function allows an + application to break up long-running work into multiple regular NIF + calls or to schedule a + dirty NIF to execute on a dirty scheduler thread.

+

The dirty NIF functionality described here is + experimental. You have to enable support for dirty + schedulers when building OTP to try out the functionality.

+ + fun_name + +

Provides a name for the NIF that is scheduled for execution. + If it cannot be converted to an atom, enif_schedule_nif + returns a badarg exception.

+
+ flags + +

Must be set to 0 for a regular NIF. If the emulator was + built with the experimental dirty scheduler support enabled, + flags can be set to either + ERL_NIF_DIRTY_JOB_CPU_BOUND if the job is expected to be + CPU-bound, or ERL_NIF_DIRTY_JOB_IO_BOUND for + jobs that will be I/O-bound. If dirty scheduler threads are not + available in the emulator, an attempt to schedule such a job + results in a badarg exception.

+
+ argc and argv + +

Can either be the originals passed into the calling NIF, + or can be values created by the calling NIF.

+
+
+

The calling NIF must use the return value of + enif_schedule_nif as its own return value.

+

Be aware that enif_schedule_nif, as its name implies, only + schedules the NIF for future execution. The calling NIF does not + block waiting for the scheduled NIF to execute and return. This means + that the calling NIF cannot expect to receive the scheduled NIF return value and use it for further operations.

ErlNifPid * - enif_self(ErlNifEnv* caller_env, ErlNifPid* pid) - Get the pid of the calling process + enif_self(ErlNifEnv* caller_env, ErlNifPid* pid) + + Get the pid of the calling process. -

Initialize the pid variable *pid to represent the - calling process. Return pid.

+

Initializes the pid variable *pid to represent the + calling process.

+

Returns pid.

- int - enif_send(ErlNifEnv* env, ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg) - Send a message to a process - -

Send a message to a process.

- - env - The environment of the calling process. Must be NULL if and - only if calling from a created thread. - *to_pid - The pid of the receiving process. The pid should refer to a process on the local node. - msg_env - The environment of the message term. Must be a process - independent environment allocated with - enif_alloc_env or NULL. - msg - The message term to send. - -

Return true if the message was successfully sent; otherwise, false. The send - operation will fail if *to_pid does not refer to an alive local process, - or if currently executing process, i.e. the sender, is not alive.

-

The message environment msg_env with all its terms (including - msg) will be invalidated by a successful call to enif_send. The environment - should either be freed with enif_free_env - of cleared for reuse with enif_clear_env.

-

If msg_env is set to NULL the msg term is copied and - the original term and its environemt is still valid after the call.

-

This function is only thread-safe when the emulator with SMP support is used. - It can only be used in a non-SMP emulator from a NIF-calling thread.

-

Passing msg_env as NULL is only supported since - erts-8.0 (OTP 19).

+ intenif_send(ErlNifEnv* env, ErlNifPid* to_pid, + ErlNifEnv* msg_env, ERL_NIF_TERM msg) + Send a message to a process. + +

Sends a message to a process.

+ + env + The environment of the calling process. Must be NULL + only if calling from a created thread. + *to_pid + The pid of the receiving process. The pid is to refer to a + process on the local node. + msg_env + The environment of the message term. Must be a + process-independent environment allocated with + enif_alloc_env + or NULL. + msg + The message term to send. + +

Returns true if the message is successfully sent. Returns + false if the send operation fails, that is:

+ + *to_pid does not refer to an alive local process. + The currently executing process (that is, the sender) is not + alive. + +

The message environment msg_env with all its terms (including + msg) is invalidated by a successful call to enif_send. + The environment is to either be freed with + + enif_free_env of cleared for reuse with + enif_clear_env.

+

If msg_env is set to NULL, the msg term is + copied and the original term and its environemt is still valid after + the call.

+

This function is only thread-safe when the emulator with SMP support + is used. It can only be used in a non-SMP emulator from a NIF-calling + thread.

+ +

Passing msg_env as NULL is only supported as from + ERTS 8.0 (Erlang/OTP 19).

+
unsigned - enif_sizeof_resource(void* obj) - Get the byte size of a resource object + enif_sizeof_resource(void* obj) + Get the byte size of a resource object. -

Get the byte size of a resource object obj obtained by - enif_alloc_resource.

+

Gets the byte size of resource object obj obtained by + + enif_alloc_resource.

- int - enif_snprintf(char *str, size_t size, const char *format, ...) - Format strings and Erlang terms + intenif_snprintf(char *str, size_t size, const + char *format, ...) + Format strings and Erlang terms. -

Similar to snprintf but this format string also accepts "%T" which formats Erlang terms. -

+

Similar to snprintf but this format string also accepts + "%T", which formats Erlang terms.

- void - enif_system_info(ErlNifSysInfo *sys_info_ptr, size_t size) - Get information about the Erlang runtime system + voidenif_system_info(ErlNifSysInfo + *sys_info_ptr, size_t size) + Get information about the Erlang runtime system. -

Same as driver_system_info. -

+

Same as + driver_system_info.

- int - enif_term_to_binary(ErlNifEnv *env, ERL_NIF_TERM term, ErlNifBinary *bin) - Convert a term to the external format - -

Allocates a new binary with enif_alloc_binary - and stores the result of encoding term according to the Erlang external term format.

-

Returns true on success or false if allocation failed.

-

See also: - erlang:term_to_binary/1 and - enif_binary_to_term. -

-
+ intenif_term_to_binary(ErlNifEnv *env, + ERL_NIF_TERM term, ErlNifBinary *bin) + Convert a term to the external format. + +

Allocates a new binary with + enif_alloc_binary and stores the result of encoding + term according to the Erlang external term format.

+

Returns true on success, or false if the allocation + fails.

+

See also + erlang:term_to_binary/1 and + + enif_binary_to_term.

+
- int - enif_thread_create(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts) - - -

Same as erl_drv_thread_create. -

+ intenif_thread_create(char *name,ErlNifTid + *tid,void * (*func)(void *),void *args,ErlNifThreadOpts + *opts) + + +

Same as + erl_drv_thread_create.

void - enif_thread_exit(void *resp) - - -

Same as erl_drv_thread_exit. -

+ enif_thread_exit(void *resp) + + +

Same as + erl_drv_thread_exit.

int - enif_thread_join(ErlNifTid, void **respp) - - -

Same as erl_drv_thread_join . -

+ enif_thread_join(ErlNifTid, void **respp) + + +

Same as + erl_drv_thread_join.

ErlNifThreadOpts * - enif_thread_opts_create(char *name) - - -

Same as erl_drv_thread_opts_create. -

+ enif_thread_opts_create(char *name) + + +

Same as + erl_drv_thread_opts_create.

void - enif_thread_opts_destroy(ErlNifThreadOpts *opts) - - -

Same as erl_drv_thread_opts_destroy. -

+ enif_thread_opts_destroy(ErlNifThreadOpts *opts) + + + +

Same as + erl_drv_thread_opts_destroy.

ErlNifTid - enif_thread_self(void) - - -

Same as erl_drv_thread_self. -

+ enif_thread_self(void) + + +

Same as + erl_drv_thread_self.

int enif_thread_type(void) - Determine type of current thread - -

Determine the type of currently executing thread. A positive value - indicates a scheduler thread while a negative value or zero indicates - another type of thread. Currently the following specific types exist - (which may be extended in the future):

- - ERL_NIF_THR_UNDEFINED -

Undefined thread that is not a scheduler thread.

- ERL_NIF_THR_NORMAL_SCHEDULER -

A normal scheduler thread.

- ERL_NIF_THR_DIRTY_CPU_SCHEDULER -

A dirty CPU scheduler thread.

- ERL_NIF_THR_DIRTY_IO_SCHEDULER -

A dirty I/O scheduler thread.

-
-
+ Determine type of current thread + +

Determine the type of currently executing thread. A positive value + indicates a scheduler thread while a negative value or zero indicates + another type of thread. Currently the following specific types exist + (which may be extended in the future):

+ + ERL_NIF_THR_UNDEFINED +

Undefined thread that is not a scheduler thread.

+ ERL_NIF_THR_NORMAL_SCHEDULER +

A normal scheduler thread.

+ ERL_NIF_THR_DIRTY_CPU_SCHEDULER +

A dirty CPU scheduler thread.

+ ERL_NIF_THR_DIRTY_IO_SCHEDULER +

A dirty I/O scheduler thread.

+
+
ErlNifTime - enif_time_offset(ErlNifTimeUnit time_unit) - Get current Time Offset - - -

Arguments:

- - time_unit - Time unit of returned value. - -

Returns the current time offset between - Erlang monotonic time - and - Erlang system time - converted into the time_unit passed as argument.

-

Returns ERL_NIF_TIME_ERROR if called with an invalid - time unit argument, or if called from a thread that is not a - scheduler thread.

-

See also: - ErlNifTime and - ErlNifTimeUnit. -

+ enif_time_offset(ErlNifTimeUnit time_unit) + Get current time offset. + + +

Returns the current time offset between + + Erlang monotonic time and + + Erlang system time + converted into the time_unit passed as argument.

+

time_unit is the time unit of the returned value.

+

Returns ERL_NIF_TIME_ERROR if called with an invalid + time unit argument or if called from a thread that is not a + scheduler thread.

+

See also ErlNifTime + and + ErlNifTimeUnit.

void * - enif_tsd_get(ErlNifTSDKey key) - - -

Same as erl_drv_tsd_get. -

+ enif_tsd_get(ErlNifTSDKey key) + + +

Same as + erl_drv_tsd_get.

int - enif_tsd_key_create(char *name, ErlNifTSDKey *key) - - -

Same as erl_drv_tsd_key_create. -

-
-
+ enif_tsd_key_create(char *name, ErlNifTSDKey *key) + + + +

Same as + erl_drv_tsd_key_create.

+
+
void - enif_tsd_key_destroy(ErlNifTSDKey key) - - -

Same as erl_drv_tsd_key_destroy. -

+ enif_tsd_key_destroy(ErlNifTSDKey key) + + +

Same as + erl_drv_tsd_key_destroy.

void - enif_tsd_set(ErlNifTSDKey key, void *data) - - -

Same as erl_drv_tsd_set. -

+ enif_tsd_set(ErlNifTSDKey key, void *data) + + +

Same as + erl_drv_tsd_set.

+
- SEE ALSO -

erlang:load_nif/2

+ See Also +

+ erlang:load_nif/2

-- cgit v1.2.3