A Guide To The Erlang Source

From Erlang Community

(Difference between revisions)
Revision as of 17:59, 19 August 2009 (edit)
Zghst (Talk | contribs)

← Previous diff
Current revision (21:31, 19 January 2011) (edit) (undo)
Zghst (Talk | contribs)
m
 
(10 intermediate revisions not shown.)
Line 2: Line 2:
== Download == == Download ==
-The source can be downloaded from: http://erlang.org/download.html+The source can be downloaded from: https://github.com/erlang/otp
== Tree == == Tree ==
Line 11: Line 11:
The atoms used in erlang are listed in erts/emulator/beam/atom.names and are referenced in the code as am_foo. So the 'EXIT' atom is am_EXIT in the code. The atoms used in erlang are listed in erts/emulator/beam/atom.names and are referenced in the code as am_foo. So the 'EXIT' atom is am_EXIT in the code.
-== Types ==+== Basic types ==
-Most used types are: Sint, Uint, Eterm, ...+See sys.h for the basic datatypes:
-Conversion is done in erts/emulator/beam/big.c. For example uint_to_big(Uint x, Eterm *y). term_to_Uint(Eterm term, Uint *up)+<code>
 +** Data types:
 +**
 +** Eterm: A tagged erlang term (possibly 64 bits)
 +** BeamInstr: A beam code instruction unit, possibly larger than Eterm, not smaller.
 +** UInt: An unsigned integer exactly as large as an Eterm.
 +** SInt: A signed integer exactly as large as an eterm and therefor large
 +** enough to hold the return value of the signed_val() macro.
 +** UWord: An unsigned integer at least as large as a void * and also as large
 +** or larger than an Eterm
 +** SWord: A signed integer at least as large as a void * and also as large
 +** or larger than an Eterm
 +** Uint32: An unsigned integer of 32 bits exactly
 +** Sint32: A signed integer of 32 bits exactly
 +** Uint16: An unsigned integer of 16 bits exactly
 +** Sint16: A signed integer of 16 bits exactly.
 +</code>
 + 
 + 
 +See erts/emulator/beam/big.c for the conversion between types. For example:
 +<code>
 + uint_to_big(Uint x, Eterm *y).
 + term_to_Uint(Eterm term, Uint *up).
 +</code>
 +An Eterm can contain any erlang term like atoms, integers, etc.
 +Some util methods can be found in erl_term.h to get the value out:
 +<code>
 +is_atom
 +is_fun
 +...
 +</code>
 +More util methods in
 + 
 + 
 +== Trivia ==
 +* rp = receiving process / registered process
 +* cp = calling process
 +* rq = runqueue
 + 
 +== BIFs ==
 + 
 +The bifs are summed up in the bif.tab file. For example:
 +<code>
 +bif 'erl.lang':exit/1 ebif_exit_1
 +bif erlang:exit/2
 +</code>
 + 
 +This means the exit bif is mapped to the exit_1 method in the bif.c file.
 +The bif.c file holds the bif implementations like:
 + 
 +BIF_RETTYPE spawn_3(BIF_ALIST_3)
 +{...
 + 
 +BIF_ALIST_3 means you have BIF_P, BIF_ARG1 to 3 and
 +The arguments BIF_ARG1 are Eterms, so you have to check them with
 + 
 +is_number(BIF_ARG_1),
 +is_atom,
 +is_tuple,
 +is_list
 +etc
 + 
 +As defined in bif.h:
 +<code>
 +#define BIF_RETTYPE Eterm
 + 
 +#define BIF_P A__p
 + 
 +#define BIF_ALIST_0 Process* A__p
 +#define BIF_ALIST_1 Process* A__p, Eterm A_1
 +#define BIF_ALIST_2 Process* A__p, Eterm A_1, Eterm A_2
 +#define BIF_ALIST_3 Process* A__p, Eterm A_1, Eterm A_2, Eterm A_3
 + 
 +#define BIF_ARG_1 A_1
 +#define BIF_ARG_2 A_2
 +#define BIF_ARG_3 A_3
 +</code>
 + 
 +To bif to set process flags:
 + 
 +<code>
 +BIF_RETTYPE process_flag_2(BIF_ALIST_2)
 +{
 + Eterm old_value;
 + ...
 + 
 + else if (BIF_ARG_1 == am_priority) {
 + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_STATUS);
 + old_value = erts_set_process_priority(BIF_P, BIF_ARG_2);
 + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_STATUS);
 + if (old_value == THE_NON_VALUE)
 + goto error;
 + BIF_RET(old_value);
 + }
 + 
 +</code>
 + 
 +am_priority is one of the predefined atoms (like am_EXIT). BIF_ARG_1 is an Eterm that can contain the erlang atom 'priority'.
 +BIF_RETTYPE is an Eterm: we return the old priority as an Eterm.
 + 
 +More bifs in bif.c (these are called in erlang like erlang:register(,...))
 + 
 +* process_flag/2
 +* process_flag/3, ...
 +* process_info/1 and /2
 +* register/2
 +* whereis/1
 +* exit/2
 + 
 +== More types ==
 +structs
 +* ErlSpawnOpts
 +* Process (see erl_process.h )
 +* ErtsProcLocks
 +* ErtsMonitor
 +* ErtsRunQueue
 + 
 + 
 +== SMP ==
 +http://en.wikipedia.org/wiki/Symmetric_multiprocessing
 +You will see this a lot in the code: #ifdef ERTS_SMP
 +Things get more complicated, with regards to locking etc. if SMP is enabled.
 + 
 +== Locking ==
 + 
 +...
 + 
