Skip to content

Commit

Permalink
rewrote markdown.c to use dirty schedulers when available
Browse files Browse the repository at this point in the history
  • Loading branch information
zambal committed Feb 10, 2014
1 parent dd72e4d commit 792a414
Showing 1 changed file with 49 additions and 43 deletions.
92 changes: 49 additions & 43 deletions src/markdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "html.h"

#define OUTPUT_UNIT 128
#define MAX_INPUT_SIZE_SHORT_JOB 20000

typedef struct {
ERL_NIF_TERM atom_true;
Expand All @@ -17,16 +18,31 @@ typedef struct {
ERL_NIF_TERM atom_fenced_code;
} markdown_priv;

static int
is_short_job(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary input;
if (enif_inspect_binary(env, argv[0], &input) == 0) {
return -1;
}

return input.size < MAX_INPUT_SIZE_SHORT_JOB;
}

static ERL_NIF_TERM
to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
do_job(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary input;
ErlNifBinary output;

markdown_priv* priv;

ERL_NIF_TERM options;
ERL_NIF_TERM atom_true;
ERL_NIF_TERM atom_tables;
ERL_NIF_TERM atom_autolink;
ERL_NIF_TERM atom_fenced_code;

ERL_NIF_TERM term;
const ERL_NIF_TERM* tuple;
int tuple_size;

unsigned int extensions;

hoedown_buffer* ob;
Expand All @@ -41,29 +57,32 @@ to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
return argv[0];
}

priv = enif_priv_data(env);
options = argv[1];
extensions = 0;
atom_true = enif_make_atom(env, "true");
atom_tables = enif_make_atom(env, "tables");
atom_autolink = enif_make_atom(env, "autolink");
atom_fenced_code = enif_make_atom(env, "fenced_code");

while (enif_get_list_cell(env, options, &term, &options) != 0) {
if (enif_get_tuple(env, term, &tuple_size, &tuple) != 0) {
if (tuple_size > 1) {
if (enif_compare(tuple[0], priv->atom_tables) == 0) {
if (enif_compare(tuple[1], priv->atom_true) == 0) {
if (enif_compare(tuple[0], atom_tables) == 0) {
if (enif_compare(tuple[1], atom_true) == 0) {
extensions |= HOEDOWN_EXT_TABLES;
continue;
}
}

if (enif_compare(tuple[0], priv->atom_autolink) == 0) {
if (enif_compare(tuple[1], priv->atom_true) == 0) {
if (enif_compare(tuple[0], atom_autolink) == 0) {
if (enif_compare(tuple[1], atom_true) == 0) {
extensions |= HOEDOWN_EXT_AUTOLINK;
continue;
}
}

if (enif_compare(tuple[0], priv->atom_fenced_code) == 0) {
if (enif_compare(tuple[1], priv->atom_true) == 0) {
if (enif_compare(tuple[0], atom_fenced_code) == 0) {
if (enif_compare(tuple[1], atom_true) == 0) {
extensions |= HOEDOWN_EXT_FENCED_CODE;
continue;
}
Expand All @@ -77,7 +96,6 @@ to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
markdown = hoedown_markdown_new(extensions, 16, renderer);
hoedown_markdown_render(ob, (uint8_t*) input.data, input.size, markdown);

enif_release_binary(&input);
hoedown_html_renderer_free(renderer);
hoedown_markdown_free(markdown);

Expand All @@ -88,40 +106,28 @@ to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
return enif_make_binary(env, &output);
}

static ErlNifFunc funcs[] = {
{ "to_html", 2, to_html }
};

static int
load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) {
markdown_priv* data = enif_alloc(sizeof(markdown_priv));
if (data == NULL) {
return 1;
}

data->atom_true = enif_make_atom(env, "true");
data->atom_false = enif_make_atom(env, "false");
data->atom_tables = enif_make_atom(env, "tables");
data->atom_autolink = enif_make_atom(env, "autolink");
data->atom_fenced_code = enif_make_atom(env, "fenced_code");

*priv = (void*) data;
return 0;
}

static int
reload(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) {
return 0;
static ERL_NIF_TERM
do_dirty_job(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ERL_NIF_TERM result = do_job(env, argc, argv);
return enif_schedule_dirty_nif_finalizer(env, result, enif_dirty_nif_finalizer);
}

static int
upgrade(ErlNifEnv* env, void** priv, void** old_priv, ERL_NIF_TERM info) {
return load(env, priv, info);
static ERL_NIF_TERM
to_html(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
if(is_short_job(env, argc, argv)) {
return do_job(env, argc, argv);
}
else {
return enif_schedule_dirty_nif(env, ERL_NIF_DIRTY_JOB_CPU_BOUND, do_dirty_job, argc, argv);
}
#else
return do_job(env, argc, argv);
#endif
}

static void
unload(ErlNifEnv* env, void* priv) {
enif_free(priv);
}
static ErlNifFunc funcs[] = {
{ "to_html", 2, to_html }
};

ERL_NIF_INIT(Elixir.Markdown, funcs, &load, &reload, &upgrade, &unload)
ERL_NIF_INIT(Elixir.Markdown, funcs, NULL, NULL, NULL, NULL)

0 comments on commit 792a414

Please sign in to comment.