4
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
4
* Copyright Ericsson AB 2001-2010. All Rights Reserved.
6
6
* The contents of this file are subject to the Erlang Public License,
7
7
* Version 1.1, (the "License"); you may not use this file except in
8
8
* compliance with the License. You should have received a copy of the
9
9
* Erlang Public License along with this software. If not, it can be
10
10
* retrieved online at http://www.erlang.org/.
12
12
* Software distributed under the License is distributed on an "AS IS"
13
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
* the License for the specific language governing rights and limitations
15
15
* under the License.
94
96
erts_refc_init(&dep->refc, -1);
95
erts_smp_rwmtx_init_x(&dep->rwmtx, "dist_entry", chnl_nr);
97
erts_smp_rwmtx_init_opt_x(&dep->rwmtx, &rwmtx_opt, "dist_entry", chnl_nr);
96
98
dep->sysname = sysname;
98
100
dep->connection_id = 0;
170
172
ASSERT(!dep->cache);
171
173
erts_smp_rwmtx_destroy(&dep->rwmtx);
172
174
erts_smp_mtx_destroy(&dep->lnk_mtx);
173
erts_smp_spinlock_destroy(&dep->qlock);
175
erts_smp_mtx_destroy(&dep->qlock);
176
178
sys_memset(vdep, 0x77, sizeof(DistEntry));
233
235
erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
234
236
res_dep = (DistEntry *) hash_get(&erts_dist_table, (void *) &de);
236
long refc = erts_refc_inctest(&res_dep->refc, 1);
238
erts_aint_t refc = erts_refc_inctest(&res_dep->refc, 1);
237
239
if (refc < 2) /* Pending delete */
238
240
erts_refc_inc(&res_dep->refc, 1);
277
279
erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
278
280
res = hash_get(&erts_dist_table, (void *) &de);
280
long refc = erts_refc_inctest(&res->refc, 1);
282
erts_aint_t refc = erts_refc_inctest(&res->refc, 1);
281
283
if (refc < 2) /* Pending delete */
282
284
erts_refc_inc(&res->refc, 1);
581
583
ne.sysname = sysname;
582
584
ne.creation = creation;
586
erts_smp_rwmtx_rlock(&erts_node_table_rwmtx);
587
res = hash_get(&erts_node_table, (void *) &ne);
588
if (res && res != erts_this_node) {
589
erts_aint_t refc = erts_refc_inctest(&res->refc, 0);
590
if (refc < 2) /* New or pending delete */
591
erts_refc_inc(&res->refc, 1);
593
erts_smp_rwmtx_runlock(&erts_node_table_rwmtx);
583
597
erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
584
598
res = hash_put(&erts_node_table, (void *) &ne);
586
600
if (res != erts_this_node) {
587
long refc = erts_refc_inctest(&res->refc, 0);
601
erts_aint_t refc = erts_refc_inctest(&res->refc, 0);
588
602
if (refc < 2) /* New or pending delete */
589
603
erts_refc_inc(&res->refc, 1);
697
711
void erts_init_node_tables(void)
713
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
716
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
717
rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED;
701
719
f.hash = (H_FUN) dist_table_hash;
702
720
f.cmp = (HCMP_FUN) dist_table_cmp;
703
721
f.alloc = (HALLOC_FUN) dist_table_alloc;
719
737
erts_this_dist_entry->prev = NULL;
720
738
erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */
722
erts_smp_rwmtx_init_x(&erts_this_dist_entry->rwmtx,
724
make_small(ERST_INTERNAL_CHANNEL_NO));
740
erts_smp_rwmtx_init_opt_x(&erts_this_dist_entry->rwmtx,
743
make_small(ERST_INTERNAL_CHANNEL_NO));
725
744
erts_this_dist_entry->sysname = am_Noname;
726
745
erts_this_dist_entry->cid = NIL;
727
746
erts_this_dist_entry->connection_id = 0;
736
755
erts_this_dist_entry->nlinks = NULL;
737
756
erts_this_dist_entry->monitors = NULL;
739
erts_smp_spinlock_init_x(&erts_this_dist_entry->qlock,
740
"dist_entry_out_queue",
741
make_small(ERST_INTERNAL_CHANNEL_NO));
758
erts_smp_mtx_init_x(&erts_this_dist_entry->qlock,
759
"dist_entry_out_queue",
760
make_small(ERST_INTERNAL_CHANNEL_NO));
742
761
erts_this_dist_entry->qflgs = 0;
743
762
erts_this_dist_entry->qsize = 0;
744
763
erts_this_dist_entry->out_queue.first = NULL;
773
792
(void) hash_put(&erts_node_table, (void *) erts_this_node);
775
erts_smp_rwmtx_init(&erts_node_table_rwmtx, "node_table");
776
erts_smp_rwmtx_init(&erts_dist_table_rwmtx, "dist_table");
794
erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table");
795
erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table");
778
797
references_atoms_need_init = 1;
1088
1107
insert_offheap(ErlOffHeap *oh, int type, Eterm id)
1091
ExternalThing *etp = oh->externals;
1093
insert_node(etp->node, type, id);
1109
union erl_off_heap_ptr u;
1110
struct insert_offheap2_arg a;
1100
struct insert_offheap2_arg a;
1102
for(pb = oh->mso; pb; pb = pb->next) {
1103
if(IsMatchProgBinary(pb->val)) {
1113
for (u.hdr = oh->first; u.hdr; u.hdr = u.hdr->next) {
1114
switch (thing_subtag(u.hdr->thing_word)) {
1115
case REFC_BINARY_SUBTAG:
1116
if(IsMatchProgBinary(u.pb->val)) {
1104
1117
InsertedBin *ib;
1105
1118
int insert_bin = 1;
1106
1119
for (ib = inserted_bins; ib; ib = ib->next)
1107
if(ib->bin_val == pb->val) {
1120
if(ib->bin_val == u.pb->val) {
1108
1121
insert_bin = 0;
1111
1124
if (insert_bin) {
1112
Uint id_heap[BIG_UINT_HEAP_SIZE];
1126
UWord val = (UWord) u.pb->val;
1127
DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE*2); /* extra place allocated */
1129
DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE);
1113
1131
Uint *hp = &id_heap[0];
1114
1132
InsertedBin *nib;
1115
a.id = erts_bld_uint(&hp, NULL, (Uint) pb->val);
1116
erts_match_prog_foreach_offheap(pb->val,
1134
int actual_need = BIG_UWORD_HEAP_SIZE(val);
1135
ASSERT(actual_need <= (BIG_UINT_HEAP_SIZE*2));
1136
UseTmpHeapNoproc(actual_need);
1137
a.id = erts_bld_uword(&hp, NULL, (UWord) val);
1139
UseTmpHeapNoproc(BIG_UINT_HEAP_SIZE);
1140
a.id = erts_bld_uint(&hp, NULL, (Uint) u.pb->val);
1142
erts_match_prog_foreach_offheap(u.pb->val,
1117
1143
insert_offheap2,
1119
1145
nib = erts_alloc(ERTS_ALC_T_NC_TMP, sizeof(InsertedBin));
1120
nib->bin_val = pb->val;
1146
nib->bin_val = u.pb->val;
1121
1147
nib->next = inserted_bins;
1122
1148
inserted_bins = nib;
1150
UnUseTmpHeapNoproc(actual_need);
1152
UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE);
1158
break; /* No need to */
1160
ASSERT(is_external_header(u.hdr->thing_word));
1161
insert_node(u.ext->node, type, id);
1135
1167
static void doit_insert_monitor(ErtsMonitor *monitor, void *p)
1190
1222
insert_bif_timer(Eterm receiver, Eterm msg, ErlHeapFragment *bp, void *arg)
1225
DeclareTmpHeapNoproc(heap,3);
1227
UseTmpHeapNoproc(3);
1194
1228
insert_offheap(&bp->off_heap,
1196
1230
(is_internal_pid(receiver)
1198
1232
: TUPLE2(&heap[0], AM_process, receiver)));
1233
UnUseTmpHeapNoproc(3);
1251
1286
/* Go through the hole system, and build a table of all references
1252
1287
to ErlNode and DistEntry structures */
1289
UseTmpHeapNoproc(3);
1254
1290
insert_node(erts_this_node,
1256
1292
TUPLE2(&heap[0], AM_system, am_undefined));
1262
1298
TUPLE2(&heap[0], AM_processes, am_undefined));
1300
UnUseTmpHeapNoproc(3);
1265
1302
/* Insert all processes */
1266
1303
for (i = 0; i < erts_max_processes; i++)
1267
1304
if (process_tab[i]) {
1268
1305
ErlMessage *msg;
1269
1307
/* Insert Heap */
1270
1308
insert_offheap(&(process_tab[i]->off_heap),
1353
1391
{ /* Add binaries stored elsewhere ... */
1355
ProcBin pb[2] = {{0},{0}};
1356
ProcBin *mso = NULL;
1358
1395
Binary *default_match_spec;
1359
1396
Binary *default_meta_match_spec;
1361
/* Only the ProcBin members val and next will be inspected
1399
/* Only the ProcBin members thing_word, val and next will be inspected
1362
1400
(by insert_offheap()) */
1363
1401
#undef ADD_BINARY
1364
#define ADD_BINARY(Bin) \
1366
pb[i].val = (Bin); \
1402
#define ADD_BINARY(Bin) \
1404
pb[i].thing_word = REFC_BINARY_SUBTAG; \
1405
pb[i].val = (Bin); \
1406
pb[i].next = oh.first; \
1407
oh.first = (struct erl_off_heap_header*) &pb[i]; \
1372
1411
erts_get_default_trace_pattern(NULL,