== Scheduler == == Scheduler ==
-The process struct is defined in erts/emulator/beam/process.h. The important function is Process *schedule(Process *p, int calls). The next process is picked in "pick_next_process" of that method.+The process struct is defined in erts/emulator/beam/process.h. The important function is Process *schedule(Process *p, int calls) in process.c . The next process is picked in "pick_next_process" of that method.
 + 
 +== Process ==
 + 
 +The main struct is Process as defined in erl_process.h, Each process has its own heap.
 +Some variables:
 +* int prio
 +* Uint reds
 +* ErlMessageQueue msg
 +* Eterm id (the pid)
 +* Uint flags
 + 
 +Process statuses are:
 +#define P_FREE 0
 +#define P_RUNABLE 1
 +#define P_WAITING 2
 +#define P_RUNNING 3
 +#define P_EXITING 4
 +#define P_GARBING 5
 +#define P_SUSPENDED 6
 + 
 + 
 +== Monitors and links ==
 +See erl_monitor.c and .h. The main structs are ErtsLinks and ErtsMonitor.
 +Each process has a *ErtLinks and *ErtsMonitor (herein all its links/monitors are kept as an AVL tree). Actions are done with erts_sweep_links(ErtsLink *root, ...) and erts_sweep_monitors(ErtsMonitor *root, ...).

Current revision

A guide to the erlang source.

Contents

[edit] Download

The source can be downloaded from: https://github.com/erlang/otp

[edit] Tree

Most of the interesting code is in: erts/emulator/beam

[edit] Atoms

The atoms used in erlang are listed in erts/emulator/beam/atom.names and are referenced in the code as am_foo. So the 'EXIT' atom is am_EXIT in the code.

[edit] Basic types

See sys.h for the basic datatypes:

** Data types:
**
** Eterm: A tagged erlang term (possibly 64 bits)
** BeamInstr: A beam code instruction unit, possibly larger than Eterm, not smaller.
** UInt:  An unsigned integer exactly as large as an Eterm.
** SInt:  A signed integer exactly as large as an eterm and therefor large
**        enough to hold the return value of the signed_val() macro.
** UWord: An unsigned integer at least as large as a void * and also as large
**          or larger than an Eterm
** SWord: A signed integer at least as large as a void * and also as large
**          or larger than an Eterm
** Uint32: An unsigned integer of 32 bits exactly
** Sint32: A signed integer of 32 bits exactly
** Uint16: An unsigned integer of 16 bits exactly
** Sint16: A signed integer of 16 bits exactly.


