From 2a8c77b210307db2110c4f3c3cdc59ddaed6bd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 25 Nov 2024 12:43:30 +0100 Subject: [PATCH] Add `process_info(Pid, label)` for retrieving the process label The only documented way to retrieve the label for a process was by calling `proc_lib:get_label/1`. This commit teaches `process_info/2` the option `label` for retrieving the process label. This is especially useful when one needs to retrieve other process info items at the same time. For example: process_info(Pid, [label,registered_name]) --- erts/emulator/beam/atom.names | 2 ++ erts/emulator/beam/erl_bif_info.c | 20 ++++++++++++++++++++ erts/emulator/test/process_SUITE.erl | 23 ++++++++++++++++++++++- erts/preloaded/ebin/erlang.beam | Bin 39168 -> 39168 bytes erts/preloaded/src/erlang.erl | 7 +++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index 758c84d1c1d7..0b328a6d9a5c 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -578,6 +578,8 @@ atom processes atom processes_used atom process_count atom process_display +atom DollarProcessLabel='$process_label' +atom process_limit atom process_limit atom process_dump atom procs diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index c2bd395ad3a7..b421071579f9 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -782,6 +782,7 @@ collect_one_suspend_monitor(ErtsMonitor *mon, void *vsmicp, Sint reds) #define ERTS_PI_IX_PARENT 36 #define ERTS_PI_IX_ASYNC_DIST 37 #define ERTS_PI_IX_DICTIONARY_LOOKUP 38 +#define ERTS_PI_IX_LABEL 39 #define ERTS_PI_UNRESERVE(RS, SZ) \ (ASSERT((RS) >= (SZ)), (RS) -= (SZ)) @@ -834,6 +835,7 @@ static ErtsProcessInfoArgs pi_args[] = { {am_parent, 0, 0, ERTS_PROC_LOCK_MAIN}, {am_async_dist, 0, 0, ERTS_PROC_LOCK_MAIN}, {am_dictionary, 3, ERTS_PI_FLAG_FORCE_SIG_SEND|ERTS_PI_FLAG_KEY_TUPLE2, ERTS_PROC_LOCK_MAIN}, + {am_label, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN}, }; #define ERTS_PI_ARGS ((int) (sizeof(pi_args)/sizeof(pi_args[0]))) @@ -966,6 +968,8 @@ pi_arg2ix(Eterm arg, Eterm *extrap) return ERTS_PI_IX_PARENT; case am_async_dist: return ERTS_PI_IX_ASYNC_DIST; + case am_label: + return ERTS_PI_IX_LABEL; default: if (is_tuple_arity(arg, 2)) { Eterm *tpl = tuple_val(arg); @@ -2279,6 +2283,22 @@ process_info_aux(Process *c_p, break; } + case ERTS_PI_IX_LABEL: { + Uint sz; + + res = erts_pd_hash_get(rp, am_DollarProcessLabel); + sz = (!(flags & ERTS_PI_FLAG_REQUEST_FOR_OTHER) || is_immed(res) + ? 0 + : size_object(res)); + + hp = erts_produce_heap(hfact, sz, reserve_size); + + if (sz) + res = copy_struct(res, sz, &hp, hfact->off_heap); + + break; + } + default: return THE_NON_VALUE; /* will produce badarg */ diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index c8b86e4e740b..9680eb5836fd 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -55,6 +55,7 @@ process_info_self_msgq_len_more/1, process_info_msgq_len_no_very_long_delay/1, process_info_dict_lookup/1, + process_info_label/1, bump_reductions/1, low_prio/1, binary_owner/1, yield/1, yield2/1, otp_4725/1, dist_unlink_ack_exit_leak/1, bad_register/1, garbage_collect/1, otp_6237/1, @@ -182,7 +183,8 @@ groups() -> process_info_self_msgq_len_messages, process_info_self_msgq_len_more, process_info_msgq_len_no_very_long_delay, - process_info_dict_lookup]}, + process_info_dict_lookup, + process_info_label]}, {otp_7738, [], [otp_7738_waiting, otp_7738_suspended, otp_7738_resume]}, @@ -1728,6 +1730,25 @@ process_info_dict_lookup(Config) when is_list(Config) -> false = is_process_alive(Pid), ok. +process_info_label(Config) when is_list(Config) -> + Pid = spawn_link(fun proc_dict_helper/0), + LabelKey = '$process_label', + Ref = make_ref(), + Tuple = {make_ref(), erlang:monotonic_time()}, + + undefined = pdh(Pid, put, [LabelKey, Tuple]), + erlang:garbage_collect(Pid), + + {label,Tuple} = process_info(Pid, label), + Self = self(), + [{label,Tuple},{registered_name,[]},{links,[Self]}] = + process_info(Pid, [label,registered_name,links]), + + put(LabelKey, Ref), + {label,Ref} = process_info(self(), label), + + ok. + pdh(Pid, AsyncOp, Args) when AsyncOp == put_async; AsyncOp == erase_async -> Pid ! {AsyncOp, Args}, diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam index 6e90e635bea468a582dc0c9e752a4b961b14b822..8a212178bb0516fb45b5b4de2e5929acdf27f804 100644 GIT binary patch delta 1158 zcmWN}YfRO39KhkhELh8&m2RITj~&nda{ia!@B76ZP@>J1Guu)$%gjqR+f-m>OQ)&F zg(<0#h*-*kE+T|wT((T5LRJlCI%~~J22{(|DsPjtd{O!S*|VWNdqaEn_Q_d8)l;IZ zE7hgzv#z%Nkv%NuPxKsmp=M~<`OGpB%Slv_*hr$0#6A-3Bsxg+kmx0;B=boYk}M)M zi&P1zQc`84E|a=~GaTn8oDe6%nT1n=^EA#9oSiteIJtH*j}naO-fJao@weMnAwkgnJmb6ZaVI0PY~}Mchkx*Wu;jDc%IUBD|S+C3y4j z7UGrTt-xD_w+(MQUM=4Hcx`xx@xH__z%Rrv!Jmu25Wf`vDf~_NmG}q9_^tQ{@z3I) z$G=QENjgP3Al*-Tkn|aX+X%)G2*Ct`VuHy8iwG7IG!Zlt93ki=96>mWa5UjVgbx$0 zBwR&UO;|&Cny`;(6wzp+2Z?49ts#1mXfIJCQKp@!gXj#=uf#VK-$Fc{_0+Q$;V8@6krN5MVR|Ak7DLy$}!Jk z)?(ISDlxBM-o(^rFs+z2Oc$mba}?8qIfglj`3mzrrVrDP`4M{~b~t7T^B3kH%vEd_ zHXCyRa}hfdn}f~8=3#Hgj>RUiK7Gm$hP9kHAu~V>9vE|r3 z$QUFK8H-FqrXw?u5@ZhY7_tC)99fDiN1jJkBWsZg(m`1nEXTMY@n4; z6`h7YfX+tepmWjr=o9FZ=o0i9bSb(FEkn!E=g<}C3+PI8HM#~}hptCoLMzZs=w@^a zx)rTLUqg4GHRvw%b#xC}ht{JFEYNq*chP-l6WW6AM-QMMqU~r0`Vo2%J%VCr5+)XHpAft4Ray7|vl3PeNk~~1NjbuB?UXmxs56BP6SMm!< z%_Ef|RYIzi)Cj37IOA}}aZ9e6L{RpY&d*NWGP_c6ZUD}DxlA^sBl68z=(S^P@;!({yy{3H11@qfl2 zAw8A!bkYT+2S^W*K1Xl^!DNCoK}1kQFq2>@!7_p-f`bId2)YO-5KbhVM0g+J{eSVef2u%Bom(IldKiRKb*BzlHuKT#u5wvDKr=p51a#McsEM?8o4F5(A>7ZEQd zUPfF_yoI=)xPkaMaS!nz@euKUm@ybIH(^p32b0Ex7=savVhS;{F%M!EW6Cg3Vm4tm zV=6JvV_w13XE809R!ldh2Xh?Li#dtu!+e7I64Q?vzzHA2M3iA-j+&WH(Zc zG$5}cuOa)9Mx+Tjh-90Q7Niw9igY0FAw9_ZNH@}poI*|`eaPp?8RRQu5cvlA7Woc2 zk6b{0KoiJs$e+kx$Yo?0oq*<|*Q0qT=rnXXdJ9^Brcf76qaj+DMQ=mzK<`9np~dJu z=zMemx)5EAK8ikuu0WqaSE8%XQnUr2hW^P~g|7lAtZvX%Q diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 061f55cd4337..df90b942eadb 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -7724,6 +7724,7 @@ process_flag(_Flag, _Value) -> heap_size | initial_call | links | + label | last_calls | memory | message_queue_len | @@ -7768,6 +7769,7 @@ process_flag(_Flag, _Value) -> {heap_size, Size :: non_neg_integer()} | {initial_call, mfa()} | {links, PidsAndPorts :: [pid() | port()]} | + {label, term()} | {last_calls, false | (Calls :: [mfa()])} | {memory, Size :: non_neg_integer()} | {message_queue_len, MessageQueueLen :: non_neg_integer()} | @@ -7903,6 +7905,11 @@ Valid `InfoTuple`s with corresponding `Item`s: - **`{links, PidsAndPorts}`** - `PidsAndPorts` is a list of process identifiers and port identifiers, with processes or ports to which the process has a link. +- **`{label, Label}`** - + `Label` is the label for the process. See `proc_lib:get_label/1`. + + Since: OTP 27.2 + - **`{last_calls, false|Calls}`** - The value is `false` if call saving is not active for the process (see `process_flag/3`). If call saving is active, a list is returned, in which the last element is the most recent called.