-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new IP assignment, random init, fifo reuse of IP
Initialized the free IP pool with a random order and time stamp to build a queue in the ets table. Released IPs are appended to the end of the free queue (through the timestamp).
- Loading branch information
Showing
5 changed files
with
338 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Based on c_src.mk from erlang.mk by Loic Hoguin <essen@ninenines.eu> | ||
|
||
CURDIR := $(shell pwd) | ||
BASEDIR := $(abspath $(CURDIR)/..) | ||
|
||
PROJECT ?= $(notdir $(BASEDIR)) | ||
PROJECT := $(strip $(PROJECT)) | ||
|
||
ERTS_INCLUDE_DIR ?= $(shell erl -noshell -eval "io:format(\"~ts/erts-~ts/include/\", [code:root_dir(), erlang:system_info(version)])." -s init stop) | ||
ERL_INTERFACE_INCLUDE_DIR ?= $(shell erl -noshell -eval "io:format(\"~ts\", [code:lib_dir(erl_interface, include)])." -s init stop) | ||
ERL_INTERFACE_LIB_DIR ?= $(shell erl -noshell -eval "io:format(\"~ts\", [code:lib_dir(erl_interface, lib)])." -s init stop) | ||
|
||
C_SRC_DIR = $(CURDIR) | ||
C_SRC_OUTPUT ?= $(CURDIR)/../priv/$(PROJECT).so | ||
|
||
# System type and C compiler/flags. | ||
|
||
UNAME_SYS := $(shell uname -s) | ||
ifeq ($(UNAME_SYS), Darwin) | ||
CC ?= cc | ||
CFLAGS ?= -O3 -std=c99 -arch x86_64 -finline-functions -Wall -Wmissing-prototypes | ||
CXXFLAGS ?= -O3 -arch x86_64 -finline-functions -Wall | ||
LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress | ||
else ifeq ($(UNAME_SYS), FreeBSD) | ||
CC ?= cc | ||
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes | ||
CXXFLAGS ?= -O3 -finline-functions -Wall | ||
else ifeq ($(UNAME_SYS), Linux) | ||
CC ?= gcc | ||
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes | ||
CXXFLAGS ?= -O3 -finline-functions -Wall | ||
endif | ||
|
||
CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) | ||
CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) | ||
|
||
LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lei | ||
LDFLAGS += -shared | ||
|
||
# Verbosity. | ||
|
||
c_verbose_0 = @echo " C " $(?F); | ||
c_verbose = $(c_verbose_$(V)) | ||
|
||
cpp_verbose_0 = @echo " CPP " $(?F); | ||
cpp_verbose = $(cpp_verbose_$(V)) | ||
|
||
link_verbose_0 = @echo " LD " $(@F); | ||
link_verbose = $(link_verbose_$(V)) | ||
|
||
SOURCES := $(shell find $(C_SRC_DIR) -type f \( -name "*.c" -o -name "*.C" -o -name "*.cc" -o -name "*.cpp" \)) | ||
OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) | ||
|
||
COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c | ||
COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c | ||
|
||
$(C_SRC_OUTPUT): $(OBJECTS) | ||
@mkdir -p $(BASEDIR)/priv/ | ||
$(link_verbose) $(CC) $(OBJECTS) $(LDFLAGS) $(LDLIBS) -o $(C_SRC_OUTPUT) | ||
|
||
%.o: %.c | ||
$(COMPILE_C) $(OUTPUT_OPTION) $< | ||
|
||
%.o: %.cc | ||
$(COMPILE_CPP) $(OUTPUT_OPTION) $< | ||
|
||
%.o: %.C | ||
$(COMPILE_CPP) $(OUTPUT_OPTION) $< | ||
|
||
%.o: %.cpp | ||
$(COMPILE_CPP) $(OUTPUT_OPTION) $< | ||
|
||
clean: | ||
@rm -f $(C_SRC_OUTPUT) $(OBJECTS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/* Copyright 2021, Travelping GmbH <info@travelping.com> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
|
||
/* Generate a sequence of at most 2^32 unsigned 32bit integers using the | ||
* Fisher-Yates shuffle */ | ||
|
||
#include <erl_nif.h> | ||
#include <stdint.h> | ||
#include <time.h> | ||
|
||
#define STEPCNT (4*1024) | ||
|
||
#define min(x,y) ( \ | ||
{ __auto_type __x = (x); __auto_type __y = (y); \ | ||
__x < __y ? __x : __y; }) | ||
|
||
static ERL_NIF_TERM | ||
mk_atom(ErlNifEnv* env, const char* atom) | ||
{ | ||
ERL_NIF_TERM ret; | ||
|
||
if(!enif_make_existing_atom(env, atom, &ret, ERL_NIF_LATIN1)) | ||
{ | ||
return enif_make_atom(env, atom); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static void swap (unsigned int *a, unsigned int *b) | ||
{ | ||
unsigned int temp = *a; | ||
*a = *b; | ||
*b = temp; | ||
} | ||
|
||
static ERL_NIF_TERM shuffle_ret(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) | ||
{ | ||
ERL_NIF_TERM new_argv[4]; | ||
ERL_NIF_TERM head, tail; | ||
unsigned int i, n, end; | ||
unsigned int *arr; | ||
ErlNifBinary bin; | ||
|
||
if (argc != 4 || | ||
!enif_get_uint(env, argv[0], &n) || n <= 0 || | ||
!enif_get_uint(env, argv[1], &i) || i > n || | ||
!enif_inspect_binary(env, argv[2], &bin) || | ||
!enif_is_list(env, argv[3])) | ||
return enif_make_badarg(env); | ||
|
||
/* printf("ret i: %u\n\r", i); */ | ||
/* printf("ret n: %u\n\r", n); */ | ||
|
||
tail = argv[3]; | ||
end = min(n, i + STEPCNT); | ||
arr = (unsigned int *)bin.data; | ||
|
||
for (; i < end; i++) { | ||
head = enif_make_tuple1(env, | ||
enif_make_tuple2(env, | ||
enif_make_int64(env, INT64_MIN + i), | ||
enif_make_uint(env, arr[i]))); | ||
tail = enif_make_list_cell(env, head, tail); | ||
} | ||
|
||
if (i >= n) { | ||
enif_release_binary(&bin); | ||
return tail; | ||
} else { | ||
new_argv[0] = argv[0]; | ||
new_argv[1] = enif_make_uint(env, i); | ||
new_argv[2] = argv[2]; | ||
new_argv[3] = tail; | ||
return enif_schedule_nif(env, "shuffle_ret", 0, shuffle_ret, 4, new_argv); | ||
} | ||
} | ||
|
||
static ERL_NIF_TERM shuffle_randomize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) | ||
{ | ||
ERL_NIF_TERM new_argv[4]; | ||
unsigned int i, n, end; | ||
unsigned int *arr; | ||
ErlNifBinary bin; | ||
|
||
if (argc != 3 || | ||
!enif_get_uint(env, argv[0], &n) || n <= 0 || | ||
!enif_get_uint(env, argv[1], &i) || i > n || | ||
!enif_inspect_binary(env, argv[2], &bin)) | ||
return enif_make_badarg(env); | ||
|
||
if (i == n - 1) | ||
srand(time(NULL)); | ||
|
||
end = (i > STEPCNT) ? i - STEPCNT : 0; | ||
arr = (unsigned int *)bin.data; | ||
|
||
for (; i > end; i--) { | ||
unsigned int j = rand() % (i+1); | ||
swap(&arr[i], &arr[j]); | ||
} | ||
|
||
new_argv[0] = argv[0]; | ||
new_argv[2] = argv[2]; | ||
|
||
if (i == 0) { | ||
new_argv[1] = enif_make_uint(env, 0); | ||
new_argv[3] = enif_make_list(env, 0); | ||
return enif_schedule_nif(env, "shuffle_ret", 0, shuffle_ret, 4, new_argv); | ||
} else { | ||
new_argv[1] = enif_make_uint(env, i); | ||
return enif_schedule_nif(env, "shuffle_randomize", 0, shuffle_randomize, 3, new_argv); | ||
} | ||
} | ||
|
||
static ERL_NIF_TERM shuffle_fill(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) | ||
{ | ||
ERL_NIF_TERM new_argv[3]; | ||
unsigned int i, n, end; | ||
unsigned int *arr; | ||
ErlNifBinary bin; | ||
|
||
if (argc != 3 || | ||
!enif_get_uint(env, argv[0], &n) || n <= 0 || | ||
!enif_get_uint(env, argv[1], &i) || i > n || | ||
!enif_inspect_binary(env, argv[2], &bin)) | ||
return enif_make_badarg(env); | ||
|
||
/* printf("fill i: %u\r\n", i); */ | ||
/* printf("fill n: %u\r\n", n); */ | ||
|
||
end = min(n, i + STEPCNT); | ||
arr = (unsigned int *)bin.data; | ||
|
||
for (; i < end; i++) | ||
arr[i] = i; | ||
|
||
new_argv[0] = argv[0]; | ||
new_argv[2] = argv[2]; | ||
|
||
if (i == n) { | ||
new_argv[1] = enif_make_uint(env, n - 1); | ||
return enif_schedule_nif(env, "shuffle_randomize", 0, shuffle_randomize, 3, new_argv); | ||
} else { | ||
new_argv[1] = enif_make_uint(env, i); | ||
return enif_schedule_nif(env, "shuffle_fill", 0, shuffle_fill, 3, new_argv); | ||
} | ||
} | ||
|
||
static ERL_NIF_TERM shuffle(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) | ||
{ | ||
ERL_NIF_TERM new_argv[3]; | ||
unsigned int n; | ||
|
||
if (!enif_get_uint(env, argv[0], &n) || n <= 0) | ||
return enif_make_badarg(env); | ||
|
||
if (!(enif_make_new_binary(env, n * sizeof(unsigned int), &new_argv[2]))) | ||
return enif_raise_exception(env, mk_atom(env, "out_of_memory")); | ||
|
||
new_argv[0] = argv[0]; | ||
new_argv[1] = enif_make_uint(env, 0); | ||
return enif_schedule_nif(env, "shuffle_fill", 0, shuffle_fill, 3, new_argv); | ||
} | ||
|
||
#if 0 | ||
static ERL_NIF_TERM shuffle(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) | ||
{ | ||
ERL_NIF_TERM head, tail; | ||
unsigned int *arr; | ||
unsigned int i, n; | ||
|
||
if (!enif_get_uint(env, argv[0], &n) || n <= 0) | ||
return enif_make_badarg(env); | ||
|
||
if (!(arr = enif_alloc(n * sizeof(arr[0])))) | ||
return enif_raise_exception(env, mk_atom(env, "out_of_memory")); | ||
|
||
for (i = 0; i < n; i++) | ||
arr[i] = i; | ||
//randomize(arr, n); | ||
|
||
tail = enif_make_list(env, 0); | ||
for (i = 0; i < n; i++) { | ||
head = enif_make_uint(env, arr[i]); | ||
tail = enif_make_list_cell(env, head, tail); | ||
} | ||
return tail; | ||
} | ||
#endif | ||
|
||
static ErlNifFunc nif_funcs[] = | ||
{ | ||
{"shuffle", 1, shuffle} | ||
}; | ||
|
||
ERL_NIF_INIT(uint32_fy_shuffle, nif_funcs, NULL, NULL, NULL, NULL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{erl_opts, [debug_info]}. | ||
{deps, []}. | ||
|
||
{pre_hooks, | ||
[{"(linux|darwin|solaris)", compile, "make -C c_src"}, | ||
{"(freebsd)", compile, "gmake -C c_src"}]}. | ||
{post_hooks, | ||
[{"(linux|darwin|solaris)", clean, "make -C c_src clean"}, | ||
{"(freebsd)", clean, "gmake -C c_src clean"}]}. |
Oops, something went wrong.