sys.h

Include dependency graph for sys.h:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "7" [label="stdbool.h" tooltip="stdbool.h"]
    "23" [label="refc_binary.h" tooltip="refc_binary.h"]
    "4" [label="atom.h" tooltip="atom.h"]
    "10" [label="assert.h" tooltip="assert.h"]
    "21" [label="utils.h" tooltip="utils.h"]
    "15" [label="synclist.h" tooltip="synclist.h"]
    "14" [label="list.h" tooltip="list.h"]
    "3" [label="stdint.h" tooltip="stdint.h"]
    "5" [label="stdlib.h" tooltip="stdlib.h"]
    "29" [label="context.h" tooltip="context.h"]
    "20" [label="memory.h" tooltip="memory.h"]
    "1" [label="/__w/AtomVM/AtomVM/src/libAtomVM/sys.h" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/sys.h" fillcolor="#BFBFBF"]
    "27" [label="module.h" tooltip="module.h"]
    "31" [label="valueshashtable.h" tooltip="valueshashtable.h"]
    "24" [label="resources.h" tooltip="resources.h"]
    "18" [label="term.h" tooltip="term.h"]
    "22" [label="stddef.h" tooltip="stddef.h"]
    "8" [label="erl_nif.h" tooltip="erl_nif.h"]
    "30" [label="exportedfunction.h" tooltip="exportedfunction.h"]
    "11" [label="limits.h" tooltip="limits.h"]
    "6" [label="atom_table.h" tooltip="atom_table.h"]
    "19" [label="string.h" tooltip="string.h"]
    "9" [label="term_typedef.h" tooltip="term_typedef.h"]
    "2" [label="globalcontext.h" tooltip="globalcontext.h"]
    "17" [label="smp.h" tooltip="smp.h"]
    "28" [label="atomshashtable.h" tooltip="atomshashtable.h"]
    "32" [label="time.h" tooltip="time.h"]
    "26" [label="timer_list.h" tooltip="timer_list.h"]
    "25" [label="mailbox.h" tooltip="mailbox.h"]
    "16" [label="stdio.h" tooltip="stdio.h"]
    "13" [label="ets.h" tooltip="ets.h"]
    "12" [label="inttypes.h" tooltip="inttypes.h"]
    "23" -> "7" [dir=forward tooltip="include"]
    "23" -> "5" [dir=forward tooltip="include"]
    "23" -> "14" [dir=forward tooltip="include"]
    "23" -> "24" [dir=forward tooltip="include"]
    "4" -> "3" [dir=forward tooltip="include"]
    "4" -> "5" [dir=forward tooltip="include"]
    "21" -> "22" [dir=forward tooltip="include"]
    "21" -> "16" [dir=forward tooltip="include"]
    "21" -> "5" [dir=forward tooltip="include"]
    "15" -> "16" [dir=forward tooltip="include"]
    "15" -> "14" [dir=forward tooltip="include"]
    "15" -> "17" [dir=forward tooltip="include"]
    "14" -> "7" [dir=forward tooltip="include"]
    "29" -> "2" [dir=forward tooltip="include"]
    "29" -> "14" [dir=forward tooltip="include"]
    "29" -> "25" [dir=forward tooltip="include"]
    "29" -> "17" [dir=forward tooltip="include"]
    "29" -> "18" [dir=forward tooltip="include"]
    "29" -> "26" [dir=forward tooltip="include"]
    "20" -> "3" [dir=forward tooltip="include"]
    "20" -> "5" [dir=forward tooltip="include"]
    "20" -> "8" [dir=forward tooltip="include"]
    "20" -> "9" [dir=forward tooltip="include"]
    "20" -> "21" [dir=forward tooltip="include"]
    "1" -> "2" [dir=forward tooltip="include"]
    "1" -> "27" [dir=forward tooltip="include"]
    "1" -> "3" [dir=forward tooltip="include"]
    "1" -> "32" [dir=forward tooltip="include"]
    "27" -> "7" [dir=forward tooltip="include"]
    "27" -> "3" [dir=forward tooltip="include"]
    "27" -> "4" [dir=forward tooltip="include"]
    "27" -> "6" [dir=forward tooltip="include"]
    "27" -> "28" [dir=forward tooltip="include"]
    "27" -> "29" [dir=forward tooltip="include"]
    "27" -> "30" [dir=forward tooltip="include"]
    "27" -> "2" [dir=forward tooltip="include"]
    "27" -> "18" [dir=forward tooltip="include"]
    "27" -> "31" [dir=forward tooltip="include"]
    "24" -> "5" [dir=forward tooltip="include"]
    "24" -> "8" [dir=forward tooltip="include"]
    "24" -> "14" [dir=forward tooltip="include"]
    "24" -> "20" [dir=forward tooltip="include"]
    "18" -> "7" [dir=forward tooltip="include"]
    "18" -> "3" [dir=forward tooltip="include"]
    "18" -> "16" [dir=forward tooltip="include"]
    "18" -> "5" [dir=forward tooltip="include"]
    "18" -> "19" [dir=forward tooltip="include"]
    "18" -> "20" [dir=forward tooltip="include"]
    "18" -> "23" [dir=forward tooltip="include"]
    "18" -> "21" [dir=forward tooltip="include"]
    "18" -> "9" [dir=forward tooltip="include"]
    "8" -> "9" [dir=forward tooltip="include"]
    "30" -> "18" [dir=forward tooltip="include"]
    "6" -> "7" [dir=forward tooltip="include"]
    "6" -> "4" [dir=forward tooltip="include"]
    "9" -> "10" [dir=forward tooltip="include"]
    "9" -> "11" [dir=forward tooltip="include"]
    "9" -> "12" [dir=forward tooltip="include"]
    "9" -> "3" [dir=forward tooltip="include"]
    "2" -> "3" [dir=forward tooltip="include"]
    "2" -> "4" [dir=forward tooltip="include"]
    "2" -> "6" [dir=forward tooltip="include"]
    "2" -> "8" [dir=forward tooltip="include"]
    "2" -> "13" [dir=forward tooltip="include"]
    "2" -> "14" [dir=forward tooltip="include"]
    "2" -> "25" [dir=forward tooltip="include"]
    "2" -> "17" [dir=forward tooltip="include"]
    "2" -> "15" [dir=forward tooltip="include"]
    "2" -> "18" [dir=forward tooltip="include"]
    "2" -> "26" [dir=forward tooltip="include"]
    "17" -> "7" [dir=forward tooltip="include"]
    "28" -> "4" [dir=forward tooltip="include"]
    "26" -> "7" [dir=forward tooltip="include"]
    "26" -> "3" [dir=forward tooltip="include"]
    "26" -> "14" [dir=forward tooltip="include"]
    "25" -> "7" [dir=forward tooltip="include"]
    "25" -> "14" [dir=forward tooltip="include"]
    "25" -> "9" [dir=forward tooltip="include"]
    "25" -> "21" [dir=forward tooltip="include"]
    "13" -> "14" [dir=forward tooltip="include"]
    "13" -> "15" [dir=forward tooltip="include"]
    "13" -> "18" [dir=forward tooltip="include"]
}

