Selaa lähdekoodia

ft: 修改

master
SisMaker 3 vuotta sitten
vanhempi
commit
d44e5f7ed7
1 muutettua tiedostoa jossa 175 lisäystä ja 154 poistoa
  1. +175
    -154
      c_src/eLfq/eLfq.cc

+ 175
- 154
c_src/eLfq/eLfq.cc Näytä tiedosto

@ -1,56 +1,22 @@
#include "erl_nif.h"
#include <string.h>
#include "erl_nif.h"
#include "concurrentqueue.h"
struct atoms {
ERL_NIF_TERM atomOk;
ERL_NIF_TERM atomError;
ERL_NIF_TERM atomTrue;
//ERL_NIF_TERM atomFalse;
//ERL_NIF_TERM atomUndefined;
ERL_NIF_TERM atomEmpty;
};
struct shared_data {
ErlNifResourceType *resQueueInstance;
};
struct q_item {
struct qData {
ErlNifEnv *env;
ERL_NIF_TERM term;
};
struct squeue {
moodycamel::ConcurrentQueue<q_item> *queue;
struct lfqIns {
moodycamel::ConcurrentQueue<qData> *LFQ;
moodycamel::ConcurrentQueue<ErlNifEnv *> *G_ENV;
};
const char kAtomOk[] = "ok";
const char kAtomError[] = "error";
const char kAtomTrue[] = "true";
//const char kAtomFalse[] = "false";
//const char kAtomUndefined[] = "undefined";
const char kAtomEmpty[] = "empty";
atoms ATOMS;
void nif_enlfq_free(ErlNifEnv *env, void *obj);
ERL_NIF_TERM nif_enlfq_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM nif_enlfq_push(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM nif_enlfq_pop(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM make_atom(ErlNifEnv *env, const char *name) {
ERL_NIF_TERM ret;
if (enif_make_existing_atom(env, name, &ret, ERL_NIF_LATIN1))
return ret;
return enif_make_atom(env, name);
}
ERL_NIF_TERM atomOk;
ERL_NIF_TERM atomError;
ERL_NIF_TERM atomTrue;
ERL_NIF_TERM atomFalse;
ERL_NIF_TERM atomEmpty;
ERL_NIF_TERM make_binary(ErlNifEnv *env, const char *buff, size_t length) {
ERL_NIF_TERM term;
@ -60,183 +26,238 @@ ERL_NIF_TERM make_binary(ErlNifEnv *env, const char *buff, size_t length) {
}
ERL_NIF_TERM make_error(ErlNifEnv *env, const char *error) {
return enif_make_tuple2(env, ATOMS.atomError, make_binary(env, error, strlen(error)));
return enif_make_tuple2(env, atomError, make_binary(env, error, strlen(error)));
}
void eLfqFree(ErlNifEnv *, void *obj) {
lfqIns *ObjIns = static_cast<lfqIns *>(obj);
void open_resources(ErlNifEnv *env, shared_data *data) {
ErlNifResourceFlags flags = static_cast<ErlNifResourceFlags>(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);
data->resQueueInstance = enif_open_resource_type(env, NULL, "enlfq_instance", nif_enlfq_free, flags, NULL);
}
int on_nif_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM) {
if (ObjIns != nullptr) {
qData Data;
while (ObjIns->LFQ->try_dequeue(Data)) {
enif_free_env(Data.env);
}
ATOMS.atomOk = make_atom(env, kAtomOk);
ATOMS.atomError = make_atom(env, kAtomError);
ATOMS.atomTrue = make_atom(env, kAtomTrue);
// ATOMS.atomFalse = make_atom(env, kAtomFalse);
// ATOMS.atomUndefined = make_atom(env, kAtomUndefined);
ATOMS.atomEmpty = make_atom(env, kAtomEmpty);
ErlNifEnv *StoreEnv;
while (ObjIns->G_ENV->try_dequeue(StoreEnv)) {
enif_free_env(StoreEnv);
}
delete ObjIns->LFQ;
delete ObjIns->G_ENV;
}
}
shared_data *data = static_cast<shared_data *>(enif_alloc(sizeof(shared_data)));
open_resources(env, data);
int nifLoad(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM) {
ErlNifResourceFlags flags = static_cast<ErlNifResourceFlags>(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);
ErlNifResourceType *ResIns;
ResIns = enif_open_resource_type(env, NULL, "eLfqRes", eLfqFree, flags, NULL);
if (NULL == ResIns)
return -1;
*priv_data = ResIns;
atomOk = enif_make_atom(env, "ok");
atomError = enif_make_atom(env, "error");
atomTrue = enif_make_atom(env, "true");
atomFalse = enif_make_atom(env, "false");
atomEmpty = enif_make_atom(env, "empty");
*priv_data = data;
return 0;
}
void on_nif_unload(ErlNifEnv *, void *priv_data) {
shared_data *data = static_cast<shared_data *>(priv_data);
enif_free(data);
}
int on_nif_upgrade(ErlNifEnv *env, void **priv, void **, ERL_NIF_TERM) {
shared_data *data = static_cast<shared_data *>(enif_alloc(sizeof(shared_data)));
open_resources(env, data);
int nifUpgrade(ErlNifEnv *env, void **priv_data, void **, ERL_NIF_TERM) {
ErlNifResourceFlags flags = static_cast<ErlNifResourceFlags>(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);
ErlNifResourceType *ResIns;
ResIns = enif_open_resource_type(env, NULL, "eLfqRes", eLfqFree, flags, NULL);
if (NULL == ResIns)
return -1;
*priv = data;
*priv_data = ResIns;
return 0;
}
void nif_enlfq_free(ErlNifEnv *, void *obj) {
squeue *inst = static_cast<squeue *>(obj);
if (inst != nullptr) {
q_item item;
while (inst->queue->try_dequeue(item)) {
enif_free_env(item.env);
}
delete inst->queue;
}
void nifUnload(ErlNifEnv *, void *priv_data) {
}
ERL_NIF_TERM nif_new(ErlNifEnv *env, int, const ERL_NIF_TERM *) {
shared_data *data = static_cast<shared_data *>(enif_priv_data(env));
ERL_NIF_TERM nifNew(ErlNifEnv *env, int, const ERL_NIF_TERM *) {
ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
lfqIns *ObjIns = static_cast<lfqIns *>(enif_alloc_resource(ResIns, sizeof(lfqIns)));
ObjIns->LFQ = new moodycamel::ConcurrentQueue<qData>;
ObjIns->G_ENV = new moodycamel::ConcurrentQueue<ErlNifEnv *>;
squeue *qinst = static_cast<squeue *>(enif_alloc_resource(data->resQueueInstance, sizeof(squeue)));
qinst->queue = new moodycamel::ConcurrentQueue<q_item>;
if (qinst == NULL)
if (ObjIns == NULL)
return make_error(env, "enif_alloc_resource failed");
ERL_NIF_TERM term = enif_make_resource(env, qinst);
enif_release_resource(qinst);
return enif_make_tuple2(env, ATOMS.atomOk, term);
ERL_NIF_TERM term = enif_make_resource(env, ObjIns);
enif_release_resource(ResIns);
return enif_make_tuple2(env, atomOk, term);
}
ERL_NIF_TERM nif_in2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
shared_data *data = static_cast<shared_data *>(enif_priv_data(env));
ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
squeue *inst;
lfqIns *ObjIns = NULL;
if (!enif_get_resource(env, argv[0], data->resQueueInstance, (void **) &inst)) {
if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
return enif_make_badarg(env);
}
q_item item;
item.env = enif_alloc_env();
item.term = enif_make_copy(item.env, argv[1]);
qData InTerm;
inst->queue->enqueue(item);
InTerm.env = enif_alloc_env();
InTerm.term = enif_make_copy(InTerm.env, argv[1]);
return ATOMS.atomTrue;
if (ObjIns->LFQ->enqueue(InTerm)){
return atomTrue;
} else {
return atomFalse;
}
}
ERL_NIF_TERM nif_in3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
// ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
// ErlNifResourceType* ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
//
// lfqIns *ObjIns = NULL;
//
// if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
// return enif_make_badarg(env);
// }
//
// qData InTerm;
// if (ObjIns->G_ENV->try_dequeue(InTerm.env) != true) {
// InTerm.env = enif_alloc_env();
// }
//
// InTerm.term = enif_make_copy(InTerm.env, argv[1]);
//
// if (ObjIns->LFQ->enqueue(InTerm)){
// return atomTrue;
// } else {
// return atomFalse;
// }
// }
ERL_NIF_TERM nifIn3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_ins2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
ERL_NIF_TERM nifIns2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_ins3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
ERL_NIF_TERM nifIns3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_tryIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
ERL_NIF_TERM nifTryIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_tryIn3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
ERL_NIF_TERM nifTryIn3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_tryIns2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
ERL_NIF_TERM nifTryIns2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_tryIns3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomTrue;
ERL_NIF_TERM nifTryIns3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomTrue;
}
ERL_NIF_TERM nif_tryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
shared_data *data = static_cast<shared_data *>(enif_priv_data(env));
squeue *inst = NULL;
ERL_NIF_TERM nifTryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
lfqIns *ObjIns = NULL;
if (!enif_get_resource(env, argv[0], data->resQueueInstance, (void **) &inst)) {
if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
return enif_make_badarg(env);
}
ERL_NIF_TERM term;
q_item item;
ERL_NIF_TERM OutTerm;
qData Data;
if (inst->queue->try_dequeue(item)) {
term = enif_make_copy(env, item.term);
enif_free_env(item.env);
return enif_make_tuple2(env, ATOMS.atomOk, term);
if (ObjIns->LFQ->try_dequeue(Data)) {
OutTerm = enif_make_copy(env, Data.term);
enif_free_env(Data.env);
return enif_make_tuple2(env, atomOk, OutTerm);
} else {
return ATOMS.atomEmpty;
return atomEmpty;
}
}
ERL_NIF_TERM nif_tryOut2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomEmpty;
// ERL_NIF_TERM nifTryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
// ErlNifResourceType* ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
// lfqIns *ObjIns = NULL;
//
// if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
// return enif_make_badarg(env);
// }
//
// ERL_NIF_TERM OutTerm;
// qData Data;
//
// if (ObjIns->LFQ->try_dequeue(Data)) {
// OutTerm = enif_make_copy(env, Data.term);
//
// if(ObjIns->G_ENV->size_approx() > 1000){
// enif_free_env(Data.env);
// }else{
// enif_clear_env(Data.env);
// if (!ObjIns->G_ENV->enqueue(Data.env)){
// enif_free_env(Data.env);
// }
// }
// return enif_make_tuple2(env, atomOk, OutTerm);
// } else {
// return atomEmpty;
// }
// }
ERL_NIF_TERM nifTryOut2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomEmpty;
}
ERL_NIF_TERM nif_tryOuts2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomEmpty;
ERL_NIF_TERM nifTryOuts2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomEmpty;
}
ERL_NIF_TERM nif_tryOuts3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomEmpty;
ERL_NIF_TERM nifTryOuts3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomEmpty;
}
ERL_NIF_TERM nif_tryOutByProd2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomEmpty;
ERL_NIF_TERM nifTryOutByProd2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomEmpty;
}
ERL_NIF_TERM nif_tryOutsByProd3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomEmpty;
ERL_NIF_TERM nifTryOutByProd3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomEmpty;
}
ERL_NIF_TERM nif_size1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return ATOMS.atomEmpty;
ERL_NIF_TERM nifSize1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
return atomEmpty;
}
static ErlNifFunc nif_funcs[] =
static ErlNifFunc nifFuncs[] =
{
{"new", 0, nif_new},
{"in", 2, nif_in2},
{"in", 3, nif_in3},
{"ins", 2, nif_ins2},
{"ins", 3, nif_ins3},
{"tryIn", 2, nif_tryIn2},
{"tryIn", 3, nif_tryIn3},
{"tryIns", 2, nif_tryIns2},
{"tryIns", 3, nif_tryIns3},
{"tryOut", 1, nif_tryOut1},
{"tryOut", 2, nif_tryOut2},
{"tryOuts", 2, nif_tryOuts2},
{"tryOuts", 3, nif_tryOuts3},
{"tryOutByProd", 2, nif_tryOutByProd2},
{"tryOutsByProd", 3, nif_tryOutsByProd3},
{"size", 1, nif_size1}
{"new", 0, nifNew},
{"in", 2, nifIn2},
{"in", 3, nifIn3},
{"ins", 2, nifIns2},
{"ins", 3, nifIns3},
{"tryIn", 2, nifTryIn2},
{"tryIn", 3, nifTryIn3},
{"tryIns", 2, nifTryIns2},
{"tryIns", 3, nifTryIns3},
{"tryOut", 1, nifTryOut1},
{"tryOut", 2, nifTryOut2},
{"tryOuts", 2, nifTryOuts2},
{"tryOuts", 3, nifTryOuts3},
{"tryOutByProd", 2, nifTryOutByProd2},
{"tryOutsByProd", 3, nifTryOutByProd3},
{"size", 1, nifSize1}
};
ERL_NIF_INIT(eLfq, nif_funcs, on_nif_load, NULL, on_nif_upgrade, on_nif_unload
ERL_NIF_INIT(eLfq, nifFuncs, nifLoad, NULL, nifUpgrade, nifUnload
)

Ladataan…
Peruuta
Tallenna