1 /* 2 * %CopyrightBegin% 3 * 4 * Copyright Ericsson AB 2001-2018. All Rights Reserved. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * %CopyrightEnd% 19 */ 20 21 #ifndef ERL_NODE_CONTAINER_UTILS_H__ 22 #define ERL_NODE_CONTAINER_UTILS_H__ 23 24 #include "erl_ptab.h" 25 26 /* 27 * Note regarding node containers: 28 * 29 * The term "node container" is used as a group name (internally in 30 * the emulator) for the Erlang data types that contain a reference 31 * to a node, i.e. pids, ports, and references. 32 * 33 * Node containers are divided into internal and external node containers. 34 * An internal node container refer to the current incarnation of the 35 * node which it reside on. An external node container refer to 36 * either a remote node (i.e. a node with another node name than the 37 * node name of the node on which the node container resides on) or another 38 * incarnation of the node which the node container resides on (i.e 39 * another node with the same node name but another creation). 40 * 41 * External node containers are boxed data types. The data of an 42 * external node container is stored on the heap together with a pointer 43 * to an element in the node table (see erl_term.h and erl_node_tables.h). 44 * The elements of the node table are garbage collected by reference 45 * counting (much like refc binaries, and funs in the separate heap case). 46 * 47 * Internal node containers are stored as they previously were (in R8) 48 * with the exception of changed internal layouts (see erl_term.h), i.e. 49 * internal pid, and internal port are immediate data types and internal 50 * reference is a boxed data type. An internal node container have an 51 * implicit reference to the 'erts_this_node' element in the node table. 52 * 53 * OBSERVE! Pids doesn't use fixed size 'serial' and 'number' fields any 54 * more. Previously the 15 bit 'number' field of a pid was used as index 55 * into the process table, and the 3 bit 'serial' field was used as a 56 * "wrap counter". The needed number of bits for index into the process 57 * table is now calculated at startup and the rest (of the 18 bits used) 58 * are used as 'serial'. In the "emulator interface" (external format, 59 * list_to_pid, etc) the least significant 15 bits are presented as 60 * 'number' and the most significant 3 bits are presented as 'serial', 61 * though. The makro internal_pid_index() can be used for retrieving 62 * index into the process table. Do *not* use the result from 63 * pid_number() as an index into the process table. The pid_number() and 64 * pid_serial() (and friends) fetch the old fixed size 'number' and 65 * 'serial' fields. 66 */ 67 68 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 69 * Node containers * 70 \* */ 71 72 #define node_container_node_name(x) (is_external(x) \ 73 ? external_node_name((x)) \ 74 : internal_node_name((x))) 75 #define node_container_creation(x) (is_external(x) \ 76 ? external_creation((x)) \ 77 : internal_creation((x))) 78 #define node_container_dist_entry(x) (is_external(x) \ 79 ? external_dist_entry((x)) \ 80 : internal_dist_entry((x))) 81 #define node_container_channel_no(x) (is_external((x)) \ 82 ? external_channel_no((x)) \ 83 : internal_channel_no((x))) 84 #define is_node_container(x) (is_external((x)) || is_internal((x))) 85 #define is_not_node_container(x) (!is_node_container((x))) 86 87 #define is_internal(x) (is_internal_pid((x)) \ 88 || is_internal_port((x)) \ 89 || is_internal_ref((x))) 90 #define is_not_internal(x) (!is_internal((x))) 91 #define internal_node_name(x) (erts_this_node->sysname) 92 #define external_node_name(x) external_node((x))->sysname 93 #define internal_creation(x) (erts_this_node->creation) 94 #define external_creation(x) (external_node((x))->creation) 95 #define internal_dist_entry(x) (erts_this_node->dist_entry) 96 #define external_dist_entry(x) (external_node((x))->dist_entry) 97 98 /* 99 * For this node (and previous incarnations of this node), 0 is used as 100 * channel no. For other nodes, the atom index of the atom corresponding 101 * to the node name is used as channel no. 102 * 103 * (We used to assert for correct node names, but we removed that assertion 104 * as it is possible to sneak in incorrect node names for instance using 105 * the external format.) 106 */ 107 #define dist_entry_channel_no(x) \ 108 ((x) == erts_this_dist_entry \ 109 ? ((Uint) 0) \ 110 : (ASSERT(is_atom((x)->sysname)), \ 111 (Uint) atom_val((x)->sysname))) 112 #define internal_channel_no(x) ((Uint) ERST_INTERNAL_CHANNEL_NO) 113 #define external_channel_no(x) \ 114 (dist_entry_channel_no(external_dist_entry((x)))) 115 116 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 117 * Pids * 118 \* */ 119 120 extern ErtsPTab erts_proc; 121 122 #define make_internal_pid(D) erts_ptab_make_id(&erts_proc, \ 123 (D), \ 124 _TAG_IMMED1_PID) 125 126 #define internal_pid_index(PID) (ASSERT(is_internal_pid((PID))), \ 127 erts_ptab_id2pix(&erts_proc, (PID))) 128 129 #define internal_pid_data(PID) (ASSERT(is_internal_pid((PID))), \ 130 erts_ptab_id2data(&erts_proc, (PID))) 131 132 #define internal_pid_number(x) _GET_PID_NUM(internal_pid_data((x))) 133 #define internal_pid_serial(x) _GET_PID_SER(internal_pid_data((x))) 134 135 #define internal_pid_node_name(x) (internal_pid_node((x))->sysname) 136 #define external_pid_node_name(x) (external_pid_node((x))->sysname) 137 #define internal_pid_creation(x) (internal_pid_node((x))->creation) 138 #define external_pid_creation(x) (external_pid_node((x))->creation) 139 #define internal_pid_dist_entry(x) (internal_pid_node((x))->dist_entry) 140 #define external_pid_dist_entry(x) (external_pid_node((x))->dist_entry) 141 142 #define internal_pid_channel_no(x) (internal_channel_no((x))) 143 #define external_pid_channel_no(x) (external_channel_no((x))) 144 145 #define pid_data_words(x) (is_internal_pid((x)) \ 146 ? internal_pid_data_words((x)) \ 147 : external_pid_data_words((x))) 148 #define pid_number(x) (is_internal_pid((x)) \ 149 ? internal_pid_number((x)) \ 150 : external_pid_number((x))) 151 #define pid_serial(x) (is_internal_pid((x)) \ 152 ? internal_pid_serial((x)) \ 153 : external_pid_serial((x))) 154 #define pid_node(x) (is_internal_pid((x)) \ 155 ? internal_pid_node((x)) \ 156 : external_pid_node((x))) 157 #define pid_node_name(x) (is_internal_pid((x)) \ 158 ? internal_pid_node_name((x)) \ 159 : external_pid_node_name((x))) 160 #define pid_creation(x) (is_internal_pid((x)) \ 161 ? internal_pid_creation((x)) \ 162 : external_pid_creation((x))) 163 #define pid_dist_entry(x) (is_internal_pid((x)) \ 164 ? internal_pid_dist_entry((x)) \ 165 : external_pid_dist_entry((x))) 166 #define pid_channel_no(x) (is_internal_pid((x)) \ 167 ? internal_pid_channel_no((x)) \ 168 : external_pid_channel_no((x))) 169 #define is_pid(x) (is_internal_pid((x)) \ 170 || is_external_pid((x))) 171 #define is_not_pid(x) (!is_pid(x)) 172 173 /* 174 * Maximum number of processes. We want the number to fit in a SMALL on 175 * 32-bit CPU. 176 */ 177 178 #define ERTS_MAX_PROCESSES (ERTS_PTAB_MAX_SIZE-1) 179 #define ERTS_MAX_PID_DATA ((1 << _PID_DATA_SIZE) - 1) 180 #define ERTS_MAX_PID_NUMBER ((1 << _PID_NUM_SIZE) - 1) 181 #define ERTS_MAX_PID_SERIAL ((1 << _PID_SER_SIZE) - 1) 182 183 #define ERTS_PROC_BITS (_PID_SER_SIZE + _PID_NUM_SIZE) 184 185 #define ERTS_INVALID_PID ERTS_PTAB_INVALID_ID(_TAG_IMMED1_PID) 186 187 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 188 * Ports * 189 \* */ 190 191 extern ErtsPTab erts_port; 192 193 #define make_internal_port(D) erts_ptab_make_id(&erts_port, \ 194 (D), \ 195 _TAG_IMMED1_PORT) 196 197 #define internal_port_index(PRT) (ASSERT(is_internal_port((PRT))), \ 198 erts_ptab_id2pix(&erts_port, (PRT))) 199 200 #define internal_port_data(PRT) (ASSERT(is_internal_port((PRT))), \ 201 erts_ptab_id2data(&erts_port, (PRT))) 202 203 #define internal_port_number(x) _GET_PORT_NUM(internal_port_data((x))) 204 205 #define internal_port_node_name(x) (internal_port_node((x))->sysname) 206 #define external_port_node_name(x) (external_port_node((x))->sysname) 207 #define internal_port_creation(x) (internal_port_node((x))->creation) 208 #define external_port_creation(x) (external_port_node((x))->creation) 209 #define internal_port_dist_entry(x) (internal_port_node((x))->dist_entry) 210 #define external_port_dist_entry(x) (external_port_node((x))->dist_entry) 211 212 #define internal_port_channel_no(x) (internal_channel_no((x))) 213 #define external_port_channel_no(x) (external_channel_no((x))) 214 215 #define port_data_words(x) (is_internal_port((x)) \ 216 ? internal_port_data_words((x))\ 217 : external_port_data_words((x))) 218 #define port_number(x) (is_internal_port((x)) \ 219 ? internal_port_number((x)) \ 220 : external_port_number((x))) 221 #define port_node(x) (is_internal_port((x)) \ 222 ? internal_port_node((x)) \ 223 : external_port_node((x))) 224 #define port_node_name(x) (is_internal_port((x)) \ 225 ? internal_port_node_name((x)) \ 226 : external_port_node_name((x))) 227 #define port_creation(x) (is_internal_port((x)) \ 228 ? internal_port_creation((x)) \ 229 : external_port_creation((x))) 230 #define port_dist_entry(x) (is_internal_port((x)) \ 231 ? internal_port_dist_entry((x))\ 232 : external_port_dist_entry((x))) 233 #define port_channel_no(x) (is_internal_port((x)) \ 234 ? internal_port_channel_no((x))\ 235 : external_port_channel_no((x))) 236 237 #define is_port(x) (is_internal_port((x)) \ 238 || is_external_port((x))) 239 #define is_not_port(x) (!is_port(x)) 240 241 /* Highest port-ID part in a term of type Port 242 Not necessarily the same as current maximum port table size 243 which defines the maximum number of simultaneous Ports 244 in the Erlang node. ERTS_MAX_PORTS is a hard upper limit. 245 */ 246 #define ERTS_MAX_PORTS (ERTS_PTAB_MAX_SIZE-1) 247 #define ERTS_MAX_PORT_DATA ((1 << _PORT_DATA_SIZE) - 1) 248 #define ERTS_MAX_PORT_NUMBER ((1 << _PORT_NUM_SIZE) - 1) 249 250 #define ERTS_PORTS_BITS (_PORT_NUM_SIZE) 251 252 #define ERTS_INVALID_PORT ERTS_PTAB_INVALID_ID(_TAG_IMMED1_PORT) 253 254 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 255 * Refs * 256 \* */ 257 258 #define internal_ref_no_numbers(x) ERTS_REF_NUMBERS 259 #define internal_ref_numbers(x) (is_internal_ordinary_ref((x)) \ 260 ? internal_ordinary_ref_numbers((x)) \ 261 : (ASSERT(is_internal_magic_ref((x))), \ 262 internal_magic_ref_numbers((x)))) 263 #if defined(ARCH_64) 264 265 #define external_ref_no_numbers(x) \ 266 (external_ref_data((x))[0]) 267 #define external_thing_ref_no_numbers(thing) \ 268 (external_thing_ref_data(thing)[0]) 269 #define external_ref_numbers(x) \ 270 (&external_ref_data((x))[1]) 271 #define external_thing_ref_numbers(thing) \ 272 (&external_thing_ref_data(thing)[1]) 273 274 275 #else 276 277 #define external_ref_no_numbers(x) (external_ref_data_words((x))) 278 #define external_thing_ref_no_numbers(t) (external_thing_ref_data_words((t))) 279 #define external_ref_numbers(x) (external_ref_data((x))) 280 #define external_thing_ref_numbers(t) (external_thing_ref_data((t))) 281 282 #endif 283 284 #define internal_ref_node_name(x) (internal_ref_node((x))->sysname) 285 #define external_ref_node_name(x) (external_ref_node((x))->sysname) 286 #define internal_ref_creation(x) (internal_ref_node((x))->creation) 287 #define external_ref_creation(x) (external_ref_node((x))->creation) 288 #define internal_ref_dist_entry(x) (internal_ref_node((x))->dist_entry) 289 #define external_ref_dist_entry(x) (external_ref_node((x))->dist_entry) 290 291 292 #define internal_ref_channel_no(x) (internal_channel_no((x))) 293 #define external_ref_channel_no(x) (external_channel_no((x))) 294 295 #define ref_no_numbers(x) (is_internal_ref((x)) \ 296 ? internal_ref_no_numbers((x))\ 297 : external_ref_no_numbers((x))) 298 #define ref_numbers(x) (is_internal_ref((x)) \ 299 ? internal_ref_numbers((x)) \ 300 : external_ref_numbers((x))) 301 #define ref_node(x) (is_internal_ref((x)) \ 302 ? internal_ref_node(x) \ 303 : external_ref_node((x))) 304 #define ref_node_name(x) (is_internal_ref((x)) \ 305 ? internal_ref_node_name((x)) \ 306 : external_ref_node_name((x))) 307 #define ref_creation(x) (is_internal_ref((x)) \ 308 ? internal_ref_creation((x)) \ 309 : external_ref_creation((x))) 310 #define ref_dist_entry(x) (is_internal_ref((x)) \ 311 ? internal_ref_dist_entry((x)) \ 312 : external_ref_dist_entry((x))) 313 #define ref_channel_no(x) (is_internal_ref((x)) \ 314 ? internal_ref_channel_no((x)) \ 315 : external_ref_channel_no((x))) 316 #define is_ref(x) (is_internal_ref((x)) \ 317 || is_external_ref((x))) 318 #define is_not_ref(x) (!is_ref(x)) 319 320 #endif 321