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

📄 utils.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
		Uint i = 0;		Uint n = BIG_SIZE(ptr);		Uint32 con = BIG_SIGN(ptr) ? HCONST_10 : HCONST_11;		do {		    Uint x, y;		    ASSERT(sizeof(digit_t) <= 4);		    ASSERT(D_EXP < 8*sizeof(Uint));		    x = i < n ? BIG_DIGIT(ptr, i++) : 0;		    if (sizeof(digit_t) == 2)			x += (Uint)(i < n ? BIG_DIGIT(ptr, i++) : 0) << D_EXP;		    y = i < n ? BIG_DIGIT(ptr, i++) : 0;		    if (sizeof(digit_t) == 2)			y += (Uint)(i < n ? BIG_DIGIT(ptr, i++) : 0) << D_EXP;		    UINT32_HASH_2((Uint32)x, (Uint32)y, con);		} while (i < n);		goto hash2_common;	    }	    break;	    case REF_SUBTAG:		UINT32_HASH(internal_ref_numbers(term)[0], HCONST_7);		goto hash2_common;		break;	    case EXTERNAL_REF_SUBTAG:		UINT32_HASH(external_ref_numbers(term)[0], HCONST_7);		goto hash2_common;		break;	    case EXTERNAL_PID_SUBTAG:		UINT32_HASH(external_pid_number(term), HCONST_5);		goto hash2_common;	    case EXTERNAL_PORT_SUBTAG:		UINT32_HASH(external_port_number(term), HCONST_6);		goto hash2_common;	    case FLOAT_SUBTAG:	    {		FloatDef ff;		GET_DOUBLE(term, ff);#if defined(WORDS_BIGENDIAN)		UINT32_HASH_2(ff.fw[0], ff.fw[1], HCONST_12);#else		UINT32_HASH_2(ff.fw[1], ff.fw[0], HCONST_12);#endif		goto hash2_common;	    }	    break;		    	    default:		erl_exit(1, "Invalid tag in make_hash2(0x%X)\n", term);	    }	}	break;	case TAG_PRIMARY_IMMED1:	    switch (term & _TAG_IMMED1_MASK) {	    case _TAG_IMMED1_PID:		UINT32_HASH(internal_pid_number(term), HCONST_5);		goto hash2_common;	    case _TAG_IMMED1_PORT:		UINT32_HASH(internal_port_number(term), HCONST_6);		goto hash2_common;	    case _TAG_IMMED1_IMMED2:		switch (term & _TAG_IMMED2_MASK) {		case _TAG_IMMED2_ATOM:		    if (hash == 0)			hash = atom_tab(atom_val(term))->slot.bucket.hvalue;		    else			UINT32_HASH(atom_tab(atom_val(term))->slot.bucket.hvalue,				    HCONST_3);		    goto hash2_common;		case _TAG_IMMED2_NIL:		    if (hash == 0)			hash = 3468870702UL;		    else			UINT32_HASH(NIL_DEF, HCONST_2);		    goto hash2_common;		default:		    erl_exit(1, "Invalid tag in make_hash2(0x%X)\n", term);		}	    case _TAG_IMMED1_SMALL:	      {		  Sint x = signed_val(term);		  if (SMALL_BITS > 28 && !IS_SSMALL28(x)) {		      term = small_to_big(x, tmp_big);		      break;		  }		  SINT32_HASH(x, HCONST);		  goto hash2_common;	      }	    }	    break;	default:	    erl_exit(1, "Invalid tag in make_hash2(0x%X)\n", term);	hash2_common:	    if (ESTACK_ISEMPTY(s)) {		DESTROY_ESTACK(s);		return hash;	    }	    term = ESTACK_POP(s);	}    }    }#undef UINT32_HASH_2#undef UINT32_HASH#undef SINT32_HASH}#undef HCONST#undef MIX#ifdef ARCH_64Uint32make_broken_hash(Eterm term, Uint32 hash)#elseUintmake_broken_hash(Eterm term, Uint hash)#endif{    switch (tag_val_def(term)) {    case NIL_DEF:	return hash*FUNNY_NUMBER3 + 1;    case ATOM_DEF:	return hash*FUNNY_NUMBER1 + 	    (atom_tab(atom_val(term))->slot.bucket.hvalue);    case SMALL_DEF:#ifdef ARCH_64    {	Sint y1 = signed_val(term);	Uint y2 = y1 < 0 ? -(Uint)y1 : y1;	Uint32 y3 = (Uint32) (y2 >> 32);	int arity = 1;#if defined(WORDS_BIGENDIAN)	if (!IS_SSMALL28(y1))	{   /* like a bignum */	    Uint32 y4 = (Uint32) y2;	    hash = hash*FUNNY_NUMBER2 + ((y4 << 16) | (y4 >> 16));	    if (y3) 	    {		hash = hash*FUNNY_NUMBER2 + ((y3 << 16) | (y3 >> 16));		arity++;	    }	    return hash * (y1 < 0 ? FUNNY_NUMBER3 : FUNNY_NUMBER2) + arity;	}	return hash*FUNNY_NUMBER2 + (((Uint) y1) & 0xfffffff);#else	if  (!IS_SSMALL28(y1))	{   /* like a bignum */	    hash = hash*FUNNY_NUMBER2 + ((Uint32) y2);	    if (y3)	    {		hash = hash*FUNNY_NUMBER2 + y3;		arity++;	    }	    return hash * (y1 < 0 ? FUNNY_NUMBER3 : FUNNY_NUMBER2) + arity;	}        return hash*FUNNY_NUMBER2 + (((Uint) y1) & 0xfffffff);#endif    }#else	return hash*FUNNY_NUMBER2 + unsigned_val(term);#endif    case BINARY_DEF:	{	    size_t sz = binary_size(term);	    size_t i = (sz < 15) ? sz : 15;	    hash = hash_binary_bytes(term, i, hash);	    return hash*FUNNY_NUMBER4 + sz;	}    case EXPORT_DEF:	{	    Export* ep = (Export *) (export_val(term))[1];	    hash = hash * FUNNY_NUMBER11 + ep->code[2];	    hash = hash*FUNNY_NUMBER1 + 		(atom_tab(atom_val(ep->code[0]))->slot.bucket.hvalue);	    hash = hash*FUNNY_NUMBER1 + 		(atom_tab(atom_val(ep->code[1]))->slot.bucket.hvalue);	    return hash;	}    case FUN_DEF:	{	    ErlFunThing* funp = (ErlFunThing *) fun_val(term);	    Uint num_free = funp->num_free;	    Uint i;	    hash = hash * FUNNY_NUMBER10 + num_free;	    hash = hash*FUNNY_NUMBER1 + 		(atom_tab(atom_val(funp->fe->module))->slot.bucket.hvalue);	    hash = hash*FUNNY_NUMBER2 + funp->fe->old_index;	    hash = hash*FUNNY_NUMBER2 + funp->fe->old_uniq;	    for (i = 0; i < num_free; i++) {		hash = make_broken_hash(funp->env[i], hash);	    }	    return hash;	}    case PID_DEF:	return hash*FUNNY_NUMBER5 + internal_pid_number(term);    case EXTERNAL_PID_DEF:	return hash*FUNNY_NUMBER5 + external_pid_number(term);    case PORT_DEF:	return hash*FUNNY_NUMBER9 + internal_port_number(term);    case EXTERNAL_PORT_DEF:	return hash*FUNNY_NUMBER9 + external_port_number(term);    case REF_DEF:	return hash*FUNNY_NUMBER9 + internal_ref_numbers(term)[0];    case EXTERNAL_REF_DEF:	return hash*FUNNY_NUMBER9 + external_ref_numbers(term)[0];    case FLOAT_DEF: 	{	    FloatDef ff;	    GET_DOUBLE(term, ff);	    return hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]);	}	break;    case LIST_DEF:	{	    Eterm* list = list_val(term);	    while(1) {		hash = make_broken_hash(*list, hash);		if (is_not_list(CDR(list)))		    return make_broken_hash(CDR(list),hash)*FUNNY_NUMBER8;		list = list_val(CDR(list));	    }	}	break;    case BIG_DEF:	{	    Eterm* ptr  = big_val(term);	    int is_neg = BIG_SIGN(ptr);	    Uint arity = BIG_ARITY(ptr);	    #ifdef ARCH_64	    Uint i = 0;	    Uint n = BIG_SIZE(ptr);	    arity = n;	    for (i = 0; i < n; i++)	    {		digit_t d = BIG_DIGIT(ptr, i);#if defined(WORDS_BIGENDIAN)		hash = hash*FUNNY_NUMBER2 + ((d << 16) | (d >> 16));#else		hash = hash*FUNNY_NUMBER2 + d;#endif	    }#else	    int i = arity;	    ptr++;	    while (i--) {		hash = hash*FUNNY_NUMBER2 + *ptr++;	    }#endif	    if (is_neg)		return hash*FUNNY_NUMBER3 + arity;	    else		return hash*FUNNY_NUMBER2 + arity;	}	break;    case TUPLE_DEF: 	{	    Eterm* ptr = tuple_val(term);	    Uint arity = arityval(*ptr);	    int i = arity;	    ptr++;	    while(i--)		hash = make_broken_hash(*ptr++, hash);	    return hash*FUNNY_NUMBER9 + arity;	}	break;    default:	erl_exit(1, "Invalid tag in make_broken_hash\n");	return 0;    }}static int do_send_to_logger(Eterm tag, Eterm gleader, char *buf, int len){    /* error_logger !        {notify,{info_msg,gleader,{emulator,"~s~n",[<message as list>]}}} |       {notify,{error,gleader,{emulator,"~s~n",[<message as list>]}}} |       {notify,{warning_msg,gleader,{emulator,"~s~n",[<message as list>}]}} */    Eterm* hp;    Uint sz;    Uint gl_sz;    Eterm gl;    Eterm list,plist,format,tuple1,tuple2,tuple3;    ErlOffHeap *ohp;#ifdef ERTS_SMP    ErlHeapFragment *bp;#else    Process *p;#endif    ASSERT(is_atom(tag));    if (len <= 0) {	return -1;    }#ifndef ERTS_SMP    if (#ifdef USE_THREADS	!erts_get_scheduler_data() || /* Must be scheduler thread */#endif	(p = erts_whereis_process(NULL, 0, am_error_logger, 0, 0)) == NULL	|| p->status == P_RUNNING) {	/* buf *always* points to a null terminated string */	erts_fprintf(stderr, "(no error logger present) %T: \"%s\"\n",		     tag, buf);	return 0;    }    /* So we have an error logger, lets build the message */#endif    gl_sz = IS_CONST(gleader) ? 0 : size_object(gleader);    sz = len * 2 /* message list */+ 2 /* cons surrounding message list */	+ gl_sz + 	3 /*outher 2-tuple*/ + 4 /* middle 3-tuple */ + 4 /*inner 3-tuple */ +	8 /* "~s~n" */;#ifdef ERTS_SMP    bp = new_message_buffer(sz);    ohp = &bp->off_heap;    hp = bp->mem;#else    ohp = &MSO(p);    hp = HAlloc(p, sz);#endif    gl = (is_nil(gleader)	  ? am_noproc	  : (IS_CONST(gleader)	     ? gleader	     : copy_struct(gleader,gl_sz,&hp,ohp)));    list = buf_to_intlist(&hp, buf, len, NIL);    plist = CONS(hp,list,NIL);    hp += 2;    format = buf_to_intlist(&hp, "~s~n", 4, NIL);    tuple1 = TUPLE3(hp, am_emulator, format, plist);    hp += 4;    tuple2 = TUPLE3(hp, tag, gl, tuple1);    hp += 4;    tuple3 = TUPLE2(hp, am_notify, tuple2);#ifdef HARDDEBUG    erts_fprintf(stderr, "%T\n", tuple3);#endif#ifdef ERTS_SMP    {	Eterm from = erts_get_current_pid();	if (is_not_internal_pid(from))	    from = NIL;	erts_queue_error_logger_message(from, tuple3, bp);    }#else    erts_queue_message(p, 0/* only used for smp build */, NULL, tuple3, NIL);#endif    return 0;}static ERTS_INLINE intsend_info_to_logger(Eterm gleader, char *buf, int len) {    return do_send_to_logger(am_info_msg, gleader, buf, len);}static ERTS_INLINE intsend_warning_to_logger(Eterm gleader, char *buf, int len) {    Eterm tag;    switch (erts_error_logger_warnings) {    case am_info:	tag = am_info_msg;	break;    case am_warning:	tag = am_warning_msg;	break;    default:		tag = am_error;		break;    }    return do_send_to_logger(tag, gleader, buf, len);}static ERTS_INLINE intsend_error_to_logger(Eterm gleader, char *buf, int len) {    return do_send_to_logger(am_error, gleader, buf, len);}#define LOGGER_DSBUF_INC_SZ 256static erts_dsprintf_buf_t *grow_logger_dsbuf(erts_dsprintf_buf_t *dsbufp, size_t need){    size_t size;    size_t free_size = dsbufp->size - dsbufp->str_len;    ASSERT(dsbufp && dsbufp->str);    if (need <= free_size)	return dsbufp;    size = need - free_size + LOGGER_DSBUF_INC_SZ;    size = (((size + LOGGER_DSBUF_INC_SZ - 1) / LOGGER_DSBUF_INC_SZ)	    * LOGGER_DSBUF_INC_SZ);    size += dsbufp->size;    ASSERT(dsbufp->str_len + need <= size);    dsbufp->str = (char *) erts_realloc(ERTS_ALC_T_LOGGER_DSBUF,					(void *) dsbufp->str,					size);    dsbufp->size = size;    return dsbufp;}erts_dsprintf_buf_t *erts_create_logger_dsbuf(void){    erts_dsprintf_buf_t init = ERTS_DSPRINTF_BUF_INITER(grow_logger_dsbuf);    erts_dsprintf_buf_t *dsbufp = erts_alloc(ERTS_ALC_T_LOGGER_DSBUF,					     sizeof(erts_dsprintf_buf_t));    sys_memcpy((void *) dsbufp, (void *) &init, sizeof(erts_dsprintf_buf_t));    dsbufp->str = (char *) erts_alloc(ERTS_ALC_T_LOGGER_DSBUF,				      LOGGER_DSBUF_INC_SZ);    dsbufp->str[0] = '\0';    dsbufp->size = LOGGER_DSBUF_INC_SZ;    return dsbufp;}static ERTS_INLINE voiddestroy_logger_dsbuf(erts_dsprintf_buf_t *dsbufp){    ASSERT(dsbufp && dsbufp->str);    erts_free(ERTS_ALC_T_LOGGER_DSBUF, (void *) dsbufp->str);    erts_free(ERTS_ALC_T_LOGGER_DSBUF, (void *) dsbufp);}interts_send_info_to_logger(Eterm gleader, erts_dsprintf_buf_t *dsbufp){    int res;    res = send_info_to_logger(gleader, dsbufp->str, dsbufp->str_len);    destroy_logger_dsbuf(dsbufp);    return res;}interts_send_warning_to_logger(Eterm gleader, erts_dsprintf_buf_t *dsbufp){    int res;    res = send_warning_to_logger(gleader, dsbufp->str, dsbufp->str_len);    destroy_logger_dsbuf(dsbufp);    return res;}interts_send_error_to_logger(Eterm gleader, erts_dsprintf_buf_t *dsbufp){    int res;    res = send_error_to_logger(gleader, dsbufp->str, dsbufp->str_len);    destroy_logger_dsbuf(dsbufp);    return res;}interts_send_info_to_logger_str(Eterm gleader, char *str){    return send_info_to_logger(gleader, str, sys_strlen(str));}interts_send_warning_to_logger_str(Eterm gleader, char *str){    return send_warning_to_logger(gleader, str, sys_strlen(str));}interts_send_error_to_logger_str(Eterm gleader, char *str){    return send_error_to_logger(gleader, str, sys_strlen(str));}interts_send_info_to_logger_nogl(erts_dsprintf_buf_t *dsbuf){    return erts_send_info_to_logger(NIL, dsbuf);}interts_send_warning_to_logger_nogl(erts_dsprintf_buf_t *dsbuf){    return erts_send_warning_to_logger(NIL, dsbuf);}interts_send_error_to_logger_nogl(erts_dsprintf_buf_t *dsbuf){    return erts_send_error_to_logger(NIL, dsbuf);}interts_send_info_to_logger_str_nogl(char *str){    return erts_send_info_to_logger_str(NIL, str);}interts_send_warning_to_logger_str_nogl(char *str){    return erts_send_warning_to_logger_str(NIL, str);}interts_send_error_to_logger_str_nogl(char *str){    return erts_send_error_to_logger_str(NIL, str);}#define TMP_DSBUF_INC_SZ 256static erts_dsprintf_buf_t *grow_tmp_dsbuf(erts_dsprintf_buf_t *dsbufp, size_t need){    size_t size;    size_t free_size = dsbufp->size - dsbufp->str_len;    ASSERT(dsbufp);    if (need <= free_size)	return dsbufp;    size = need - free_size + TMP_DSBUF_INC_SZ;    size = ((size + TMP_DSBUF_INC_SZ - 1)/TMP_DSBUF_INC_SZ)*TMP_DSBUF_INC_SZ;    size += dsbufp->size;    ASSERT(dsbufp->str_len + need <= size);    dsbufp->str = (char *) erts_realloc(ERTS_ALC_T_TMP_DSBUF,					(void *) dsbufp->str,					size);    dsbufp->size = size;    return dsbufp;}erts_dsprintf_buf_t *erts_create_tmp_dsbuf(Uint size){    Uint init_size = size ? size : TMP_DSBUF_INC_SZ;    erts_dsprintf_buf_t init = ERTS_DSPRINTF_BUF_INITER(grow_tmp_dsbuf);    erts_dsprintf_buf_t *dsbufp = erts_alloc(ERTS_ALC_T_TMP_DSBUF,					     sizeof(erts_dsprintf_buf_t));    sys_memcpy((void *) dsbufp, (void *) &init, sizeof(erts_dsprintf_buf_t));

⌨️ 快捷键说明

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