This graph shows which files directly or indirectly include sys.h:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "5" [label="/__w/AtomVM/AtomVM/src/libAtomVM/nifs.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/nifs.c"]
    "2" [label="/__w/AtomVM/AtomVM/src/libAtomVM/context.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/context.c"]
    "1" [label="/__w/AtomVM/AtomVM/src/libAtomVM/sys.h" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/sys.h" fillcolor="#BFBFBF"]
    "4" [label="/__w/AtomVM/AtomVM/src/libAtomVM/module.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/module.c"]
    "7" [label="/__w/AtomVM/AtomVM/src/libAtomVM/resources.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/resources.c"]
    "3" [label="/__w/AtomVM/AtomVM/src/libAtomVM/globalcontext.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/globalcontext.c"]
    "6" [label="/__w/AtomVM/AtomVM/src/libAtomVM/otp_socket.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/otp_socket.c"]
    "1" -> "2" [dir=back tooltip="include"]
    "1" -> "3" [dir=back tooltip="include"]
    "1" -> "4" [dir=back tooltip="include"]
    "1" -> "5" [dir=back tooltip="include"]
    "1" -> "6" [dir=back tooltip="include"]
    "1" -> "7" [dir=back tooltip="include"]
}

Platform specific functions.

This header defines platform dependent functions, that mostly deals with events. Some functions can be implemented by using functions defined and implemented in listeners.h header.

