Erlang Central

Difference between revisions of "A Guide To The Erlang Source"

From ErlangCentral Wiki

m
m
Line 13: Line 13:
 
== Basic types ==
 
== Basic types ==
 
See sys.h for the basic datatypes:
 
See sys.h for the basic datatypes:
 +
<code>
 
** Data types:
 
** Data types:
 
**
 
**
Line 28: Line 29:
 
** Uint16: An unsigned integer of 16 bits exactly
 
** Uint16: An unsigned integer of 16 bits exactly
 
** Sint16: A signed 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 uint_to_big(Uint x, Eterm *y). term_to_Uint(Eterm term, Uint *up).
 
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.
 
An Eterm can contain any erlang term like atoms, integers, etc.
Line 55: Line 56:
  
 
As defined in bif.h:
 
As defined in bif.h:
[code]
+
<code>
 
#define BIF_RETTYPE Eterm
 
#define BIF_RETTYPE Eterm
  
Line 68: Line 69:
 
#define BIF_ARG_2  A_2
 
#define BIF_ARG_2  A_2
 
#define BIF_ARG_3  A_3
 
#define BIF_ARG_3  A_3
[/code]
+
</code>
  
 
To bif to set process flags:
 
To bif to set process flags:
  
[code]
+
<code>
 
BIF_RETTYPE process_flag_2(BIF_ALIST_2)
 
BIF_RETTYPE process_flag_2(BIF_ALIST_2)
 
{
 
{
Line 87: Line 88:
 
   }
 
   }
  
[/code]
+
</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'.  
 
am_priority is one of the predefined atoms (like am_EXIT). BIF_ARG_1 is an Eterm that can contain the erlang atom 'priority'.  

Revision as of 21:02, 19 January 2011

A guide to the erlang source.

Contents

Download

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

Tree

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

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.

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.
<code>
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.

== 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:
<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

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 types

structs ErlSpawnOpts Process ErtsProcLocks ErtsMonitor

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

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

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


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, ...).