aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_nif_api_funcs.h
AgeCommit message (Collapse)Author
2018-03-23Add enif_make_map_from_arraysJohn Högberg
2018-03-22erts: Add enif_vfprintf and enif_vsnprintfSverker Eriksson
2018-03-22erts: Add enif_*_name functionsSverker Eriksson
2017-11-30Add enif_ioq_peek_headJohn Högberg
This introduces a way to retrieve erlang terms from NIF IO queues without having to resort to copying. OTP-14797
2017-09-05erts: Add nif ioqLukas Larsson
2017-05-22Add enif_whereis_...() functionsTed Burghart
#### Why do we need this new feature? There are cases when a NIF needs to send a message, using `enif_send()`, to a long-lived process with a registered name. A common use-case is logging, where asynchronous fire-and-forget messages are the norm. There can also be cases where a yielding or dirty NIF or background thread may request a callback from a service with additional information it needs to complete its operation, yielding or waiting (with suitable timeouts, etc) until its state has been updated through the NIF module's API. NIFs can only send messages to pids, and the lack of name resolution leaves a complicated dance between separate monitoring processes and the NIF as the only way to keep a NIF informed of the whereabouts of such long-lived processes. Providing a reliable, built-in facility for NIFs to resolve process (or port) names simplifies these use cases considerably. #### Risks or uncertain artifacts? Testing has not exposed any significant risk. The implementation behaves as expected on regular and dirty scheduler threads as well as non-scheduler threads. By constraining the `enif_whereis_...()` functions to their minimal scopes and using patterns consistent with related functions, the implementation, testing, and maintenance burden is low. The API and behavior of existing functions is unchanged. #### How did you solve it? While extending `enif_send()` to operate on a pid or an atom (as `erlang:send/2` does) was attractive, it would have entailed changing the type of its `to_pid` parameter and thereby breaking backward compatibility. The same consideration applies to `enif_port_command()`. That leaves a choice between 1, 2, or 3 new functions: 1. `enif_whereis()` 2. `enif_whereis_pid()` and `enif_whereis_port()` 3. All of the above. While option (1), directly mimicking the behavior of `erlang:whereis/1`, is appealing, it poses potential problems if `pid()` or `port()` are subsequently implemented as non-integral types that must be bound to an owning `ErlNifEnv` instance. Therefore, option (2) has been chosen to use `ErlNifPid`/`ErlNifPort` structures in the API to maintain proper term ownership semantics.
2017-05-12use ErlNifMonitor instead of ErlDrvMonitor for enif_monitor/demonitorDaniel Goertzen
2017-05-04Update copyright yearRaimo Niskanen
2017-04-27Move enif_hash last to not break WindowsSverker Eriksson
2017-04-22erts: Allow for easier future enif_hash expansionGuilherme Andrade
Allow for expanding support to 64-bit hashes without breaking the interface.
2017-04-22erts: Support custom salt in enif_hashGuilherme Andrade
2017-04-20erts: Refactor enif_phash2 into enif_hashGuilherme Andrade
A more generic hashing function which can also hash terms based on `make_internal_hash'.
2017-04-20erts: Remove enif_phash2_rangedGuilherme Andrade
2017-04-19erts: Add enif_phash2 and enif_phash2_rangedGuilherme Andrade
These allow one to hash VM terms from NIF code.
2017-02-20erts: Add enif_compare_monitorsSverker Eriksson
# Conflicts: # erts/emulator/test/nif_SUITE_data/nif_SUITE.c
2017-02-09erts: Add pid argument to enif_selectSverker Eriksson
2017-02-09erts: Add enif_monitor_process and enif_demonitor_processSverker Eriksson
2016-11-30erts: Add enif_select & enif_open_resource_type_xSverker Eriksson
2016-06-08Replace enif_is_on_dirty_scheduler() with enif_thread_type()Rickard Green
2016-05-13Merge branch 'egil/erts/nif-format_term/OTP-13580'Björn-Egil Dahlberg
* egil/erts/nif-format_term/OTP-13580: runtime_tools: Change erts_snprintf to enif_snprintf erts: Document enif_snprintf erts: Add tests for enif_snprintf erts: Add enif_snprintf Conflicts: erts/emulator/beam/erl_nif_api_funcs.h
2016-05-11Add better support for communication with a process executing dirty NIFRickard Green
- Termination of a process... - Modify trace flags of process... - Process info on process... - Register/unregister of name on process... - Set group leader on process... ... while it is executing a dirty NIF.
2016-05-11erts: Add enif_snprintfBjörn-Egil Dahlberg
* Add the capability to format erlang terms to a char buffer in nifs. * Bump NIF version to 2.11
2016-05-10Remove conditional dirty schedulers APIRickard Green
2016-04-13Merge branch 'henrik/update-copyrightyear'Henrik Nord
* henrik/update-copyrightyear: update copyright-year
2016-03-29erts: Improve enif_binary_to_termSverker Eriksson
* Accept a raw data buffer instead of ErlNifBinary * Accept option ERL_NIF_BIN2TERM_SAFE * Return number of read bytes
2016-03-29erts: Add enif_port_commandLukas Larsson
2016-03-29erts: Add enif_term_to_binary and enif_binary_to_termLukas Larsson
2016-03-29erts: Add enif_is_process/port_aliveLukas Larsson
2016-03-29erts: Add enif_cpu/now_time and enif_make_unique_integerLukas Larsson
2016-03-15update copyright-yearHenrik Nord
2016-01-21Introduce time management in native APIsRickard Green
2015-11-26erts: Add enif_getenvSverker Eriksson
to read OS environment variables in a safe and portable way.
2015-08-11fix unused parameter warning in enif_make_pidDaniel Goertzen
2015-06-18Change license text to APLv2Bruce Yinhe
2015-05-26Add enif_raise_exceptionSteve Vinoski
Add enif_raise_exception function to allow NIFs to raise error exceptions holding any Erlang terms. This does not replace or deprecate the enif_make_badarg function, though, because raising badarg errors is so idiomatic in NIFs. Reimplement enif_make_badarg on top of enif_raise_exception. Add new tests for enif_raise_exception for both normal and dirty NIFs. Add documentation for enif_raise_exception.
2015-05-26Enhance enif_has_pending_exceptionSteve Vinoski
Sverker Eriksson came up with the following idea: to handle a future ability for NIFs to raise more than just badarg exceptions, modify the recently-added enif_has_pending_exception function to take a second argument: a pointer to ERL_NIF_TERM. If this argument is a null pointer, ignore it. Otherwise, if the first argument, an ErlNifEnv*, has an associated exception, set the pointed-to ERL_NIF_TERM of the second argument to the value of the exception term. Add new tests and documentation for this modification.
2015-04-15erts: Add enif_has_pending_exceptionSverker Eriksson
2014-09-12erts: Remove enif_have_dirty_schedulers()Sverker Eriksson
and add 'dirty_scheduler_support' to ErlNifSysInfo
2014-09-10erts: Correct dirty scheduler NIF API for WindowsSverker Eriksson
enif_schedule_nif() put LAST of the unconditional functions to keep the order which is vital for ABI compatibility on Windows. The conditional dirty scheduler stuff moved down at the end of the list to keep them out of the way. We don't want them mess things up then they become unconditional some day.
2014-08-28add enif_schedule_nif() to NIF APISteve Vinoski
In the #erlang IRC channel Anthony Ramine once mentioned the idea of allowing a NIF to use an emulator trap, similar to a BIF trap, to schedule another NIF for execution. This is exactly how dirty NIFs were implemented for Erlang/OTP 17.0, so this commit refactors and generalizes that dirty NIF code to support a new enif_schedule_nif() API function. The enif_schedule_nif() function allows a long-running NIF to be broken into separate NIF invocations. The NIF first executes part of the long-running task, then calls enif_schedule_nif() to schedule a NIF for later execution to continue the task. Any number of NIFs can be scheduled in this manner, one after another. Since the emulator regains control between invocations, this helps avoid problems caused by native code tying up scheduler threads for too long. The enif_schedule_nif() function also replaces the original experimental dirty NIF API. The function takes a flags parameter that a caller can use to indicate the NIF should be scheduled onto either a dirty CPU scheduler thread, a dirty I/O scheduler thread, or scheduled as a regular NIF on a regular scheduler thread. With this change, the original experimental enif_schedule_dirty_nif(), enif_schedule_dirty_nif_finalizer() and enif_dirty_nif_finalizer() API functions are no longer needed and have been removed. Explicit scheduling of a dirty NIF finalization function is no longer necessary; if an application wants similar functionality, it can have a dirty NIF just invoke enif_schedule_nif() to schedule a non-dirty NIF to complete its task. Lift the restriction that dirty NIFs can't call enif_make_badarg() to raise an exception. This was a problem with the original dirty NIF API because it forced developers to get and check all incoming arguments in a regular NIF, and then schedule the dirty NIF which then had to get all the arguments again. Now, the argument checking can be done in the dirty NIF and it can call enif_make_badarg() itself to flag incorrect arguments. Extend the ErlNifFunc struct with a new flags field that allows NIFs to be declared as dirty. The default value for this field is 0, indicating a regular NIF, so it's backwards compatible with all existing statically initialized ErlNifFunc struct instances, and so such instances require no code changes. Defining the flags field with a value of ERL_NIF_DIRTY_JOB_CPU_BOUND indicates that the NIF should execute on a dirty CPU scheduler thread, or defining it with a value of ERL_NIF_DIRTY_JOB_IO_BOUND indicates that the NIF should execute on a dirty I/O scheduler thread. Any other flags field value causes a NIF library loading error. Extend the ErlNifEntry struct with a new options field that indicates whether a NIF library was built with support for optional features such as dirty NIFs. When a NIF library is loaded, the runtime checks the options field to ensure compatibility. If a NIF library built with dirty NIF support is loaded into a runtime that does not support dirty NIFs, and the library defines one or more ErlNifFunc entries with non-zero flags fields indicating dirty NIFs, a NIF library loading error results. There is no error if a NIF library built with dirty NIF support is loaded into a runtime that does not support dirty NIFs but the library does not have any dirty NIFs. It is also not an error if a library without dirty NIF support is loaded into a runtime built with dirty NIF support. Add documentation and tests for enif_schedule_nif().
2014-01-29erts: Fixup enif_make_map_put on windowsBjörn-Egil Dahlberg
2014-01-29erts: Change 'size' argument of enif_get_map_size from int* to size_t*Sverker Eriksson
2014-01-29erts: Increase version for NIF API and reject experimental v2.5Sverker Eriksson
2014-01-29erts: Remove enif_find_map_valueSverker Eriksson
as it does the same thing as enif_get_map_value. Replace with placeholder to be ABI backward compatible on Windows as long as enif_find_map_value is not called.
2014-01-29erts: NIFs Map API fixupBjörn-Egil Dahlberg
2014-01-29erts: Add NIFs for MapsBjörn-Egil Dahlberg
- int enif_is_map(ErlNifEnv* env, ERL_NIF_TERM map) - int enif_get_map_size(ErlNifEnv *env, ERL_NIF_TERM, int*) - ERL_NIF_TERM enif_make_new_map(ErlNifEnv *env) - int enif_make_map_put(ErlNifEnv *env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value, ERL_NIF_TERM* map_out) - int enif_get_map_value(ErlNifEnv *env, ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value) - int enif_find_map_value(ErlNifEnv *env, ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value) - int enif_make_map_update(ErlNifEnv *env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value, ERL_NIF_TERM* map_out) - int enif_make_map_remove(ErlNifEnv *env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out) - int enif_map_iterator_create(ErlNifEnv *env, ERL_NIF_TERM map, ErlNifMapIterator *iter) - void enif_map_iterator_destroy(ErlNifEnv *env, ErlNifMapIterator *iter) - int enif_map_iterator_next(ErlNifEnv *env, ErlNifMapIterator *iter) - int enif_map_iterator_get_pair(ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value)
2014-01-28initial support for dirty schedulers and dirty NIFsSteve Vinoski
Add initial support for dirty schedulers. There are two types of dirty schedulers: CPU schedulers and I/O schedulers. By default, there are as many dirty CPU schedulers as there are normal schedulers and as many dirty CPU schedulers online as normal schedulers online. There are 10 dirty I/O schedulers (similar to the choice of 10 as the default for async threads). By default, dirty schedulers are disabled and conditionally compiled out. To enable them, you must pass --enable-dirty-schedulers to the top-level configure script when building Erlang/OTP. Current dirty scheduler support requires the emulator to be built with SMP support. This restriction will be lifted in the future. You can specify the number of dirty schedulers with the command-line options +SDcpu (for dirty CPU schedulers) and +SDio (for dirty I/O schedulers). The +SDcpu option is similar to the +S option in that it takes two numbers separated by a colon: C1:C2, where C1 specifies the number of dirty schedulers available and C2 specifies the number of dirty schedulers online. The +SDPcpu option allows numbers of dirty CPU schedulers available and dirty CPU schedulers online to be specified as percentages, similar to the existing +SP option for normal schedulers. The number of dirty CPU schedulers created and dirty CPU schedulers online may not exceed the number of normal schedulers created and normal schedulers online, respectively. The +SDio option takes only a single number specifying the number of dirty I/O schedulers available and online. There is no support yet for programmatically changing at run time the number of dirty CPU schedulers online via erlang:system_flag/2. Also, changing the number of normal schedulers online via erlang:system_flag(schedulers_online, NewSchedulersOnline) should ensure that there are no more dirty CPU schedulers than normal schedulers, but this is not yet implemented. You can retrieve the number of dirty schedulers by passing dirty_cpu_schedulers, dirty_cpu_schedulers_online, or dirty_io_schedulers to erlang:system_info/1. Currently only NIFs are able to access dirty scheduler functionality. Neither drivers nor BIFs currently support dirty schedulers. This restriction will be addressed in the future. If dirty scheduler support is present in the runtime, the initial status line Erlang prints before presenting its interactive prompt will include the indicator "[ds:C1:C2:I]" where "ds" indicates "dirty schedulers", "C1" indicates the number of dirty CPU schedulers available, "C2" indicates the number of dirty CPU schedulers online, and "I" indicates the number of dirty I/O schedulers. Document The dirty NIF API in the erl_nif man page. The API closely follows Rickard Green's presentation slides from his talk "Future Extensions to the Native Interface", presented at the 2011 Erlang Factory held in the San Francisco Bay Area. Rickard's slides are available online at http://bit.ly/1m34UHB . Document the new erl command-line options, the additions to erlang:system_info/1, and also add the erlang:system_flag/2 dirty scheduler documentation even though it's not yet implemented. To determine whether the dirty NIF API is available, native code can check to see whether the C preprocessor macro ERL_NIF_DIRTY_SCHEDULER_SUPPORT is defined. To check if dirty schedulers are available at run time, native code can call the boolean enif_have_dirty_schedulers() function, and Erlang code can call erlang:system_info(dirty_cpu_schedulers), which raises badarg if no dirty scheduler support is available. Add a simple dirty NIF test to the emulator NIF suite.
2013-02-13erts: Add enif_consume_timesliceSverker Eriksson
2013-01-25Update copyright yearsBjörn-Egil Dahlberg
2012-10-09crypto: Make unloading of crypto saferSverker Eriksson
Facts: crypto nif-lib registers callback functions that openssl uses for memory management and thread synchronization. The callback functions can only be set once, openssl does not allow changing the callback functions. Problem: If openssl is dynamicly linked to crypto, you might get s scenario where the crypto lib is unloaded while leaving openssl loaded with its old pointers to the unloaded crypto code intact. If crypto is then reloaded (by init:restart() for example), the crypto nif-lib might get relocated at a different address. crypto calls openssl which in turn calls the old invalid callback functions...kaboom. Solution: Break apart the callback functions into a separate dynamic lib that crypto loads with dlopen. When crypto is unloaded the callback lib is left in place to be reused if/when crypto is loaded again.