Typedefs

typedef struct EventListener EventListener

Event listener.

An event listener structure should be defined by the platform. Event listeners belong to the GlobalContext.listeners synchronized list.

typedef EventListener *(*event_handler_t)(GlobalContext *glb, EventListener *listener)

Event handlers (for ports)

The event handler is called from the scheduler thread but outside any process. It can send messages to processes using globalcontext_send_message function.

Result of this callback alters the list of handlers which is locked for writing when it is called. It can:

  • return listener, in which case the list is not modified

  • return NULL, in which case the entry is removed. The callback is responsible for freeing the listener.

  • return another listener, in which case the current listener is replaced by the other listener. The callback is responsible for freeing the previous listener if it is no longer needed.

Appending a listener is also possible by altering the list head.

This callback is defined for platforms using listeners.h header and can be ignored by others.

Param glb:

global context

Param listener:

the current listener

Return:

NULL if the current listener should be removed, listener if it should be kept or another listener if it should be replaced.

Enums

enum [anonymous]

Values:

enumerator SYS_POLL_EVENTS_DO_NOT_WAIT = 0
enumerator SYS_POLL_EVENTS_WAIT_FOREVER = -1
enum OpenAVMResult

Values:

enumerator AVM_OPEN_OK = 0
enumerator AVM_OPEN_FAILED_ALLOC = 1
enumerator AVM_OPEN_INVALID = 2
enumerator AVM_OPEN_CANNOT_OPEN = 3
enumerator AVM_OPEN_CANNOT_READ = 4
enumerator AVM_OPEN_NOT_SUPPORTED = 5

Functions

void sys_poll_events(GlobalContext *glb, int timeout_ms)

Poll events (from drivers and select events), with a timeout (in ms), or until sys_signal is called.

Depending on platforms, check all open file descriptors/queues and call drivers that should send messages to contexts (which will unblock them). With SMP builds, this function can be called from any scheduler.

If selectable events are supported on the platform, this function should also:

  • call select_event_destroy on select events that have close set to 1

  • include the set of ErlNifEvent that are marked for read or write in the select set, and if they are selected, call select_event_notify to send the notification.

select_event_count_and_destroy_closed defined in resources.h can be used to process closed select events.

Parameters:
  • glb – the global context.

  • timeout_ms – the number of ms to wait, SYS_POLL_EVENTS_WAIT_FOREVER to wait forever.

void sys_register_select_event(GlobalContext *glb, ErlNifEvent event, bool is_write)

Update the select set by adding an event for reading or writing.

This function probably should update set and call sys_signal so new set is taken into account.

Parameters:
  • glb – the global context.

  • event – the event (file descriptor) to add to the set

  • is_write – whether to add the event for writing (as opposed to reading)

void sys_unregister_select_event(GlobalContext *glb, ErlNifEvent event, bool is_write)

Update the select set by removing an event for reading or writing.

This function probably should update set and call sys_signal so new set is taken into account. After this function is called, sys_poll_events must check for closed select events.

