static ERTS_INLINE Eterm make_unique_monotonic_integer_value(Eterm *hp, Uint hsz, Uint64 raw, int positive) { Eterm res; #ifdef DEBUG Eterm *end_hp = hp + hsz; #endif if (positive) { Uint64 value = raw+1; res = hsz ? erts_uint64_to_big(value, &hp) : make_small(value); } else { Sint64 value = ((Sint64) raw) + ERTS_UNIQUE_MONOTONIC_OFFSET; if (hsz == 0) res = make_small(value); else { #if defined(ARCH_32) res = erts_sint64_to_big(value, &hp); #else res = erts_uint64_to_big((Uint64) value, &hp); #endif } } ASSERT(end_hp == hp); return res; }
static int http_request_erl(void* arg, const http_atom_t* meth, const char* meth_ptr, int meth_len, const PacketHttpURI* uri, int major, int minor) { struct packet_callback_args* pca = (struct packet_callback_args*) arg; Eterm meth_term, uri_term, ver_term; Uint sz = 0; Uint* szp = &sz; Eterm* hp; Eterm** hpp = NULL; /* {http_request,Meth,Uri,Version} */ for (;;) { meth_term = (meth!=NULL) ? meth->atom : http_bld_string(pca, hpp, szp, meth_ptr, meth_len); uri_term = http_bld_uri(pca, hpp, szp, uri); ver_term = erts_bld_tuple(hpp, szp, 2, make_small(major), make_small(minor)); pca->res = erts_bld_tuple(hpp, szp, 4, am_http_request, meth_term, uri_term, ver_term); if (hpp != NULL) break; hpp = &hp; hp = HAlloc(pca->p, sz); szp = NULL; } return 1; }
ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i) { #if SIZEOF_INT == ERTS_SIZEOF_ETERM return IS_SSMALL(i) ? make_small(i) : small_to_big(i,alloc_heap(env,2)); #elif SIZEOF_LONG == ERTS_SIZEOF_ETERM return make_small(i); #endif }
ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i) { #if SIZEOF_INT == ERTS_SIZEOF_ETERM return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2)); #elif SIZEOF_LONG == ERTS_SIZEOF_ETERM return make_small(i); #endif }
/* return a timestamp */ BIF_RETTYPE os_timestamp_0(BIF_ALIST_0) { Uint megasec, sec, microsec; Eterm* hp; get_sys_now(&megasec, &sec, µsec); hp = HAlloc(BIF_P, 4); BIF_RET(TUPLE3(hp, make_small(megasec), make_small(sec), make_small(microsec))); }
int erts_is_time_break(Process *p, BeamInstr *pc, Eterm *retval) { Uint i, ix; bp_time_hash_t hash; Uint size; Eterm *hp, t; bp_data_time_item_t *item = NULL; BpDataTime *bdt = (BpDataTime *) is_break(pc, (BeamInstr) BeamOp(op_i_time_breakpoint)); if (bdt) { if (retval) { /* collect all hashes to one hash */ bp_hash_init(&hash, 64); /* foreach threadspecific hash */ for (i = 0; i < bdt->n; i++) { bp_data_time_item_t *sitem; /* foreach hash bucket not NIL*/ for(ix = 0; ix < bdt->hash[i].n; ix++) { item = &(bdt->hash[i].item[ix]); if (item->pid != NIL) { sitem = bp_hash_get(&hash, item); if (sitem) { BP_TIME_ADD(sitem, item); } else { bp_hash_put(&hash, item); } } } } /* *retval should be NIL or term from previous bif in export entry */ if (hash.used > 0) { size = (5 + 2)*hash.used; hp = HAlloc(p, size); for(ix = 0; ix < hash.n; ix++) { item = &(hash.item[ix]); if (item->pid != NIL) { t = TUPLE4(hp, item->pid, make_small(item->count), make_small(item->s_time), make_small(item->us_time)); hp += 5; *retval = CONS(hp, t, *retval); hp += 2; } } } bp_hash_delete(&hash); } return !0; } return 0; }
ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i) { if (IS_USMALL(0,i)) { return make_small(i); } #if SIZEOF_LONG == ERTS_SIZEOF_ETERM return uint_to_big(i,alloc_heap(env,2)); #elif SIZEOF_LONG_LONG == ERTS_SIZEOF_ETERM return make_small(i); #elif SIZEOF_LONG == 8 ensure_heap(env,3); return erts_uint64_to_big(i, &env->hp); #endif }
BIF_RETTYPE bit_size_1(BIF_ALIST_1) { Uint low_bits; Uint bytesize; Uint high_bits; if (is_binary(BIF_ARG_1)) { bytesize = binary_size(BIF_ARG_1); high_bits = bytesize >> ((sizeof(Uint) * 8)-3); low_bits = (bytesize << 3) + binary_bitsize(BIF_ARG_1); if (high_bits == 0) { if (IS_USMALL(0,low_bits)) { BIF_RET(make_small(low_bits)); } else { Eterm* hp = HAlloc(BIF_P, BIG_UINT_HEAP_SIZE); BIF_RET(uint_to_big(low_bits, hp)); } } else { Uint sz = BIG_UINT_HEAP_SIZE+1; Eterm* hp = HAlloc(BIF_P, sz); hp[0] = make_pos_bignum_header(sz-1); BIG_DIGIT(hp,0) = low_bits; BIG_DIGIT(hp,1) = high_bits; BIF_RET(make_big(hp)); } } else {
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; }
static Eterm http_bld_uri(struct packet_callback_args* pca, Eterm** hpp, Uint* szp, const PacketHttpURI* uri) { Eterm s1, s2; if (uri->type == URI_STAR) { return am_Times; /* '*' */ } s1 = http_bld_string(pca, hpp, szp, uri->s1_ptr, uri->s1_len); switch (uri->type) { case URI_ABS_PATH: return erts_bld_tuple(hpp, szp, 2, am_abs_path, s1); case URI_HTTP: case URI_HTTPS: s2 = http_bld_string(pca, hpp, szp, uri->s2_ptr, uri->s2_len); return erts_bld_tuple (hpp, szp, 5, am_absoluteURI, ((uri->type==URI_HTTP) ? am_http : am_https), s1, ((uri->port==0) ? am_undefined : make_small(uri->port)), s2); case URI_STRING: return s1; case URI_SCHEME: s2 = http_bld_string(pca, hpp, szp, uri->s2_ptr, uri->s2_len); return erts_bld_tuple(hpp, szp, 3, am_scheme, s1, s2); default: erts_exit(ERTS_ERROR_EXIT, "%s, line %d: type=%u\n", __FILE__, __LINE__, uri->type); } }
Eterm hipe_build_stacktrace(Process *p, struct StackTrace *s) { int depth, i; Uint heap_size; Eterm *hp, *hp_end, mfa, m, f, head, *next_p, next; const void *ra; unsigned int a; depth = s->depth; if (depth < 1) return NIL; heap_size = 6 * depth; /* each [{M,F,A}|_] is 2+4 == 6 words */ hp = HAlloc(p, heap_size); hp_end = hp + heap_size; head = NIL; next_p = &head; for (i = 0; i < depth; ++i) { ra = (const void*)s->trace[i]; if (!hipe_find_mfa_from_ra(ra, &m, &f, &a)) continue; mfa = TUPLE3(hp, m, f, make_small(a)); hp += 4; next = CONS(hp, mfa, NIL); *next_p = next; next_p = &CDR(list_val(next)); hp += 2; } HRelease(p, hp_end, hp); return head; }
BIF_RETTYPE size_1(BIF_ALIST_1) { if (is_tuple(BIF_ARG_1)) { Eterm* tupleptr = tuple_val(BIF_ARG_1); BIF_RET(make_small(arityval(*tupleptr))); } else if (is_binary(BIF_ARG_1)) { Uint sz = binary_size(BIF_ARG_1); if (IS_USMALL(0, sz)) { return make_small(sz); } else { Eterm* hp = HAlloc(BIF_P, BIG_UINT_HEAP_SIZE); BIF_RET(uint_to_big(sz, hp)); } } BIF_ERROR(BIF_P, BADARG); }
static void serialize_small_test( void ) { int i; bson b; for ( i=0; i<PER_TRIAL; i++ ) { make_small( &b, i ); bson_destroy( &b ); } }
BIF_RETTYPE hipe_bifs_process_info_0(BIF_ALIST_0) { #ifdef __BENCHMARK__ #ifndef BM_COUNTERS Uint processes_busy = 0; Uint processes_spawned = 0; #endif Eterm *hp; hp = HAlloc(BIF_P, 3); BIF_RET(TUPLE2(hp, make_small(processes_busy), make_small(processes_spawned))); #else BIF_RET(am_false); #endif }
BIF_RETTYPE hipe_bifs_system_timer_0(BIF_ALIST_0) { #ifdef __BENCHMARK__ uint min = 0; uint sec = 0; uint milli = 0; Eterm *hp; hp = HAlloc(BIF_P, 4); MAKE_TIME(system); BIF_RET(TUPLE3(hp, make_small(min), make_small(sec), make_small(milli))); #else BIF_RET(am_false); #endif }
static void single_insert_small_test( void ) { int i; bson b; for ( i=0; i<PER_TRIAL; i++ ) { make_small( &b, i ); mongo_insert( conn, DB ".single.small", &b, NULL ); bson_destroy( &b ); } }
static void index_insert_small_test( void ) { int i; bson b; ASSERT( mongo_create_simple_index( conn, DB ".index.small", "x", 0, NULL ) == MONGO_OK ); for ( i=0; i<PER_TRIAL; i++ ) { make_small( &b, i ); mongo_insert( conn, DB ".index.small", &b, NULL ); bson_destroy( &b ); } }
static Eterm build_load_error_hp(Eterm *hp, int code) { ErrcodeEntry *ee = errcode_tab; while (ee->atm != NULL) { if (ee->code == code) { return mkatom(ee->atm); } ++ee; } return TUPLE2(hp,am_open_error, make_small(code)); }
ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i) { if (IS_SSMALL(i)) { return make_small(i); } #if SIZEOF_LONG == ERTS_SIZEOF_ETERM return small_to_big(i, alloc_heap(env,2)); #elif SIZEOF_LONG == 8 ensure_heap(env,3); return erts_sint64_to_big(i, &env->hp); #endif }
BIF_RETTYPE hipe_bifs_incremental_gc_info_0(BIF_ALIST_0) { #ifdef __BENCHMARK__ #if !defined(BM_COUNTERS) Uint minor_gc_cycles = 0; Uint major_gc_cycles = 0; Uint minor_gc_stages = 0; Uint major_gc_stages = 0; #endif Eterm *hp; hp = HAlloc(BIF_P, 5); BIF_RET(TUPLE4(hp, make_small(minor_gc_cycles), make_small(major_gc_cycles), make_small(minor_gc_stages), make_small(major_gc_stages))); #else BIF_RET(am_false); #endif }
BIF_RETTYPE hipe_bifs_shared_gc_info_0(BIF_ALIST_0) { #ifdef __BENCHMARK__ #if !(defined(BM_COUNTERS)) Uint minor_global_gc = 0; Uint major_global_gc = 0; #endif #ifndef BM_HEAP_SIZES Uint max_used_global_heap = 0; Uint max_allocated_global_heap = 0; #endif Eterm *hp; Uint tmp_used_heap = 0; Uint tmp_allocated_heap = 0; hp = HAlloc(BIF_P, 7); BIF_RET(TUPLE6(hp, make_small((uint)minor_global_gc), make_small((uint)major_global_gc), make_small(tmp_used_heap), make_small(tmp_allocated_heap), make_small(max_used_global_heap), make_small(max_allocated_global_heap))); #else BIF_RET(am_false); #endif }
BIF_RETTYPE hipe_bifs_gc_info_0(BIF_ALIST_0) { #ifdef __BENCHMARK__ #ifndef BM_COUNTERS Uint minor_gc = 0; Uint major_gc = 0; #endif #ifndef BM_HEAP_SIZES Uint max_used_heap = 0; Uint max_allocated_heap = 0; #endif Eterm *hp; Uint used_heap = (BIF_P->htop - BIF_P->heap) + (OLD_HTOP(BIF_P) - OLD_HEAP(BIF_P)) + MBUF_SIZE(BIF_P); Uint alloc_heap = (BIF_P->hend - BIF_P->heap) + (OLD_HEND(BIF_P) - OLD_HEAP(BIF_P)) + MBUF_SIZE(BIF_P); hp = HAlloc(BIF_P, 7); BIF_RET(TUPLE6(hp, make_small((Uint)minor_gc), make_small((Uint)major_gc), make_small((Uint)used_heap), make_small((Uint)alloc_heap), make_small(max_used_heap), make_small(max_allocated_heap))); #else BIF_RET(am_false); #endif }
BIF_RETTYPE hipe_bifs_message_info_0(BIF_ALIST_0) { #ifdef __BENCHMARK__ Eterm *hp; #ifndef BM_COUNTERS unsigned long messages_sent = 0; unsigned long messages_copied = 0; unsigned long messages_ego = 0; #endif #ifndef BM_MESSAGE_SIZES unsigned long words_sent = 0; unsigned long words_copied = 0; unsigned long words_prealloc = 0; #endif hp = HAlloc(BIF_P, 7); BIF_RET(TUPLE6(hp, make_small(messages_sent), make_small(messages_copied), make_small(messages_ego), make_small(words_sent), make_small(words_copied), make_small(words_prealloc))); #else BIF_RET(am_false); #endif }
static int ssl_tls_erl(void* arg, unsigned type, unsigned major, unsigned minor, const char* buf, int len, const char* prefix, int plen) { struct packet_callback_args* pca = (struct packet_callback_args*) arg; Eterm* hp; Eterm ver; Eterm bin = new_binary(pca->p, NULL, plen+len); byte* bin_ptr = binary_bytes(bin); memcpy(bin_ptr+plen, buf, len); if (plen) { memcpy(bin_ptr, prefix, plen); } /* {ssl_tls,NIL,ContentType,{Major,Minor},Bin} */ hp = HAlloc(pca->p, 3+6); ver = TUPLE2(hp, make_small(major), make_small(minor)); hp += 3; pca->res = TUPLE5(hp, am_ssl_tls, NIL, make_small(type), ver, bin); return 1; }
/* * Build a single {M,F,A,Loction} item to be part of * a stack trace. */ Eterm* erts_build_mfa_item(FunctionInfo* fi, Eterm* hp, Eterm args, Eterm* mfa_p) { BeamInstr* current = fi->current; Eterm loc = NIL; if (fi->loc != LINE_INVALID_LOCATION) { Eterm tuple; int line = LOC_LINE(fi->loc); int file = LOC_FILE(fi->loc); Eterm file_term = NIL; if (file == 0) { Atom* ap = atom_tab(atom_val(fi->current[0])); file_term = buf_to_intlist(&hp, ".erl", 4, NIL); file_term = buf_to_intlist(&hp, (char*)ap->name, ap->len, file_term); } else { Atom* ap = atom_tab(atom_val((fi->fname_ptr)[file-1])); file_term = buf_to_intlist(&hp, (char*)ap->name, ap->len, NIL); } tuple = TUPLE2(hp, am_line, make_small(line)); hp += 3; loc = CONS(hp, tuple, loc); hp += 2; tuple = TUPLE2(hp, am_file, file_term); hp += 3; loc = CONS(hp, tuple, loc); hp += 2; } if (is_list(args) || is_nil(args)) { *mfa_p = TUPLE4(hp, current[0], current[1], args, loc); } else { Eterm arity = make_small(current[2]); *mfa_p = TUPLE4(hp, current[0], current[1], arity, loc); } return hp + 5; }
static int http_header_erl(void* arg, const http_atom_t* name, const char* name_ptr, int name_len, const char* value_ptr, int value_len) { struct packet_callback_args* pca = (struct packet_callback_args*) arg; Eterm bit_term, name_term, val_term; Uint sz = 6; Eterm* hp; #ifdef DEBUG Eterm* hend; #endif /* {http_header,Bit,Name,IValue,Value} */ if (name == NULL) { http_bld_string(pca, NULL, &sz, name_ptr, name_len); } http_bld_string(pca, NULL, &sz, value_ptr, value_len); hp = HAlloc(pca->p, sz); #ifdef DEBUG hend = hp + sz; #endif if (name != NULL) { bit_term = make_small(name->index+1); name_term = name->atom; } else { bit_term = make_small(0); name_term = http_bld_string(pca, &hp,NULL,name_ptr,name_len); } val_term = http_bld_string(pca, &hp, NULL, value_ptr, value_len); pca->res = TUPLE5(hp, am_http_header, bit_term, name_term, am_undefined, val_term); ASSERT(hp+6==hend); return 1; }
BIF_RETTYPE erts_debug_size_shared_1(BIF_ALIST_1) { Process* p = BIF_P; Eterm term = BIF_ARG_1; Uint size = size_shared(term); if (IS_USMALL(0, size)) { BIF_RET(make_small(size)); } else { Eterm* hp = HAlloc(p, BIG_UINT_HEAP_SIZE); BIF_RET(uint_to_big(size, hp)); } }
BIF_RETTYPE hipe_bifs_call_count_get_1(BIF_ALIST_1) { Eterm *pc; struct hipe_call_count *hcc; pc = hipe_bifs_find_pc_from_mfa(BIF_ARG_1); if (!pc) BIF_ERROR(BIF_P, BADARG); ASSERT(pc[-5] == BeamOpCode(op_i_func_info_IaaI)); if (pc[0] != BeamOpCode(op_hipe_call_count)) BIF_RET(am_false); hcc = (struct hipe_call_count*)pc[-4]; BIF_RET(make_small(hcc->count)); }
Eterm erts_debug_get_unique_monotonic_integer_state(Process *c_p) { Uint64 value; Eterm hsz, *hp; value = (Uint64) erts_atomic64_read_mb(&raw_unique_monotonic_integer.w.value); if (IS_USMALL(0, value)) return make_small(value); hsz = ERTS_UINT64_HEAP_SIZE(value); hp = HAlloc(c_p, hsz); return erts_uint64_to_big(value, &hp); }
BIF_RETTYPE abs_1(BIF_ALIST_1) { Eterm res; Sint i0, i; Eterm* hp; /* integer arguments */ if (is_small(BIF_ARG_1)) { i0 = signed_val(BIF_ARG_1); i = ERTS_SMALL_ABS(i0); if (i0 == MIN_SMALL) { hp = HAlloc(BIF_P, BIG_UINT_HEAP_SIZE); BIF_RET(uint_to_big(i, hp)); } else { BIF_RET(make_small(i)); } } else if (is_big(BIF_ARG_1)) { if (!big_sign(BIF_ARG_1)) { BIF_RET(BIF_ARG_1); } else { int sz = big_arity(BIF_ARG_1) + 1; Uint* x; hp = HAlloc(BIF_P, sz); /* See note at beginning of file */ sz--; res = make_big(hp); x = big_val(BIF_ARG_1); *hp++ = make_pos_bignum_header(sz); x++; /* skip thing */ while(sz--) *hp++ = *x++; BIF_RET(res); } } else if (is_float(BIF_ARG_1)) { FloatDef f; GET_DOUBLE(BIF_ARG_1, f); if (f.fd < 0.0) { hp = HAlloc(BIF_P, FLOAT_SIZE_OBJECT); f.fd = fabs(f.fd); res = make_float(hp); PUT_DOUBLE(f, hp); BIF_RET(res); } else BIF_RET(BIF_ARG_1); } BIF_ERROR(BIF_P, BADARG); }