I’ve encapsulated a more efficient global lock based on atomics. To make it work efficiently, I’ve encapsulated an nif to convert Pid to integer, as well as support to convert integer to pid. the code like this:
#include "erl_nif.h"
static ERL_NIF_TERM pidToInt(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifUInt64 TermInt = (ErlNifUInt64)argv[0];
return enif_make_uint64(env, TermInt);
}
static ERL_NIF_TERM intToPid(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifUInt64 Pid;
enif_fprintf(stdout, "IMY************put0001 %T \n", argv[0]);
if (!enif_get_uint64(env, argv[0], &Pid)){
enif_fprintf(stdout, "IMY************put0002 %T \n", argv[0]);
return enif_make_badarg(env);
}
enif_fprintf(stdout, "IMY************put0003 %d \n", Pid);
ERL_NIF_TERM TermPid = (ERL_NIF_TERM)Pid;
enif_fprintf(stdout, "IMY************put0004 %T \n", TermPid);
return (ERL_NIF_TERM)Pid;
}
static ErlNifFunc nif_funcs[] = {
{"pidToInt", 1, pidToInt},
{"intToPid", 1, intToPid}
};
ERL_NIF_INIT(eGPidInt, nif_funcs, NULL, NULL, NULL, NULL);
But there is a strange problem, passing in an illegal integer will cause the system to dump, exmaple:
Eshell V14.3 (press Ctrl+G to abort, type help(). for help)
1> Pid = self().
<0.154.0>
2> PidInt = eGPidInt:pidToInt(Pid).
19715
3> eGPidInt:intToPid(PidInt).
IMY************put0001 19715
IMY************put0003 19715
IMY************put0004 <0.154.0>
<0.154.0>
4> eGPidInt:intToPid(PidInt + 1).
IMY************put0001 19716
IMY************put0003 19716
IMY************put0004 <cp/header:0x0000000000004d04>
Segmentation fault (core dumped)
I think in this case how to avoid the dump?
if you want run this code, you can get it on here: GitHub - ErlGameWorld/eGLock: erlang's global lock
if you compile the nif error you may need rebuild eNpc(GitHub - ErlGameWorld/eNpc: Erlang Nif or port_driver generic compilation scripts for Windows Linux Mac), and replace in c_src/eNpc