globalcontext.c

Include dependency graph for globalcontext.c:

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

Functions

GlobalContext *globalcontext_new()

Creates a new GlobalContext.

Allocates a new GlobalContext struct and initialize it, the newly created global context is a new AtomVM instance.

Returns:

A newly created GlobalContext.

void globalcontext_destroy(GlobalContext *glb)

Destoys an existing GlobalContext.

Frees global context resources and memory and removes it from the processes table.

Parameters:
  • glb – the global context that will be destroyed.

Context *globalcontext_get_process_nolock(GlobalContext *glb, int32_t process_id)

Gets a Context from the process table, without acquiring a lock on the process table.

Retrieves from the process table the context with the given local process id. If the process can be found, without locking the process table. This is unsafe unless a lock on the process table has been obtained previously.

Parameters:
  • glb – the global context (that owns the process table).

  • process_id – the local process id.

Returns:

a Context * with the requested local process id or NULL if not found.

Context *globalcontext_get_process_lock(GlobalContext *glb, int32_t process_id)

Gets a Context from the process table, acquiring a lock on the process table.

Retrieves from the process table the context with the given local process id. If the process can be found, the process table is locked.

Parameters:
  • glb – the global context (that owns the process table).

  • process_id – the local process id.

Returns:

a Context * with the requested local process id or NULL if not found.

static bool globalcontext_get_process_trylock(GlobalContext *glb, int32_t process_id, Context **output)
void globalcontext_get_process_unlock(GlobalContext *glb, Context *c)

Unlock the process table after c was gotten.

Parameters:
  • glb – the global context (that owns the process table).

  • c – the result of globalcontext_get_process_lock. If NULL, does nothing, otherwise releases the lock on process table.

bool globalcontext_process_exists(GlobalContext *glb, int32_t process_id)

Determine if a process exists.

Parameters:
  • glb – the global context (that owns the process table).

  • process_id – the local process id.

Returns:

true if a process exists with this id.

void globalcontext_send_message(GlobalContext *glb, int32_t process_id, term t)

Send a message to a process identified by its id.

Safely send a message to the process, doing nothing is the process cannot be found.

Parameters:
  • glb – the global context (that owns the process table).

  • process_id – the local process id.

  • t – the message to send.

void globalcontext_send_message_nolock(GlobalContext *glb, int32_t process_id, term t)

Send a message to a process from another process. There should be a lock on the process table. This variant can be used by listener handlers as an optimization (instead of sending a message to the port context which should then forward it to the target context).

Safely send a message to the process, doing nothing if the process cannot be found.

Parameters:
  • glb – the global context (that owns the process table).

  • process_id – the target process id.

  • t – the message to send.

void globalcontext_send_message_from_task(GlobalContext *glb, int32_t process_id, enum MessageType type, term t)

Send a message to a process identified by its id. This variant is to be used from task drivers. It tries to acquire the necessary locks and if it fails, it enqueues the message which will be delivered on the next scheduler context switch.

Safely send a message to the process, doing nothing if the process cannot be found.

Parameters:
  • glb – the global context (that owns the process table).

  • process_id – the target process id.

  • type – the type of message to send, can be NormalMessage or a signal

  • t – the message to send.

static inline void globalcontext_process_message_queue(GlobalContext *glb)
static inline void globalcontext_process_refc_queue(GlobalContext *glb)
void globalcontext_refc_decrement_refcount_from_task(GlobalContext *glb, struct RefcBinary *refc)

Enqueue a refc binary from a task driver, to be refc decremented later from the scheduler.

Parameters:
  • glb – the global context

  • refc – the refc binary to enqueue

void globalcontext_process_task_driver_queues(GlobalContext *glb)

Process refc binaries and messages enqueued from task drivers.

This function is called from the scheduler.

Parameters:
  • glb – the global context

void globalcontext_init_process(GlobalContext *glb, Context *ctx)

Initialize a new process, providing it with a process id.

This function also inserts the process into the process and waiting tables.

Parameters:
  • glb – the global context.

  • ctx – the process to initialize

bool globalcontext_register_process(GlobalContext *glb, int atom_index, int local_process_id)

