void erts_init_node_tables(int dd_sec) { erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER; HashFunctions f; ErlNode node_tmpl; if (dd_sec == ERTS_NODE_TAB_DELAY_GC_INFINITY) node_tab_delete_delay = (ErtsMonotonicTime) -1; else node_tab_delete_delay = ((ErtsMonotonicTime) dd_sec)*1000; orig_node_tab_delete_delay = node_tab_delete_delay; rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ; rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED; erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table"); erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table"); f.hash = (H_FUN) dist_table_hash; f.cmp = (HCMP_FUN) dist_table_cmp; f.alloc = (HALLOC_FUN) dist_table_alloc; f.free = (HFREE_FUN) dist_table_free; f.meta_alloc = (HMALLOC_FUN) erts_alloc; f.meta_free = (HMFREE_FUN) erts_free; f.meta_print = (HMPRINT_FUN) erts_print; hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f); f.hash = (H_FUN) node_table_hash; f.cmp = (HCMP_FUN) node_table_cmp; f.alloc = (HALLOC_FUN) node_table_alloc; f.free = (HFREE_FUN) node_table_free; hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f); erts_hidden_dist_entries = NULL; erts_visible_dist_entries = NULL; erts_not_connected_dist_entries = NULL; erts_no_of_hidden_dist_entries = 0; erts_no_of_visible_dist_entries = 0; erts_no_of_not_connected_dist_entries = 0; node_tmpl.sysname = am_Noname; node_tmpl.creation = 0; erts_this_node = hash_put(&erts_node_table, &node_tmpl); /* +1 for erts_this_node */ erts_refc_init(&erts_this_node->refc, 1); ASSERT(erts_this_node->dist_entry != NULL); erts_this_dist_entry = erts_this_node->dist_entry; /* +1 for erts_this_dist_entry */ /* +1 for erts_this_node->dist_entry */ erts_refc_init(&erts_this_dist_entry->refc, 2); erts_this_node_sysname = erts_this_node_sysname_BUFFER; erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER), "%T", erts_this_node->sysname); references_atoms_need_init = 1; }
static int load_driver_entry(DE_Handle **dhp, char *path, char *name) { int res; DE_Handle *dh = erts_alloc(ERTS_ALC_T_DDLL_HANDLE, sizeof(DE_Handle)); assert_drv_list_rwlocked(); dh->handle = NULL; dh->procs = NULL; erts_atomic32_init_nob(&dh->port_count, 0); erts_refc_init(&(dh->refc), (erts_aint_t) 0); dh->status = -1; dh->reload_full_path = NULL; dh->reload_driver_name = NULL; dh->reload_flags = 0; dh->full_path = NULL; dh->flags = 0; if ((res = do_load_driver_entry(dh, path, name)) != ERL_DE_NO_ERROR) { erts_free(ERTS_ALC_T_DDLL_HANDLE, (void *) dh); dh = NULL; } *dhp = dh; return res; }
static void* dist_table_alloc(void *dep_tmpl) { Eterm chnl_nr; Eterm sysname; DistEntry *dep; erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER; rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ; sysname = ((DistEntry *) dep_tmpl)->sysname; chnl_nr = make_small((Uint) atom_val(sysname)); dep = (DistEntry *) erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry)); dist_entries++; dep->prev = NULL; erts_refc_init(&dep->refc, -1); erts_smp_rwmtx_init_opt_x(&dep->rwmtx, &rwmtx_opt, "dist_entry", chnl_nr); dep->sysname = sysname; dep->cid = NIL; dep->connection_id = 0; dep->status = 0; dep->flags = 0; dep->version = 0; erts_smp_mtx_init_x(&dep->lnk_mtx, "dist_entry_links", chnl_nr); dep->node_links = NULL; dep->nlinks = NULL; dep->monitors = NULL; erts_smp_mtx_init_x(&dep->qlock, "dist_entry_out_queue", chnl_nr); dep->qflgs = 0; dep->qsize = 0; dep->out_queue.first = NULL; dep->out_queue.last = NULL; dep->suspended = NULL; dep->finalized_out_queue.first = NULL; dep->finalized_out_queue.last = NULL; erts_smp_atomic_init_nob(&dep->dist_cmd_scheduled, 0); erts_port_task_handle_init(&dep->dist_cmd); dep->send = NULL; dep->cache = NULL; /* Link in */ /* All new dist entries are "not connected". * erts_this_dist_entry is also always included among "not connected" */ dep->next = erts_not_connected_dist_entries; if(erts_not_connected_dist_entries) { ASSERT(erts_not_connected_dist_entries->prev == NULL); erts_not_connected_dist_entries->prev = dep; } erts_not_connected_dist_entries = dep; erts_no_of_not_connected_dist_entries++; return (void *) dep; }
ErlNifResourceType* enif_open_resource_type(ErlNifEnv* env, const char* module_str, const char* name_str, ErlNifResourceDtor* dtor, ErlNifResourceFlags flags, ErlNifResourceFlags* tried) { ErlNifResourceType* type = NULL; ErlNifResourceFlags op = flags; Eterm module_am, name_am; ASSERT(erts_smp_thr_progress_is_blocking()); ASSERT(module_str == NULL); /* for now... */ module_am = make_atom(env->mod_nif->mod->module); name_am = enif_make_atom(env, name_str); type = find_resource_type(module_am, name_am); if (type == NULL) { if (flags & ERL_NIF_RT_CREATE) { type = erts_alloc(ERTS_ALC_T_NIF, sizeof(struct enif_resource_type_t)); type->dtor = dtor; type->module = module_am; type->name = name_am; erts_refc_init(&type->refc, 1); type->owner = env->mod_nif; type->prev = &resource_type_list; type->next = resource_type_list.next; type->next->prev = type; type->prev->next = type; op = ERL_NIF_RT_CREATE; } } else { if (flags & ERL_NIF_RT_TAKEOVER) { steal_resource_type(type); op = ERL_NIF_RT_TAKEOVER; } else { type = NULL; } } if (type != NULL) { type->owner = env->mod_nif; type->dtor = dtor; if (type->dtor != NULL) { erts_refc_inc(&type->owner->rt_dtor_cnt, 1); } erts_refc_inc(&type->owner->rt_cnt, 1); } if (tried != NULL) { *tried = op; } return type; }
void* enif_alloc_resource(ErlNifResourceType* type, size_t size) { Binary* bin = erts_create_magic_binary(SIZEOF_ErlNifResource(size), &nif_resource_dtor); ErlNifResource* resource = ERTS_MAGIC_BIN_DATA(bin); resource->type = type; erts_refc_inc(&bin->refc, 1); #ifdef DEBUG erts_refc_init(&resource->nif_refc, 1); #endif erts_refc_inc(&resource->type->refc, 2); return resource->data; }
static void* node_table_alloc(void *venp_tmpl) { ErlNode *enp; enp = (ErlNode *) erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode)); node_entries++; erts_refc_init(&enp->refc, -1); enp->creation = ((ErlNode *) venp_tmpl)->creation; enp->sysname = ((ErlNode *) venp_tmpl)->sysname; enp->dist_entry = erts_find_or_insert_dist_entry(((ErlNode *) venp_tmpl)->sysname); return (void *) enp; }
int enif_alloc_binary(size_t size, ErlNifBinary* bin) { Binary* refbin; refbin = erts_bin_drv_alloc_fnf(size); /* BUGBUG: alloc type? */ if (refbin == NULL) { return 0; /* The NIF must take action */ } refbin->flags = BIN_FLAG_DRV; /* BUGBUG: Flag? */ erts_refc_init(&refbin->refc, 1); refbin->orig_size = (long) size; bin->size = size; bin->data = (unsigned char*) refbin->orig_bytes; bin->bin_term = THE_NON_VALUE; bin->ref_bin = refbin; return 1; }
static ErtsIOQBinary *alloc_binary(Uint size, char *source, void **iov_base, int driver) { if (driver) { ErlDrvBinary *bin = driver_alloc_binary(size); if (!bin) return NULL; sys_memcpy(bin->orig_bytes, source, size); *iov_base = bin->orig_bytes; return (ErtsIOQBinary *)bin; } else { /* This clause can be triggered in enif_ioq_enq_binary is used */ Binary *bin = erts_bin_nrml_alloc(size); if (!bin) return NULL; erts_refc_init(&bin->intern.refc, 1); sys_memcpy(bin->orig_bytes, source, size); *iov_base = bin->orig_bytes; return (ErtsIOQBinary *)bin; } }
static void* dist_table_alloc(void *dep_tmpl) { DistEntry *dep; if(((DistEntry *) dep_tmpl) == erts_this_dist_entry) return dep_tmpl; dep = (DistEntry *) erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry)); dist_entries++; dep->prev = NULL; erts_refc_init(&dep->refc, -1); dep->sysname = ((DistEntry *) dep_tmpl)->sysname; dep->cid = NIL; dep->nlinks = NULL; dep->node_links = NULL; dep->monitors = NULL; dep->status = 0; dep->flags = 0; dep->cache = NULL; dep->version = 0; #ifdef ERTS_SMP dep->mtxp = &dist_entry_mutexes[(atom_val(dep->sysname) % ERTS_NO_OF_DIST_ENTRY_MUTEXES)]; #endif /* Link in */ /* All new dist entries are "not connected" */ dep->next = erts_not_connected_dist_entries; if(erts_not_connected_dist_entries) { ASSERT(erts_not_connected_dist_entries->prev == NULL); erts_not_connected_dist_entries->prev = dep; } erts_not_connected_dist_entries = dep; erts_no_of_not_connected_dist_entries++; return (void *) dep; }
void erts_slave_serve_refc(struct master_command_refc *cmd) { switch (cmd->op) { case MASTER_REFC_OP_INIT: erts_refc_init(cmd->refcp, cmd->arg); break; case MASTER_REFC_OP_INC: erts_refc_inc(cmd->refcp, cmd->min_val); break; case MASTER_REFC_OP_DEC: erts_refc_dec(cmd->refcp, cmd->min_val); break; case MASTER_REFC_OP_ADD: erts_refc_add(cmd->refcp, cmd->arg, cmd->min_val); break; case MASTER_REFC_OP_DECFREE: erts_refc_decfree(cmd->refcp, cmd->min_val, cmd->kind, cmd->objp); break; default: erl_exit(1, "Unexpected op %d in erts_slave_serve_refc", cmd->op); } }
static void first_ddll_reference(DE_Handle *dh) { assert_drv_list_rwlocked(); erts_refc_init(&(dh->refc),1); }
void erts_init_node_tables(void) { HashFunctions f; f.hash = (H_FUN) dist_table_hash; f.cmp = (HCMP_FUN) dist_table_cmp; f.alloc = (HALLOC_FUN) dist_table_alloc; f.free = (HFREE_FUN) dist_table_free; erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry)); dist_entries = 1; hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f); erts_hidden_dist_entries = NULL; erts_visible_dist_entries = NULL; erts_not_connected_dist_entries = NULL; erts_no_of_hidden_dist_entries = 0; erts_no_of_visible_dist_entries = 0; erts_no_of_not_connected_dist_entries = 0; erts_this_dist_entry->next = NULL; erts_this_dist_entry->prev = NULL; erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */ erts_this_dist_entry->sysname = am_Noname; erts_this_dist_entry->cid = NIL; erts_this_dist_entry->node_links = NULL; erts_this_dist_entry->nlinks = NULL; erts_this_dist_entry->monitors = NULL; erts_this_dist_entry->status = 0; erts_this_dist_entry->flags = 0; erts_this_dist_entry->cache = NULL; erts_this_dist_entry->version = 0; (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry); f.hash = (H_FUN) node_table_hash; f.cmp = (HCMP_FUN) node_table_cmp; f.alloc = (HALLOC_FUN) node_table_alloc; f.free = (HFREE_FUN) node_table_free; hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f); erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode)); node_entries = 1; erts_refc_init(&erts_this_node->refc, 1); /* The system itself */ erts_this_node->sysname = am_Noname; erts_this_node->creation = 0; erts_this_node->dist_entry = erts_this_dist_entry; (void) hash_put(&erts_node_table, (void *) erts_this_node); #ifdef ERTS_SMP { int i; for (i = 0; i < ERTS_NO_OF_DIST_ENTRY_MUTEXES; i++) { #ifdef ERTS_ENABLE_LOCK_COUNT erts_smp_mtx_init_x(&dist_entry_mutexes[i], "dist_entry", make_small(i)); #else erts_smp_mtx_init(&dist_entry_mutexes[i], "dist_entry"); #endif /*ERTS_ENABLE_LOCK_COUNT*/ } erts_this_dist_entry->mtxp = &dist_entry_mutexes[0]; erts_smp_mtx_init(&erts_node_table_mtx, "node_table"); erts_smp_mtx_init(&erts_dist_table_mtx, "dist_table"); } #endif references_atoms_need_init = 1; }
BIF_RETTYPE load_nif_2(BIF_ALIST_2) { static const char bad_lib[] = "bad_lib"; static const char reload[] = "reload"; static const char upgrade[] = "upgrade"; char* lib_name = NULL; void* handle = NULL; void* init_func; ErlNifEntry* entry = NULL; ErlNifEnv env; int len, i, err; Module* mod; Eterm mod_atom; Eterm f_atom; BeamInstr* caller; ErtsSysDdllError errdesc = ERTS_SYS_DDLL_ERROR_INIT; Eterm ret = am_ok; int veto; struct erl_module_nif* lib = NULL; len = list_length(BIF_ARG_1); if (len < 0) { BIF_ERROR(BIF_P, BADARG); } lib_name = (char *) erts_alloc(ERTS_ALC_T_TMP, len + 1); if (intlist_to_buf(BIF_ARG_1, lib_name, len) != len) { erts_free(ERTS_ALC_T_TMP, lib_name); BIF_ERROR(BIF_P, BADARG); } lib_name[len] = '\0'; /* Block system (is this the right place to do it?) */ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_thr_progress_block(); /* Find calling module */ ASSERT(BIF_P->current != NULL); ASSERT(BIF_P->current[0] == am_erlang && BIF_P->current[1] == am_load_nif && BIF_P->current[2] == 2); caller = find_function_from_pc(BIF_P->cp); ASSERT(caller != NULL); mod_atom = caller[0]; ASSERT(is_atom(mod_atom)); mod=erts_get_module(mod_atom); ASSERT(mod != NULL); if (!in_area(caller, mod->code, mod->code_length)) { ASSERT(in_area(caller, mod->old_code, mod->old_code_length)); ret = load_nif_error(BIF_P, "old_code", "Calling load_nif from old " "module '%T' not allowed", mod_atom); } else if ((err=erts_sys_ddll_open2(lib_name, &handle, &errdesc)) != ERL_DE_NO_ERROR) { const char slogan[] = "Failed to load NIF library"; if (strstr(errdesc.str, lib_name) != NULL) { ret = load_nif_error(BIF_P, "load_failed", "%s: '%s'", slogan, errdesc.str); } else { ret = load_nif_error(BIF_P, "load_failed", "%s %s: '%s'", slogan, lib_name, errdesc.str); } } else if (erts_sys_ddll_load_nif_init(handle, &init_func, &errdesc) != ERL_DE_NO_ERROR) { ret = load_nif_error(BIF_P, bad_lib, "Failed to find library init" " function: '%s'", errdesc.str); } else if ((add_taint(mod_atom), (entry = erts_sys_ddll_call_nif_init(init_func)) == NULL)) { ret = load_nif_error(BIF_P, bad_lib, "Library init-call unsuccessful"); } else if (entry->major != ERL_NIF_MAJOR_VERSION || entry->minor > ERL_NIF_MINOR_VERSION) { ret = load_nif_error(BIF_P, bad_lib, "Library version (%d.%d) not compatible (with %d.%d).", entry->major, entry->minor, ERL_NIF_MAJOR_VERSION, ERL_NIF_MINOR_VERSION); } else if (entry->minor >= 1 && sys_strcmp(entry->vm_variant, ERL_NIF_VM_VARIANT) != 0) { ret = load_nif_error(BIF_P, bad_lib, "Library (%s) not compiled for " "this vm variant (%s).", entry->vm_variant, ERL_NIF_VM_VARIANT); } else if (!erts_is_atom_str((char*)entry->name, mod_atom)) { ret = load_nif_error(BIF_P, bad_lib, "Library module name '%s' does not" " match calling module '%T'", entry->name, mod_atom); } else { /*erts_fprintf(stderr, "Found module %T\r\n", mod_atom);*/ for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) { BeamInstr** code_pp; ErlNifFunc* f = &entry->funcs[i]; if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom) || (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) { ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u", mod_atom, f->name, f->arity); } else if (code_pp[1] - code_pp[0] < (5+3)) { ret = load_nif_error(BIF_P,bad_lib,"No explicit call to load_nif" " in module (%T:%s/%u to small)", mod_atom, entry->funcs[i].name, entry->funcs[i].arity); } /*erts_fprintf(stderr, "Found NIF %T:%s/%u\r\n", mod_atom, entry->funcs[i].name, entry->funcs[i].arity);*/ } } if (ret != am_ok) { goto error; } /* Call load, reload or upgrade: */ lib = erts_alloc(ERTS_ALC_T_NIF, sizeof(struct erl_module_nif)); lib->handle = handle; lib->entry = entry; erts_refc_init(&lib->rt_cnt, 0); erts_refc_init(&lib->rt_dtor_cnt, 0); lib->mod = mod; env.mod_nif = lib; if (mod->nif != NULL) { /* Reload */ int k; lib->priv_data = mod->nif->priv_data; ASSERT(mod->nif->entry != NULL); if (entry->reload == NULL) { ret = load_nif_error(BIF_P,reload,"Reload not supported by this NIF library."); goto error; } /* Check that no NIF is removed */ for (k=0; k < mod->nif->entry->num_of_funcs; k++) { ErlNifFunc* old_func = &mod->nif->entry->funcs[k]; for (i=0; i < entry->num_of_funcs; i++) { if (old_func->arity == entry->funcs[i].arity && sys_strcmp(old_func->name, entry->funcs[i].name) == 0) { break; } } if (i == entry->num_of_funcs) { ret = load_nif_error(BIF_P,reload,"Reloaded library missing " "function %T:%s/%u\r\n", mod_atom, old_func->name, old_func->arity); goto error; } } erts_pre_nif(&env, BIF_P, lib); veto = entry->reload(&env, &lib->priv_data, BIF_ARG_2); erts_post_nif(&env); if (veto) { ret = load_nif_error(BIF_P, reload, "Library reload-call unsuccessful."); } else { mod->nif->entry = NULL; /* to prevent 'unload' callback */ erts_unload_nif(mod->nif); } } else { lib->priv_data = NULL; if (mod->old_nif != NULL) { /* Upgrade */ void* prev_old_data = mod->old_nif->priv_data; if (entry->upgrade == NULL) { ret = load_nif_error(BIF_P, upgrade, "Upgrade not supported by this NIF library."); goto error; } erts_pre_nif(&env, BIF_P, lib); veto = entry->upgrade(&env, &lib->priv_data, &mod->old_nif->priv_data, BIF_ARG_2); erts_post_nif(&env); if (veto) { mod->old_nif->priv_data = prev_old_data; ret = load_nif_error(BIF_P, upgrade, "Library upgrade-call unsuccessful."); } /*else if (mod->old_nif->priv_data != prev_old_data) { refresh_cached_nif_data(mod->old_code, mod->old_nif); }*/ } else if (entry->load != NULL) { /* Initial load */ erts_pre_nif(&env, BIF_P, lib); veto = entry->load(&env, &lib->priv_data, BIF_ARG_2); erts_post_nif(&env); if (veto) { ret = load_nif_error(BIF_P, "load", "Library load-call unsuccessful."); } } } if (ret == am_ok) { /* ** Everything ok, patch the beam code with op_call_nif */ mod->nif = lib; for (i=0; i < entry->num_of_funcs; i++) { BeamInstr* code_ptr; erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom); code_ptr = *get_func_pp(mod->code, f_atom, entry->funcs[i].arity); if (code_ptr[1] == 0) { code_ptr[5+0] = (BeamInstr) BeamOp(op_call_nif); } else { /* Function traced, patch the original instruction word */ BpData** bps = (BpData**) code_ptr[1]; BpData* bp = (BpData*) bps[erts_bp_sched2ix()]; bp->orig_instr = (BeamInstr) BeamOp(op_call_nif); } code_ptr[5+1] = (BeamInstr) entry->funcs[i].fptr; code_ptr[5+2] = (BeamInstr) lib; } } else { error: ASSERT(ret != am_ok); if (lib != NULL) { erts_free(ERTS_ALC_T_NIF, lib); } if (handle != NULL) { erts_sys_ddll_close(handle); } erts_sys_ddll_free_error(&errdesc); } erts_smp_thr_progress_unblock(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_free(ERTS_ALC_T_TMP, lib_name); BIF_RET(ret); }
void erts_init_node_tables(int dd_sec) { erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER; HashFunctions f; if (dd_sec == ERTS_NODE_TAB_DELAY_GC_INFINITY) node_tab_delete_delay = (ErtsMonotonicTime) -1; else node_tab_delete_delay = ((ErtsMonotonicTime) dd_sec)*1000; orig_node_tab_delete_delay = node_tab_delete_delay; rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ; rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED; f.hash = (H_FUN) dist_table_hash; f.cmp = (HCMP_FUN) dist_table_cmp; f.alloc = (HALLOC_FUN) dist_table_alloc; f.free = (HFREE_FUN) dist_table_free; erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry)); dist_entries = 1; hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f); erts_hidden_dist_entries = NULL; erts_visible_dist_entries = NULL; erts_not_connected_dist_entries = NULL; erts_no_of_hidden_dist_entries = 0; erts_no_of_visible_dist_entries = 0; erts_no_of_not_connected_dist_entries = 0; erts_this_dist_entry->next = NULL; erts_this_dist_entry->prev = NULL; erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */ erts_smp_rwmtx_init_opt_x(&erts_this_dist_entry->rwmtx, &rwmtx_opt, "dist_entry", make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->sysname = am_Noname; erts_this_dist_entry->cid = NIL; erts_this_dist_entry->connection_id = 0; erts_this_dist_entry->status = 0; erts_this_dist_entry->flags = 0; erts_this_dist_entry->version = 0; erts_smp_mtx_init_x(&erts_this_dist_entry->lnk_mtx, "dist_entry_links", make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->node_links = NULL; erts_this_dist_entry->nlinks = NULL; erts_this_dist_entry->monitors = NULL; erts_smp_mtx_init_x(&erts_this_dist_entry->qlock, "dist_entry_out_queue", make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->qflgs = 0; erts_this_dist_entry->qsize = 0; erts_this_dist_entry->out_queue.first = NULL; erts_this_dist_entry->out_queue.last = NULL; erts_this_dist_entry->suspended = NULL; erts_this_dist_entry->finalized_out_queue.first = NULL; erts_this_dist_entry->finalized_out_queue.last = NULL; erts_smp_atomic_init_nob(&erts_this_dist_entry->dist_cmd_scheduled, 0); erts_port_task_handle_init(&erts_this_dist_entry->dist_cmd); erts_this_dist_entry->send = NULL; erts_this_dist_entry->cache = NULL; (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry); f.hash = (H_FUN) node_table_hash; f.cmp = (HCMP_FUN) node_table_cmp; f.alloc = (HALLOC_FUN) node_table_alloc; f.free = (HFREE_FUN) node_table_free; hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f); erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode)); node_entries = 1; erts_refc_init(&erts_this_node->refc, 1); /* The system itself */ erts_this_node->sysname = am_Noname; erts_this_node->creation = 0; erts_this_node->dist_entry = erts_this_dist_entry; erts_this_node_sysname = erts_this_node_sysname_BUFFER; erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER), "%T", erts_this_node->sysname); (void) hash_put(&erts_node_table, (void *) erts_this_node); erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table"); erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table"); references_atoms_need_init = 1; }