Parameters:
  • glb – the global context.

  • event – the event (file descriptor) to remove from the set

  • is_write – whether to remove the event for writing (as opposed to reading)

void sys_register_listener(GlobalContext *global, EventListener *listener)

Register a listener.

This function is called by ports to register a listener which is a native alternative to select events. The actual definition of listeners is platform dependent.

Parameters:
  • global – the global context.

  • listener – the listener to register

void sys_unregister_listener(GlobalContext *global, EventListener *listener)

Unregister a listener.

This function is called by ports to unregister a listener which is a native alternative to select events. The actual definition of listeners is platform dependent.

Parameters:
  • global – the global context.

  • listener – the listener to unregister.

void sys_listener_destroy(struct ListHead *item)

Free a listener.

This function is called when the global context is destroyed on every remaining listener. An implementation is available in listeners.h.

Parameters:
  • item – list item

void sys_signal(GlobalContext *glb)

Interrupt the wait in sys_poll_events.

This function should signal the thread that is waiting in sys_poll_events so it returns before the timeout. It is mostly used for SMP builds, but also to abort sleep from driver callbacks on FreeRTOS.

Please note that this function may be called while no thread is waiting in sys_poll_events and this should have no effect. This function is called in scheduler loop (internal function scheduler_run0) and when scheduling processes.

Parameters:
  • glb – the global context.

enum OpenAVMResult sys_open_avm_from_file(GlobalContext *global, const char *path, struct AVMPackData **data)
void sys_time(struct timespec *t)

gets wall clock time

gets system wall clock time, used by erlang:system_time/1

Parameters:
  • t – the timespec that will be updated.

void sys_monotonic_time(struct timespec *t)

gets monotonic time

gets the time that is used by erlang:monotonic_time/1

Parameters:
  • t – the timespec that will be updated.

uint64_t sys_monotonic_time_u64()

gets monotonic time for timers

This function must return a non-overflowing counter in the highest precision the platform permits to make sure that we don’t have truncation errors when compared with sys_time or sys_monotonic_time. Returning the number of microseconds or nanoseconds since boot would work.

Returns:

a monotonic time in a system-chosen unit

uint64_t sys_monotonic_time_ms_to_u64(uint64_t ms)

convert a number of milliseconds to system-chosen unit

Parameters:
  • ms – the number of milliseconds to convert

Returns:

the result of the conversion

uint64_t sys_monotonic_time_u64_to_ms(uint64_t t)

convert a number in system-chosen unit to milliseconds

Parameters:
  • t – the number to convert

Returns:

the result of the conversion

Module *sys_load_module_from_file(GlobalContext *global, const char *path)

Loads a BEAM module, searching files.

Loads a BEAM module into memory using platform dependent methods and returns a pointer to a Module struct. This function is called if loading from avm packs failed and may return NULL if there is no support for files.

Parameters:
  • global – the global context.

  • module_name – the name of the BEAM file (e.g. “mymodule.beam”).

Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts)

Create a port driver.

This function creates a port driver, encapsulated in a Context object. This function should create a Context object through the supplied global context, which will assume ownership of the new instance.

Parameters:
  • glb – the global context.

  • driver_name – the name of the driver that will control the port.

  • opts – the term options passed into the port open command.

Returns:

a new Context instance, or NULL, if a driver cannot be created from the inputs.

term sys_get_info(Context *ctx, term key)

Get platform-dependent information for the specified key.

This function returns platform-dependent information specified by the supplied key. If not information is available for the specified key, this function should return the atom ‘undefined’

Parameters:
  • ctx – the current context

  • key – an atom used to indicate the type of information requested.

Returns:

a term containing the requested information, or the atom undefined, if there is no system information for the specified key.

void sys_init_platform(GlobalContext *global)

Initialize the platform, setting global->platform_data.

void sys_free_platform(GlobalContext *global)

Free the platform data structure.

Cleanup the platform data structure. Called by global_context_destroy.