diff options
Diffstat (limited to 'erts/emulator/beam/erl_monitors.h')
-rw-r--r-- | erts/emulator/beam/erl_monitors.h | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_monitors.h b/erts/emulator/beam/erl_monitors.h new file mode 100644 index 0000000000..d3f6d410dd --- /dev/null +++ b/erts/emulator/beam/erl_monitors.h @@ -0,0 +1,180 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/********************************************************************** + * Header for monitors and links data structures. + * Monitors are kept in an AVL tree and the data structures for + * the four different types of monitors are like this: + ********************************************************************** + * Local monitor by pid/port: + * (Ref is always same in all involved data structures) + ********************************************************************** + * Process/Port X Process Y + * +-------------+ +-------------+ + * Type: | MON_ORIGIN | | MON_TARGET | + * +-------------+ +-------------+ + * Pid: | Pid(Y) | | Pid/Port(X) | + * +-------------+ +-------------+ + * Name: | [] | | [] | + * +-------------+ +-------------+ + ********************************************************************** + * Local monitor by name: (Ref is always same in all involved data structures) + ********************************************************************** + * Process X Process Y (name foo) + * +-------------+ +-------------+ + * Type: | MON_ORIGIN | | MON_TARGET | + * +-------------+ +-------------+ + * Pid: | Pid(Y) | | Pid(X) | + * +-------------+ +-------------+ + * Name: | Atom(foo) | | Atom(foo) | + * +-------------+ +-------------+ + ********************************************************************** + * Remote monitor by pid: (Ref is always same in all involved data structures) + ********************************************************************** + * Node A | Node B + * ---------------------------------+---------------------------------- + * Process X (@A) Distentry @A Distentry @B Process Y (@B) + * for node B for node A + * +-------------+ +-------------+ +-------------+ +-------------+ + * Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET | + * +-------------+ +-------------+ +-------------+ +-------------+ + * Pid: | Pid(Y) | | Pid(X) | | Pid(Y) | | Pid(X) | + * +-------------+ +-------------+ +-------------+ +-------------+ + * Name: | [] | | [] | | [] | | [] | + * +-------------+ +-------------+ +-------------+ +-------------+ + ********************************************************************** + * Remote monitor by name: (Ref is always same in all involved data structures) + ********************************************************************** + * Node A | Node B + * ---------------------------------+---------------------------------- + * Process X (@A) Distentry @A Distentry @B Process Y (@B) + * for node B for node A (name foo) + * +-------------+ +-------------+ +-------------+ +-------------+ + * Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET | + * +-------------+ +-------------+ +-------------+ +-------------+ + * Pid: | Atom(node B)| | Pid(X) | | Pid(Y) | | Pid(X) | + * +-------------+ +-------------+ +-------------+ +-------------+ + * Name: | Atom(foo) | | Atom(foo) | | Atom(foo) | | Atom(foo) | + * +-------------+ +-------------+ +-------------+ +-------------+ + * The reason for the node atom in X->pid is that we don't know the actual + * pid of the monitored process on the other node when setting the monitor + * (which is done asyncronously). + **********************************************************************/ +#ifndef _ERL_MONITORS_H +#define _ERL_MONITORS_H + +/* Type tags for monitors */ +#define MON_ORIGIN 1 +#define MON_TARGET 3 + +/* Type tags for links */ +#define LINK_PID 1 /* ...Or port */ +#define LINK_NODE 3 /* "Node monitor" */ + +/* Size of a monitor without heap, in words (fixalloc) */ +#define ERTS_MONITOR_SIZE ((sizeof(ErtsMonitor) - sizeof(Uint))/sizeof(Uint)) +#define ERTS_MONITOR_SH_SIZE (ERTS_MONITOR_SIZE + REF_THING_SIZE) +#define ERTS_LINK_SIZE ((sizeof(ErtsLink) - sizeof(Uint))/sizeof(Uint)) +#define ERTS_LINK_SH_SIZE ERTS_LINK_SIZE /* Size of fix-alloced links */ + +/* ErtsMonitor and ErtsLink *need* to begin in a similar way as + ErtsMonitorOrLink */ +typedef struct erts_monitor_or_link { + struct erts_monitor_or_link *left, *right; + Sint16 balance; +} ErtsMonitorOrLink; + +typedef struct erts_monitor { + struct erts_monitor *left, *right; + Sint16 balance; + Uint16 type; /* MON_ORIGIN | MON_TARGET */ + Eterm ref; + Eterm pid; /* In case of distributed named monitor, this is the + nodename atom in MON_ORIGIN process, otherwise a pid or + , in case of a MON_TARGET, a port */ + Eterm name; /* When monitoring a named process: atom() else [] */ + Uint heap[1]; /* Larger in reality */ +} ErtsMonitor; + +typedef struct erts_link { + struct erts_link *left, *right; + Sint16 balance; + Uint16 type; /* LINK_PID | LINK_NODE */ + Eterm pid; /* When node monitor, + the node atom is here instead */ + union { + struct erts_link *root; /* Used only in dist entries */ + Uint refc; + } shared; + Uint heap[1]; /* Larger in reality */ +} ErtsLink; + +typedef struct erts_suspend_monitor { + struct erts_suspend_monitor *left, *right; + Sint16 balance; + + int pending; + int active; + Eterm pid; +} ErtsSuspendMonitor; + +#define ERTS_LINK_ROOT(Linkp) ((Linkp)->shared.root) +#define ERTS_LINK_REFC(Linkp) ((Linkp)->shared.refc) + +#define ERTS_LINK_ROOT_AS_UINT(Linkp) (*((Uint *) &((Linkp)->root))) + +Uint erts_tot_link_lh_size(void); + + +/* Prototypes */ +void erts_destroy_monitor(ErtsMonitor *mon); +void erts_add_monitor(ErtsMonitor **root, Uint type, Eterm ref, Eterm pid, + Eterm name); +ErtsMonitor *erts_remove_monitor(ErtsMonitor **root, Eterm ref); +ErtsMonitor *erts_lookup_monitor(ErtsMonitor *root, Eterm ref); +void erts_sweep_monitors(ErtsMonitor *root, + void (*doit)(ErtsMonitor *, void *), + void *context); + +void erts_destroy_link(ErtsLink *lnk); +/* Returns 0 if OK, < 0 if already present */ +int erts_add_link(ErtsLink **root, Uint type, Eterm pid); +ErtsLink *erts_add_or_lookup_link(ErtsLink **root, Uint type, Eterm pid); +ErtsLink *erts_remove_link(ErtsLink **root, Eterm pid); +ErtsLink *erts_lookup_link(ErtsLink *root, Eterm pid); +void erts_sweep_links(ErtsLink *root, + void (*doit)(ErtsLink *, void *), + void *context); + +void erts_destroy_suspend_monitor(ErtsSuspendMonitor *sproc); +void erts_sweep_suspend_monitors(ErtsSuspendMonitor *root, + void (*doit)(ErtsSuspendMonitor *, void *), + void *context); +ErtsSuspendMonitor *erts_add_or_lookup_suspend_monitor(ErtsSuspendMonitor **root, + Eterm pid); +ErtsSuspendMonitor *erts_lookup_suspend_monitor(ErtsSuspendMonitor *root, + Eterm pid); +void erts_delete_suspend_monitor(ErtsSuspendMonitor **root, Eterm pid); +void erts_init_monitors(void); + +#define erts_doforall_monitors erts_sweep_monitors +#define erts_doforall_links erts_sweep_links +#define erts_doforall_suspend_monitors erts_sweep_suspend_monitors + +#endif /* _ERL_MONITORS_H */ |