Register a process.

Register a process with a certain name (atom) so it can be easily retrieved later.

Parameters:
  • glb – the global context, each registered process will be globally available for that context.

  • atom_index – the atom table index.

  • local_process_id – the process local id.

Returns:

true if the process was registered, false if another process with the same name already existed

bool globalcontext_unregister_process(GlobalContext *glb, int atom_index)

Unregister a process by name.

Unregister a process with a certain name (atom).

Parameters:
  • glb – the global context, each registered process will be globally available for that context.

  • atom_index – the atom table index.

Returns:

true if the process was unregistered, false otherwise

void globalcontext_maybe_unregister_process_id(GlobalContext *glb, int target_process_id)

Remove entry(ies) from registered atoms by process id.

Unregister a process with a certain process id. This is used when a process dies to ensure the process is not registered and remove it from the registered atoms table if it is.

Parameters:
  • glb – the global context, each registered process will be globally available for that context.

  • process_id – the process id of the entry to remove.

int globalcontext_get_registered_process(GlobalContext *glb, int atom_index)

Get a registered process.

Returns the local process id of a previously registered process.

Parameters:
  • glb – the global context.

  • atom_index – the atom table index.

Returns:

a previously registered process local id.

bool globalcontext_is_atom_index_equal_to_atom_string(GlobalContext *glb, int atom_index_a, AtomString atom_string_b)

Compares an atom table index with an AtomString.

Checks if the given atom table index and the given AtomString refers to the same atom.

Parameters:
  • glb – the global context.

  • atom_index_a – an atom table index.

  • atom_string_b – an atom string, which is the atom length followed by atom characters.

Returns:

true if they both refer to the same atom, otherwise false.

AtomString globalcontext_atomstring_from_term(GlobalContext *glb, term t)

Returns the AtomString value of a term.

This function fetches the AtomString value of the atom associated with the supplied term. The input term must be an atom type. If no such atom is registered in the global table, this function returns NULL. The caller should NOT free the data associated with the returned value.

Parameters:
  • glb – the global context

  • t – the atom term

Returns:

the AtomString associated with the supplied atom term.

term globalcontext_existing_term_from_atom_string(GlobalContext *glb, AtomString atom_string)

Returns the term for an existing atom.

This function allows to get an atom term associated to the given atom string, if and only if the given atom is already in the atom table, otherwise an invalid term is returned.

Parameters:
  • glb – the global context.

  • atom_string – the atom string that will be looked into the atom table.

Returns:

the term associated with the supplied atom string when already existing in the atom table, otherwise an invalid term.

int globalcontext_insert_module(GlobalContext *global, Module *module)

Inserts a module to the modules table.

Inserts an already loaded module to the modules table and assigns and index to it so it can be retrieved later by name or index.

Parameters:
  • global – the global context.

  • module – the module that will be added to the modules table.

Returns:

the module index if successful, otherwise -1.

Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom)

Returns the module with the given name.

Tries to get the module with the given name from the modules table and eventually loads it.

Parameters:
  • global – the global context.

  • module_name_atom – the module name.

Returns:

a pointer to a Module struct.

Module *globalcontext_get_module_by_index(GlobalContext *global, int index)

Get a module by index.

Safely retrieve the module by index considering the table can be reallocated by globalcontext_insert_module.

Parameters:
  • global – the global context.

  • index – the module index.

Returns:

the module

bool globalcontext_demonitor(GlobalContext *global, uint64_t ref_ticks)

remove a monitor

iterate on the list of all processes and then on each monitor to find a given monitor, and remove it

Parameters:
  • global – the global context

  • ref_ticks – the reference to the monitor

Returns:

true if the monitor was found

struct RegisteredProcess

Collaboration diagram for RegisteredProcess:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "1" [label="RegisteredProcess" tooltip="RegisteredProcess" fillcolor="#BFBFBF"]
    "2" [label="ListHead" tooltip="ListHead"]
    "1" -> "2" [dir=forward tooltip="usage"]
    "2" -> "2" [dir=forward tooltip="usage"]
}

Public Members

struct ListHead registered_processes_list_head
int atom_index
int local_process_id