See erts/emulator/beam/big.c for the conversion between types. For example:

 uint_to_big(Uint x, Eterm *y).
 term_to_Uint(Eterm term, Uint *up).

An Eterm can contain any erlang term like atoms, integers, etc. Some util methods can be found in erl_term.h to get the value out:

is_atom
is_fun
...

More util methods in


[edit] Trivia

  • rp = receiving process / registered process
  • cp = calling process
  • rq = runqueue

[edit] BIFs

The bifs are summed up in the bif.tab file. For example:

bif 'erl.lang':exit/1 ebif_exit_1
bif erlang:exit/2

This means the exit bif is mapped to the exit_1 method in the bif.c file. The bif.c file holds the bif implementations like:

BIF_RETTYPE spawn_3(BIF_ALIST_3) {...

BIF_ALIST_3 means you have BIF_P, BIF_ARG1 to 3 and The arguments BIF_ARG1 are Eterms, so you have to check them with

is_number(BIF_ARG_1), is_atom, is_tuple, is_list etc

As defined in bif.h:

#define BIF_RETTYPE Eterm

#define BIF_P A__p

#define BIF_ALIST_0 Process* A__p
#define BIF_ALIST_1 Process* A__p, Eterm A_1
#define BIF_ALIST_2 Process* A__p, Eterm A_1, Eterm A_2
#define BIF_ALIST_3 Process* A__p, Eterm A_1, Eterm A_2, Eterm A_3

#define BIF_ARG_1  A_1
#define BIF_ARG_2  A_2
#define BIF_ARG_3  A_3

To bif to set process flags:

BIF_RETTYPE process_flag_2(BIF_ALIST_2)
{
   Eterm old_value;
  ...

   else if (BIF_ARG_1 == am_priority) {
       erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_STATUS);
       old_value = erts_set_process_priority(BIF_P, BIF_ARG_2);
       erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_STATUS);
       if (old_value == THE_NON_VALUE)
	   goto error;
       BIF_RET(old_value);
   }

am_priority is one of the predefined atoms (like am_EXIT). BIF_ARG_1 is an Eterm that can contain the erlang atom 'priority'. BIF_RETTYPE is an Eterm: we return the old priority as an Eterm.

More bifs in bif.c (these are called in erlang like erlang:register(,...))

  • process_flag/2
  • process_flag/3, ...
  • process_info/1 and /2
  • register/2
  • whereis/1
  • exit/2

[edit] More types

structs

  • ErlSpawnOpts
  • Process (see erl_process.h )
  • ErtsProcLocks
  • ErtsMonitor
  • ErtsRunQueue


[edit] SMP

http://en.wikipedia.org/wiki/Symmetric_multiprocessing You will see this a lot in the code: #ifdef ERTS_SMP Things get more complicated, with regards to locking etc. if SMP is enabled.

[edit] Locking

...


[edit] Scheduler

The process struct is defined in erts/emulator/beam/process.h. The important function is Process *schedule(Process *p, int calls) in process.c . The next process is picked in "pick_next_process" of that method.

[edit] Process

The main struct is Process as defined in erl_process.h, Each process has its own heap. Some variables:

  • int prio
  • Uint reds
  • ErlMessageQueue msg
  • Eterm id (the pid)
  • Uint flags

Process statuses are:

  1. define P_FREE 0
  2. define P_RUNABLE 1
  3. define P_WAITING 2
  4. define P_RUNNING 3
  5. define P_EXITING 4
  6. define P_GARBING 5
  7. define P_SUSPENDED 6


[edit] Monitors and links

See erl_monitor.c and .h. The main structs are ErtsLinks and ErtsMonitor. Each process has a *ErtLinks and *ErtsMonitor (herein all its links/monitors are kept as an AVL tree). Actions are done with erts_sweep_links(ErtsLink *root, ...) and erts_sweep_monitors(ErtsMonitor *root, ...).

Erlang/OTP Projects
Personal tools