⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_node_container_utils.h

📁 OTP是开放电信平台的简称
💻 H
字号:
/* ``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 via the world wide web 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. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ */#ifndef ERL_NODE_CONTAINER_UTILS_H__#define ERL_NODE_CONTAINER_UTILS_H__#include "erl_term.h"/* * Note regarding node containers: * * The term "node container" is used as a group name (internally in * the emulator) for the Erlang data types that contain a reference * to a node, i.e. pids, ports, and references. * * Observe! The layouts of the node container data types have been * changed in R9.  * * Node containers are divided into internal and external node containers. * An internal node container refer to the current incarnation of the * node which it reside on. An external node container refer to * either a remote node (i.e. a node with another node name than the  * node name of the node on which the node container resides on) or another * incarnation of the node which the node container resides on (i.e * another node with the same node name but another creation). * * External node containers are boxed data types. The data of an * external node container is stored on the heap together with a pointer * to an element in the node table (see erl_term.h and erl_node_tables.h). * The elements of the node table are garbage collected by reference * counting (much like refc binaries, and funs in the separate heap case). * * Internal node containers are stored as they previously were (in R8) * with the exception of changed internal layouts (see erl_term.h), i.e. * internal pid, and internal port are immediate data types and internal * reference is a boxed data type. An internal node container have an * implicit reference to the 'erts_this_node' element in the node table. * * Due to the R9 changes in layouts of node containers there are room to * store more data than previously. Today (R9) this extra space is unused, * but it is planned to be used in the future. For example only 18 bits * are used for data in a pid but there is room for 28 bits of data (on a * 32-bit machine). Some preparations have been made in the emulator for * usage of this extra space. * * OBSERVE! Pids doesn't use fixed size 'serial' and 'number' fields any * more. Previously the 15 bit 'number' field of a pid was used as index * into the process table, and the 3 bit 'serial' field was used as a * "wrap counter". The needed number of bits for index into the process * table is now calculated at startup and the rest (of the 18 bits used) * are used as 'serial'. In the "emulator interface" (external format, * list_to_pid, etc) the least significant 15 bits are presented as * 'number' and the most significant 3 bits are presented as 'serial', * though. The makro internal_pid_index() can be used for retrieving * index into the process table. Do *not* use the result from * pid_number() as an index into the process table. The pid_number() and * pid_serial() (and friends) fetch the old fixed size 'number' and * 'serial' fields. *//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Node containers                                                         *\*                                                                         */#define node_container_node_name(x)	(is_external(x)			\					 ? external_node_name((x))	\					 : internal_node_name((x)))#define node_container_creation(x) 	(is_external(x)			\					 ? external_creation((x))	\					 : internal_creation((x)))#define node_container_dist_entry(x) 	(is_external(x)			\					 ? external_dist_entry((x))	\					 : internal_dist_entry((x)))#define node_container_channel_no(x)	(is_external((x))		\					 ? external_channel_no((x))	\					 : internal_channel_no((x)))#define is_node_container(x)		(is_external((x)) || is_internal((x)))#define is_not_node_container(x)	(!is_node_container((x)))#define is_internal(x) 			(is_internal_pid((x))		\					 || is_internal_port((x))	\					 || is_internal_ref((x)))#define is_not_internal(x) 		(!is_internal((x)))#define internal_node_name(x)		(erts_this_node->sysname)#define external_node_name(x)		external_node((x))->sysname#define internal_creation(x)		(erts_this_node->creation)#define external_creation(x)		(external_node((x))->creation)#define internal_dist_entry(x)		(erts_this_node->dist_entry)#define external_dist_entry(x)		(external_node((x))->dist_entry)extern int erts_use_r9_pids_ports;/* * For this node (and previous incarnations of this node), 0 is used as * channel no. For other nodes, the atom index of the atom corresponding * to the node name is used as channel no. * * (We used to assert for correct node names, but we removed that assertion *  as it is possible to sneak in incorrect node names for instance using *  the external format.) */#define dist_entry_channel_no(x)				\  ((x) == erts_this_dist_entry					\   ? ((Uint) 0)							\   : (ASSERT_EXPR(is_atom((x)->sysname)),			\      (Uint) atom_val((x)->sysname)))#define internal_channel_no(x) ((Uint) ERST_INTERNAL_CHANNEL_NO)#define external_channel_no(x) \  (dist_entry_channel_no(external_dist_entry((x))))/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Pids                                                                    *\*                                                                         */#define internal_pid_index(x)		(internal_pid_data((x))	\					 & erts_process_tab_index_mask)#define internal_pid_node_name(x)	(internal_pid_node((x))->sysname)#define external_pid_node_name(x)	(external_pid_node((x))->sysname)#define internal_pid_creation(x)	(internal_pid_node((x))->creation)#define external_pid_creation(x)	(external_pid_node((x))->creation)#define internal_pid_dist_entry(x)	(internal_pid_node((x))->dist_entry)#define external_pid_dist_entry(x)	(external_pid_node((x))->dist_entry)#define internal_pid_channel_no(x)	(internal_channel_no((x)))#define external_pid_channel_no(x)	(external_channel_no((x)))#define pid_data_words(x)		(is_internal_pid((x))		\					 ? internal_pid_data_words((x))	\					 : external_pid_data_words((x)))#define pid_number(x)			(is_internal_pid((x))		\					 ? internal_pid_number((x))	\					 : external_pid_number((x)))#define pid_serial(x)			(is_internal_pid((x))		\					 ? internal_pid_serial((x))	\					 : external_pid_serial((x)))#define pid_node(x)			(is_internal_pid((x))		\					 ? internal_pid_node((x))	\					 : external_pid_node((x)))#define pid_node_name(x)		(is_internal_pid((x))		\					 ? internal_pid_node_name((x))	\					 : external_pid_node_name((x)))#define pid_creation(x)			(is_internal_pid((x))		\					 ? internal_pid_creation((x))	\					 : external_pid_creation((x)))#define pid_dist_entry(x)		(is_internal_pid((x))		\					 ? internal_pid_dist_entry((x))	\					 : external_pid_dist_entry((x)))#define pid_channel_no(x)		(is_internal_pid((x))		\					 ? internal_pid_channel_no((x))	\					 : external_pid_channel_no((x)))#define is_pid(x)			(is_internal_pid((x))		\					 || is_external_pid((x)))#define is_not_pid(x)			(!is_pid(x))#define ERTS_MAX_R9_PROCESSES		(1 << ERTS_R9_PROC_BITS)/* * Maximum number of processes. We want the number to fit in a SMALL on * 32-bit CPU. */#define ERTS_MAX_PROCESSES ((1L << 27)-1)#if (ERTS_MAX_PROCESSES > MAX_SMALL)# error "The maximum number of processes must fit in a SMALL."#endif#define ERTS_MAX_PID_DATA		((1 << _PID_DATA_SIZE) - 1)#define ERTS_MAX_PID_NUMBER		((1 << _PID_NUM_SIZE) - 1)#define ERTS_MAX_PID_SERIAL		((1 << _PID_SER_SIZE) - 1)#define ERTS_MAX_PID_R9_SERIAL		((1 << _PID_R9_SER_SIZE) - 1)#define ERTS_R9_PROC_BITS		(_PID_R9_SER_SIZE + _PID_NUM_SIZE)#define ERTS_PROC_BITS			(_PID_SER_SIZE + _PID_NUM_SIZE)#define ERTS_INVALID_PID		make_internal_pid(ERTS_MAX_PID_DATA)/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Ports                                                                   *\*                                                                         */#define internal_port_index(x)		(internal_port_data((x))	\					 & erts_port_tab_index_mask)#define internal_port_node_name(x)	(internal_port_node((x))->sysname)#define external_port_node_name(x)	(external_port_node((x))->sysname)#define internal_port_creation(x)	(internal_port_node((x))->creation)#define external_port_creation(x)	(external_port_node((x))->creation)#define internal_port_dist_entry(x)	(internal_port_node((x))->dist_entry)#define external_port_dist_entry(x)	(external_port_node((x))->dist_entry)#define internal_port_channel_no(x)	(internal_channel_no((x)))#define external_port_channel_no(x)	(external_channel_no((x)))#define port_data_words(x)		(is_internal_port((x))		\					 ? internal_port_data_words((x))\					 : external_port_data_words((x)))#define port_number(x)			(is_internal_port((x))		\					 ? internal_port_number((x))	\					 : external_port_number((x)))#define port_node(x)			(is_internal_port((x))		\					 ? internal_port_node((x))	\					 : external_port_node((x)))#define port_node_name(x)		(is_internal_port((x))		\					 ? internal_port_node_name((x))	\					 : external_port_node_name((x)))#define port_creation(x)		(is_internal_port((x))		\					 ? internal_port_creation((x))	\					 : external_port_creation((x)))#define port_dist_entry(x)		(is_internal_port((x))		\					 ? internal_port_dist_entry((x))\					 : external_port_dist_entry((x)))#define port_channel_no(x)		(is_internal_port((x))		\					 ? internal_port_channel_no((x))\					 : external_port_channel_no((x)))#define is_port(x)			(is_internal_port((x))		\					 || is_external_port((x)))#define is_not_port(x)			(!is_port(x))/* Highest port-ID part in a term of type Port    Not necessarily the same as the variable erts_max_ports   which defines the maximum number of simultaneous Ports   in the Erlang node. ERTS_MAX_PORTS is a hard upper limit.*/#define ERTS_MAX_R9_PORTS		(1 << ERTS_R9_PORTS_BITS)#define ERTS_MAX_PORTS			(1 << ERTS_PORTS_BITS)#define ERTS_MAX_PORT_DATA		((1 << _PORT_DATA_SIZE) - 1)#define ERTS_MAX_PORT_NUMBER		((1 << _PORT_NUM_SIZE) - 1)#define ERTS_R9_PORTS_BITS		(_PORT_R9_NUM_SIZE)#define ERTS_PORTS_BITS			(_PORT_NUM_SIZE)/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Refs                                                                    *\*                                                                         */#ifdef ARCH_64#define internal_ref_no_of_numbers(x)					\  (((Uint32 *) internal_ref_data((x)))[0])#define internal_ref_numbers(x)						\  (&(((Uint32 *) internal_ref_data((x)))[1]))#define external_ref_no_of_numbers(x)					\  (((Uint32 *) external_ref_data((x)))[0])#define external_ref_numbers(x)						\  (&(((Uint32 *) external_ref_data((x)))[1]))#else#define internal_ref_no_of_numbers(x)	(internal_ref_data_words((x)))#define internal_ref_numbers(x)		((Uint32 *) internal_ref_data((x)))#define external_ref_no_of_numbers(x)	(external_ref_data_words((x)))#define external_ref_numbers(x)		((Uint32 *) external_ref_data((x)))#endif#define internal_ref_node_name(x)	(internal_ref_node((x))->sysname)#define external_ref_node_name(x)	(external_ref_node((x))->sysname)#define internal_ref_creation(x)	(internal_ref_node((x))->creation)#define external_ref_creation(x)	(external_ref_node((x))->creation)#define internal_ref_dist_entry(x)	(internal_ref_node((x))->dist_entry)#define external_ref_dist_entry(x)	(external_ref_node((x))->dist_entry)#define internal_ref_channel_no(x)	(internal_channel_no((x)))#define external_ref_channel_no(x)	(external_channel_no((x)))#define ref_data_words(x)		(is_internal_ref((x))		\					 ? internal_ref_data_words((x))	\					 : external_ref_data_words((x)))#define ref_data(x)			(is_internal_ref((x))		\					 ? internal_ref_data((x))	\					 : external_ref_data((x)))#define ref_no_of_numbers(x)		(is_internal_ref((x))		\					 ? internal_ref_no_of_numbers((x))\					 : external_ref_no_of_numbers((x)))#define ref_numbers(x)			(is_internal_ref((x))		\					 ? internal_ref_numbers((x))	\					 : external_ref_numbers((x)))#define ref_node(x)			(is_internal_ref((x))		\					 ? internal_ref_node(x)		\					 : external_ref_node((x)))#define ref_node_name(x)		(is_internal_ref((x))		\					 ? internal_ref_node_name((x))	\					 : external_ref_node_name((x)))#define ref_creation(x)			(is_internal_ref((x))		\					 ? internal_ref_creation((x))	\					 : external_ref_creation((x)))#define ref_dist_entry(x)		(is_internal_ref((x))		\					 ? internal_ref_dist_entry((x))	\					 : external_ref_dist_entry((x)))#define ref_channel_no(x)		(is_internal_ref((x))		\					 ? internal_ref_channel_no((x))	\					 : external_ref_channel_no((x)))#define is_ref(x)			(is_internal_ref((x))		\					 || is_external_ref((x)))#define is_not_ref(x)			(!is_ref(x))#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -