A Guide To The Erlang Source
From Erlang Community
| Revision as of 20:08, 19 August 2009 (edit) Zghst (Talk | contribs) ← Previous diff |
Current revision (21:31, 19 January 2011) (edit) (undo) Zghst (Talk | contribs) m |
||
| (8 intermediate revisions not shown.) | |||
| Line 2: | Line 2: | ||
| == Download == | == Download == | ||
| - | The source can be downloaded from: | + | 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. | ||
| - | == | + | == Basic types == |
| - | + | See sys.h for the basic datatypes: | |
| - | + | <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) in process.c . 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 == | == Monitors and links == | ||
| See erl_monitor.c and .h. The main structs are ErtsLinks and ErtsMonitor. | 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, ...). | 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:
- 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
[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, ...).

Digg It
Del.icio.us
Reddit
Facebook
Stumble Upon
Technorati

