diff --git a/.gitignore b/.gitignore index 794cf47f29656b5dce84e6bf56de0d2f052658c5..7f6c5cc92e1dda6f2ddf9164fb791a7106fb370d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,13 @@ src/networking/URI *.user NetRunner2008.ncb *.suo +*.id* +*.nam +*.til +*.dbg +/glew32.dll +/libgcc_s_sjlj-1.dll +/libssp-0.dll +/libstdc++-6.dll +/netrunner.exe +.vscode diff --git a/Makefile b/Makefile index 41f4cc30bb36c6d6ac23500b93e55daae3ab3c1c..f069d7c5f071bb651301547da559f9ddcce2b723 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,13 @@ UNAME := $(shell uname) CXX = g++ +CC = gcc GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags) +PLATFORM := $(shell g++ -dumpmachine) -CXXFLAGS = -O3 -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CXXFLAGS = -O3 -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" -DPLATFORM=\"$(PLATFORM)\" +CFLAGS = -O3 -flto=8 -std=c11 -DVERSION=\"$(GIT_VERSION)\" +CWARN = -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused WARNINGS = -Werror -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused -Wzero-as-null-pointer-constant -Wuseless-cast LIBS = -lglfw -lGL -lGLEW -lfreetype -lharfbuzz -lmbedtls -lmbedcrypto -lmbedx509 LDFLAGS = -O3 -flto=8 @@ -11,9 +15,11 @@ INCPATH = -I /usr/include/freetype2 -I /usr/include/harfbuzz MD5SUM = md5sum ifeq ($(UNAME), Darwin) -CXXFLAGS = -O3 -std=c++1y -DVERSION=\"$(GIT_VERSION)\" +CXXFLAGS = -O3 -std=c++1y -DVERSION=\"$(GIT_VERSION)\" -DPLATFORM=\"$(PLATFORM)\" +CFLAGS = -O3 -std=c11 -DVERSION=\"$(GIT_VERSION)\" WARNINGS = ifneq ("$(wildcard /usr/local/lib/libglfw3.a)","") +CWARN = LIBS = -lglfw3 -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo -lGLEW -lfreetype -lharfbuzz -lmbedtls -lmbedcrypto -lmbedx509 \ else LIBS = -lglfw3 -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo -lGLEW -lfreetype -lharfbuzz -lmbedtls -lmbedcrypto -lmbedx509 @@ -35,7 +41,7 @@ OBJECTS = $(subst $(SRCDIR),$(OBJDIR),$(SOURCES:.cpp=.o)) all: $(SOURCES) netrunner -netrunner: $(OBJECTS) +netrunner: $(OBJECTS) $(OBJDIR)/tlsf.o $(LINK) $(LDFLAGS) -o $@ $^ $(LIBS) # make make 3.81 happy (since it can't parse any echo parameters) @@ -79,6 +85,9 @@ $(OBJDIR)/%.o: $(SRCDIR)/%.cpp | shaders $(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) $(INCPATH) $(WARNINGS) -c -o $@ $< @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@ +$(OBJDIR)/tlsf.o: $(SRCDIR)/tlsf.c + $(CC) $(INCPATH) $(CWARN) -DTLSF_USE_LOCKS=0 -DUSE_MMAP=1 -DUSE_SBRK=1 -c -o $@ $< + $(DEPDIR)/%d: ; .PRECIOUS: $(DEPDIR)/%.d diff --git a/NTMakefile b/NTMakefile index f0a076f15a9a36eea1f1ffe41c62bfd0f4aab372..4ec99aa4a496be28fd5d121dc64a0299e8cbe1d2 100644 --- a/NTMakefile +++ b/NTMakefile @@ -1,21 +1,69 @@ UNAME := $(shell uname) CXX = g++ +CC = gcc GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags) ifdef DEBUG CXXFLAGS = -Og -g3 -fstack-protector-strong -fPIE -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CFLAGS = -Og -g3 -fstack-protector-strong -fPIE -std=c11 -DVERSION=\"$(GIT_VERSION)\" else +ifdef RELEASE_PACK +CXXFLAGS = -O3 -march=i686 -mtune=generic -fstack-protector-strong -fPIE -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CFLAGS = -O3 -march=i686 -mtune=generic -fstack-protector-strong -fPIE -flto=8 -std=c11 -DVERSION=\"$(GIT_VERSION)\" +else +CXXFLAGS = -O3 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CFLAGS = -O3 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE -flto=8 -std=c11 -DVERSION=\"$(GIT_VERSION)\" +endif +endif + +ifdef AMD64_DEBUG +CXXFLAGS = -Og -g3 -fstack-protector-strong -fPIE -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CFLAGS = -Og -g3 -fstack-protector-strong -fPIE -std=c11 -DVERSION=\"$(GIT_VERSION)\" +else +ifdef AMD64_RELEASE +CXXFLAGS = -O3 -march=opteron -mtune=opteron -mfpmath=sse -fstack-protector-strong -fPIE -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CFLAGS = -O3 -march=opteron -mtune=opteron -mfpmath=sse -fstack-protector-strong -fPIE -flto=8 -std=c11 -DVERSION=\"$(GIT_VERSION)\" +else +ifdef AMD64 CXXFLAGS = -O3 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" +CFLAGS = -O3 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE -std=c11 -DVERSION=\"$(GIT_VERSION)\" -flto=8 +endif +endif endif WARNINGS = -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused -Wzero-as-null-pointer-constant -Wuseless-cast +CWARN = -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused + +# i686 builds +ifdef DEBUG LIBS = -lglfw -lopenGL32 -lGLEW32 -lgdi32 -lpolarssl -lws2_32 -lharfbuzz -lfreetype -lpng -lbz2 -lz -ifndef DEBUG -LDFLAGS = -L ./deps/lib -O3 -flto=8 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE +LDFLAGS = -L ./deps/lib/nt_i386 -Og -g3 -fstack-protector-strong -fPIE else -LDFLAGS = -L ./deps/lib -Og -g3 -fstack-protector-strong -fPIE +ifdef RELEASE_PACK +LIBS = -lglfw -lopenGL32 -lGLEW32 -lgdi32 -lpolarssl -lws2_32 -lharfbuzz -lfreetype -lpng -lbz2 -lz +LDFLAGS = -L ./deps/lib/nt_i386/release -O3 -flto=8 -march=i686 -mtune=generic -fstack-protector-strong -fPIE +else +LIBS = -lglfw -lopenGL32 -lGLEW32 -lgdi32 -lpolarssl -lws2_32 -lharfbuzz -lfreetype -lpng -lbz2 -lz +LDFLAGS = -L ./deps/lib/nt_i386 -O3 -flto=8 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE endif +endif + +ifdef AMD64_DEBUG +LIBS = -lglfw -lopenGL32 -lglew32 -lgdi32 -lpolarssl -lws2_32 -lharfbuzz -lfreetype -lpng -lbz2 -lz +LDFLAGS = -L ./deps/lib/nt_amd64 -Og -g3 -fstack-protector-strong -fPIE +else +ifdef AMD64_RELEASE +LIBS = -lglfw -lopenGL32 -lglew32 -lgdi32 -lpolarssl -lws2_32 -lharfbuzz -lfreetype -lpng -lbz2 -lz +LDFLAGS = -L ./deps/lib/nt_amd64/release -O3 -flto=8 -march=opteron -mtune=opteron -mfpmath=sse -fstack-protector-strong -fPIE +else +ifdef AMD64 +LIBS = -lglfw -lopenGL32 -lglew32 -lgdi32 -lpolarssl -lws2_32 -lharfbuzz -lfreetype -lpng -lbz2 -lz +LDFLAGS = -L ./deps/lib/nt_amd64 -O3 -march=core2 -mfpmath=sse -fstack-protector-strong -fPIE -flto=8 +endif +endif +endif + INCPATH = -I ./deps/include EXECUTABLE = netrunner @@ -25,32 +73,14 @@ SRCDIR = src OBJDIR = gen DEPDIR = d -SOURCES = $(subst ./,,$(shell find . -name *.cpp)) +SOURCES = $(subst ./,,$(shell find src -name \*.cpp)) OBJECTS = $(subst $(SRCDIR),$(OBJDIR),$(SOURCES:.cpp=.o)) all: $(SOURCES) netrunner -netrunner: $(OBJECTS) +netrunner: $(OBJECTS) $(OBJDIR)/tlsf.o $(LINK) $(LDFLAGS) -o $@ $^ $(LIBS) -# make make 3.81 happy (since it can't parse any echo parameters) -ifeq ($(UNAME), Darwin) -shaders: -ifneq ($(shell cat src/graphics/opengl/shaders/FontShader.vert src/graphics/opengl/shaders/FontShader.frag src/graphics/opengl/shaders/TextureShader.vert src/graphics/opengl/shaders/TextureShader.frag | md5sum), $(shell cat src/graphics/opengl/shaders/gen/hashsum)) - @mkdir -p "src/graphics/opengl/shaders/gen" - @echo "#ifndef FONTSHADER_H\n#define FONTSHADER_H\n\nconst char *fontVertexShaderSource =\n" > src/graphics/opengl/shaders/gen/FontShader.h; - @cat src/graphics/opengl/shaders/FontShader.vert | awk '{if ($$0!="}") {print "\t\""$$0"\\n\""} else {print "\t\""$$0"\";\n"}}' >> src/graphics/opengl/shaders/gen/FontShader.h; - @echo "const char *fontFragmentShaderSource =\n" >> src/graphics/opengl/shaders/gen/FontShader.h; - @cat src/graphics/opengl/shaders/FontShader.frag | awk '{if ($$0!="}") {print "\t\""$$0"\\n\""} else {print "\t\""$$0"\";\n"}}' >> src/graphics/opengl/shaders/gen/FontShader.h; - @echo "#endif\n" >> src/graphics/opengl/shaders/gen/FontShader.h; - @echo "#ifndef TEXTURESHADER_H\n#define TEXTURESHADER_H\n\nconst char *textureVertexShaderSource =\n" > src/graphics/opengl/shaders/gen/TextureShader.h; - @cat src/graphics/opengl/shaders/TextureShader.vert | awk '{if ($$0!="}") {print "\t\""$$0"\\n\""} else {print "\t\""$$0"\";\n"}}' >> src/graphics/opengl/shaders/gen/TextureShader.h; - @echo "const char *textureFragmentShaderSource =\n" >> src/graphics/opengl/shaders/gen/TextureShader.h; - @cat src/graphics/opengl/shaders/TextureShader.frag | awk '{if ($$0!="}") {print "\t\""$$0"\\n\""} else {print "\t\""$$0"\";\n"}}' >> src/graphics/opengl/shaders/gen/TextureShader.h; - @echo "#endif\n" >> src/graphics/opengl/shaders/gen/TextureShader.h; - @cat src/graphics/opengl/shaders/FontShader.vert src/graphics/opengl/shaders/FontShader.frag src/graphics/opengl/shaders/TextureShader.vert src/graphics/opengl/shaders/TextureShader.frag | md5sum > src/graphics/opengl/shaders/gen/hashsum; -endif -else shaders: ifneq ($(shell cat src/graphics/opengl/shaders/FontShader.vert src/graphics/opengl/shaders/FontShader.frag src/graphics/opengl/shaders/TextureShader.vert src/graphics/opengl/shaders/TextureShader.frag | md5sum), $(shell cat src/graphics/opengl/shaders/gen/hashsum)) @mkdir -p "src/graphics/opengl/shaders/gen" @@ -66,17 +96,25 @@ ifneq ($(shell cat src/graphics/opengl/shaders/FontShader.vert src/graphics/open @cat src/graphics/opengl/shaders/TextureShader.frag | awk '{if ($$0!="}") {print "\t\""$$0"\\n\""} else {print "\t\""$$0"\";\n"}}' >> src/graphics/opengl/shaders/gen/TextureShader.h; @/bin/echo -ne "#endif\n" >> src/graphics/opengl/shaders/gen/TextureShader.h; endif -endif $(OBJDIR)/%.o: $(SRCDIR)/%.cpp | shaders @mkdir -p $(@D) @mkdir -p $(subst gen,d,$(@D)) - $(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) $(INCPATH) -c -o $@ $< + $(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) $(INCPATH) $(WARNINGS) -c -o $@ $< @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@ +$(OBJDIR)/tlsf.o: $(SRCDIR)/tlsf.c + $(CC) $(INCPATH) $(CWARN) -DTLSF_USE_LOCKS=0 -DUSE_SBRK=1 -c -o $@ $< + $(DEPDIR)/%d: ; .PRECIOUS: $(DEPDIR)/%.d +test-url.o: tests/testPrograms/URLtest.cpp + $(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) $(INCPATH) $(WARINGS) -c -o $@ $< + +ntr-run-tests: test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o + $(LINK) $(LDFLAGS) -o $@ test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o $(LIBS) + clean: -@rm -rf src/graphics/opengl/shaders/gen $(OBJDIR) $(EXECUTABLE) 2>/dev/null || true diff --git a/README.md b/README.md index d26f159da6b2e679577990bdd7d31d8eebf07188..4987f2c8968fd21207119241a92653aa10baff31 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +NT5+ (i386): [](https://nt-build-bot.rvx86.net:7421/job/netrunner-winnt-i686/) +.NET Server+ (AMD64): [](https://nt-build-bot.rvx86.net:7421/job/netrunner-winnt-amd64/) + # Netrunner is an implementation of a new web browser engine written in C++ utilizing OpenGL. @@ -54,7 +57,9 @@ GyroNinja.net is back online ### Windows [2017-08-20 binary package](https://my.mixtape.moe/exebyr.zip) + [Jenkins 32bit](https://nt-build-bot.rvx86.net:7421/job/netrunner-winnt-i686/) + [Jenkins 64bit](https://nt-build-bot.rvx86.net:7421/job/netrunner-winnt-amd64/) ## Milestones @@ -132,4 +137,4 @@ We coordinate on [irc.rizon.net](https://www.rizon.net/chat) #/g/netrunner or [O ### Class Types - Nodes: DOM tree objects - Elements: Individual tag types -- Components: (gameobjects) renderer entities +- Components: (gameobjects) renderer entities \ No newline at end of file diff --git a/deps/include/mbedtls/cipher.h b/deps/include/mbedtls/cipher.h index b12e38843a0f8aa2ec52e6621f7c9b5aaae82b21..7f08e5800acb95e2015b564e6f7d61770c5b8826 100644 --- a/deps/include/mbedtls/cipher.h +++ b/deps/include/mbedtls/cipher.h @@ -408,7 +408,11 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_ciphe static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx ) { if( NULL == ctx || NULL == ctx->cipher_info ) +#ifdef __cplusplus + return nullptr; +#else return 0; +#endif return ctx->cipher_info->name; } diff --git a/deps/include/mbedtls/ssl_ciphersuites.h b/deps/include/mbedtls/ssl_ciphersuites.h index 931c1b3c388f70efc1109403b1ec5f3c40b26e3c..ad6461609f046cc80999082603a78a6027b05b2f 100644 --- a/deps/include/mbedtls/ssl_ciphersuites.h +++ b/deps/include/mbedtls/ssl_ciphersuites.h @@ -349,7 +349,7 @@ struct mbedtls_ssl_ciphersuite_t unsigned char flags; }; -const int *mbedtls_ssl_list_ciphersuites( void ); +//const int *mbedtls_ssl_list_ciphersuites( void ); const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name ); const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id ); diff --git a/deps/lib/nt_amd64/glew32.dll b/deps/lib/nt_amd64/glew32.dll new file mode 100644 index 0000000000000000000000000000000000000000..4f466928eaf680ff2e421a73c0422f5347d40701 Binary files /dev/null and b/deps/lib/nt_amd64/glew32.dll differ diff --git a/deps/lib/nt_amd64/libbz2.a b/deps/lib/nt_amd64/libbz2.a new file mode 100644 index 0000000000000000000000000000000000000000..52ed3356d6251c131f0d92920c89e976d027db95 Binary files /dev/null and b/deps/lib/nt_amd64/libbz2.a differ diff --git a/deps/lib/nt_amd64/libfreetype.a b/deps/lib/nt_amd64/libfreetype.a new file mode 100644 index 0000000000000000000000000000000000000000..11a7002bc235f43a68e37bbb2cbdcc887a5d458b Binary files /dev/null and b/deps/lib/nt_amd64/libfreetype.a differ diff --git a/deps/lib/nt_amd64/libglfw.a b/deps/lib/nt_amd64/libglfw.a new file mode 100644 index 0000000000000000000000000000000000000000..e14088c96eed1a01777a8e6d4435afb91bdf2960 Binary files /dev/null and b/deps/lib/nt_amd64/libglfw.a differ diff --git a/deps/lib/nt_amd64/libharfbuzz.a b/deps/lib/nt_amd64/libharfbuzz.a new file mode 100644 index 0000000000000000000000000000000000000000..9599fb5122095dee0b81f992f7fc8a9c5b67fb2f Binary files /dev/null and b/deps/lib/nt_amd64/libharfbuzz.a differ diff --git a/deps/lib/nt_amd64/libpng.a b/deps/lib/nt_amd64/libpng.a new file mode 100644 index 0000000000000000000000000000000000000000..900c9309eb97263eb55e44c27d5d6cccb8cc9bc3 Binary files /dev/null and b/deps/lib/nt_amd64/libpng.a differ diff --git a/deps/lib/nt_amd64/libpolarssl.a b/deps/lib/nt_amd64/libpolarssl.a new file mode 100644 index 0000000000000000000000000000000000000000..a5b1f072109382620fc9bdf0c37885044deac2f0 Binary files /dev/null and b/deps/lib/nt_amd64/libpolarssl.a differ diff --git a/deps/lib/nt_amd64/libz.a b/deps/lib/nt_amd64/libz.a new file mode 100644 index 0000000000000000000000000000000000000000..670da768d995739b85ddabef06065eaac48dc994 Binary files /dev/null and b/deps/lib/nt_amd64/libz.a differ diff --git a/deps/lib/nt_amd64/release/glew32.dll b/deps/lib/nt_amd64/release/glew32.dll new file mode 100644 index 0000000000000000000000000000000000000000..4f466928eaf680ff2e421a73c0422f5347d40701 Binary files /dev/null and b/deps/lib/nt_amd64/release/glew32.dll differ diff --git a/deps/lib/nt_amd64/release/libbz2.a b/deps/lib/nt_amd64/release/libbz2.a new file mode 100644 index 0000000000000000000000000000000000000000..7eeb998741e292d5b43d5a45cd7ee5215b3e0010 Binary files /dev/null and b/deps/lib/nt_amd64/release/libbz2.a differ diff --git a/deps/lib/nt_amd64/release/libfreetype.a b/deps/lib/nt_amd64/release/libfreetype.a new file mode 100644 index 0000000000000000000000000000000000000000..b290dd6d706c80b1e9988ed23f22228cbf6f3168 Binary files /dev/null and b/deps/lib/nt_amd64/release/libfreetype.a differ diff --git a/deps/lib/nt_amd64/release/libglfw.a b/deps/lib/nt_amd64/release/libglfw.a new file mode 100644 index 0000000000000000000000000000000000000000..d1b6bc69776880af8f7e5cb7ac3e215059925090 Binary files /dev/null and b/deps/lib/nt_amd64/release/libglfw.a differ diff --git a/deps/lib/nt_amd64/release/libharfbuzz.a b/deps/lib/nt_amd64/release/libharfbuzz.a new file mode 100644 index 0000000000000000000000000000000000000000..24f898d6a6ade8b207a8e13cbef3d5e433c2d181 Binary files /dev/null and b/deps/lib/nt_amd64/release/libharfbuzz.a differ diff --git a/deps/lib/nt_amd64/release/libpng.a b/deps/lib/nt_amd64/release/libpng.a new file mode 100644 index 0000000000000000000000000000000000000000..4e1373f369fd373a493ef34bd2c3467b250eae2a Binary files /dev/null and b/deps/lib/nt_amd64/release/libpng.a differ diff --git a/deps/lib/nt_amd64/release/libpolarssl.a b/deps/lib/nt_amd64/release/libpolarssl.a new file mode 100644 index 0000000000000000000000000000000000000000..35d19c60fe3b9b239adf25f25b8e58e26a58326e Binary files /dev/null and b/deps/lib/nt_amd64/release/libpolarssl.a differ diff --git a/deps/lib/nt_amd64/release/libz.a b/deps/lib/nt_amd64/release/libz.a new file mode 100644 index 0000000000000000000000000000000000000000..b261b8bea314cc160eee42b4fbe0739bec33c00c Binary files /dev/null and b/deps/lib/nt_amd64/release/libz.a differ diff --git a/deps/lib/glew32.dll b/deps/lib/nt_i386/glew32.dll similarity index 100% rename from deps/lib/glew32.dll rename to deps/lib/nt_i386/glew32.dll diff --git a/deps/lib/libbz2.a b/deps/lib/nt_i386/libbz2.a similarity index 100% rename from deps/lib/libbz2.a rename to deps/lib/nt_i386/libbz2.a diff --git a/deps/lib/libfreetype.a b/deps/lib/nt_i386/libfreetype.a similarity index 100% rename from deps/lib/libfreetype.a rename to deps/lib/nt_i386/libfreetype.a diff --git a/deps/lib/libglfw.a b/deps/lib/nt_i386/libglfw.a similarity index 100% rename from deps/lib/libglfw.a rename to deps/lib/nt_i386/libglfw.a diff --git a/deps/lib/libharfbuzz.a b/deps/lib/nt_i386/libharfbuzz.a similarity index 100% rename from deps/lib/libharfbuzz.a rename to deps/lib/nt_i386/libharfbuzz.a diff --git a/deps/lib/libpng.a b/deps/lib/nt_i386/libpng.a similarity index 100% rename from deps/lib/libpng.a rename to deps/lib/nt_i386/libpng.a diff --git a/deps/lib/libpolarssl.a b/deps/lib/nt_i386/libpolarssl.a similarity index 99% rename from deps/lib/libpolarssl.a rename to deps/lib/nt_i386/libpolarssl.a index 882d15f6ee9fec5590f65b575ba83e0dd495f2aa..5f6ae6a2405424810f21dca48e9f2b641d1dbf0f 100644 Binary files a/deps/lib/libpolarssl.a and b/deps/lib/nt_i386/libpolarssl.a differ diff --git a/deps/lib/libz.a b/deps/lib/nt_i386/libz.a similarity index 100% rename from deps/lib/libz.a rename to deps/lib/nt_i386/libz.a diff --git a/reltools/winnt/glew32.dll b/deps/lib/nt_i386/release/glew32.dll similarity index 51% rename from reltools/winnt/glew32.dll rename to deps/lib/nt_i386/release/glew32.dll index 62e14621a5d6bd62a75fdef4a8f12a9e44b9dff5..68b362e85298fe8270380169dbb766370862dbd0 100644 Binary files a/reltools/winnt/glew32.dll and b/deps/lib/nt_i386/release/glew32.dll differ diff --git a/deps/lib/nt_i386/release/libbz2.a b/deps/lib/nt_i386/release/libbz2.a new file mode 100644 index 0000000000000000000000000000000000000000..3c57e18d6c0e0157adeda2676965de45899dac71 Binary files /dev/null and b/deps/lib/nt_i386/release/libbz2.a differ diff --git a/deps/lib/nt_i386/release/libfreetype.a b/deps/lib/nt_i386/release/libfreetype.a new file mode 100644 index 0000000000000000000000000000000000000000..65d1e8cebf955316e354cabfb7b39592b0f7fb80 Binary files /dev/null and b/deps/lib/nt_i386/release/libfreetype.a differ diff --git a/deps/lib/nt_i386/release/libglfw-nt.a b/deps/lib/nt_i386/release/libglfw-nt.a new file mode 100644 index 0000000000000000000000000000000000000000..d363a3caadcfd424c45b62c0a415311326918375 Binary files /dev/null and b/deps/lib/nt_i386/release/libglfw-nt.a differ diff --git a/deps/lib/nt_i386/release/libglfw3.a b/deps/lib/nt_i386/release/libglfw3.a new file mode 100644 index 0000000000000000000000000000000000000000..188c5e533a1e0be749dc07531c9974925689c87a Binary files /dev/null and b/deps/lib/nt_i386/release/libglfw3.a differ diff --git a/deps/lib/nt_i386/release/libharfbuzz.a b/deps/lib/nt_i386/release/libharfbuzz.a new file mode 100644 index 0000000000000000000000000000000000000000..dd60976a49e506e1e2a639b99557db5d9379ef6e Binary files /dev/null and b/deps/lib/nt_i386/release/libharfbuzz.a differ diff --git a/deps/lib/nt_i386/release/libpng.a b/deps/lib/nt_i386/release/libpng.a new file mode 100644 index 0000000000000000000000000000000000000000..3c827b02f2b0dcc74ffd17d04dfcb4c9e1172386 Binary files /dev/null and b/deps/lib/nt_i386/release/libpng.a differ diff --git a/deps/lib/nt_i386/release/libpolarssl.a b/deps/lib/nt_i386/release/libpolarssl.a new file mode 100644 index 0000000000000000000000000000000000000000..85f3b7a8a3bc55f00058c48c7d21885d7ca73d86 Binary files /dev/null and b/deps/lib/nt_i386/release/libpolarssl.a differ diff --git a/deps/lib/nt_i386/release/libz.a b/deps/lib/nt_i386/release/libz.a new file mode 100644 index 0000000000000000000000000000000000000000..ce7a576fc3d52aa650acbaa13b8a0c23a1f4d090 Binary files /dev/null and b/deps/lib/nt_i386/release/libz.a differ diff --git a/netrunner.zip b/netrunner.zip deleted file mode 100644 index 6df15da7aa1ac30f0501cfa0cf0385e366710d12..0000000000000000000000000000000000000000 Binary files a/netrunner.zip and /dev/null differ diff --git a/netrunner_ssl.zip b/netrunner_ssl.zip deleted file mode 100644 index 291530d141eb9dd84a1157e0fa94717496e4947d..0000000000000000000000000000000000000000 Binary files a/netrunner_ssl.zip and /dev/null differ diff --git a/reltools/winnt/amd64/glew32.dll b/reltools/winnt/amd64/glew32.dll new file mode 100644 index 0000000000000000000000000000000000000000..4f466928eaf680ff2e421a73c0422f5347d40701 Binary files /dev/null and b/reltools/winnt/amd64/glew32.dll differ diff --git a/reltools/winnt/amd64/libgcc_s_seh-1.dll b/reltools/winnt/amd64/libgcc_s_seh-1.dll new file mode 100644 index 0000000000000000000000000000000000000000..c2cb099075820a27a71e48b88147888a0b17a251 Binary files /dev/null and b/reltools/winnt/amd64/libgcc_s_seh-1.dll differ diff --git a/reltools/winnt/amd64/libssp-0.dll b/reltools/winnt/amd64/libssp-0.dll new file mode 100644 index 0000000000000000000000000000000000000000..1a72f8246d9b354d19a994c41c2de7fa7324bd20 Binary files /dev/null and b/reltools/winnt/amd64/libssp-0.dll differ diff --git a/reltools/winnt/amd64/libstdc++-6.dll b/reltools/winnt/amd64/libstdc++-6.dll new file mode 100644 index 0000000000000000000000000000000000000000..d53101e7ee563076f54bc583622b8291ef56e7d4 Binary files /dev/null and b/reltools/winnt/amd64/libstdc++-6.dll differ diff --git a/reltools/winnt/amd64/libwinpthread-1.dll b/reltools/winnt/amd64/libwinpthread-1.dll new file mode 100644 index 0000000000000000000000000000000000000000..11a98619aac9df5f8b098db970054247fc4b70fe Binary files /dev/null and b/reltools/winnt/amd64/libwinpthread-1.dll differ diff --git a/reltools/winnt/i386/glew32.dll b/reltools/winnt/i386/glew32.dll new file mode 100644 index 0000000000000000000000000000000000000000..68b362e85298fe8270380169dbb766370862dbd0 Binary files /dev/null and b/reltools/winnt/i386/glew32.dll differ diff --git a/reltools/winnt/libgcc_s_sjlj-1.dll b/reltools/winnt/i386/libgcc_s_sjlj-1.dll similarity index 100% rename from reltools/winnt/libgcc_s_sjlj-1.dll rename to reltools/winnt/i386/libgcc_s_sjlj-1.dll diff --git a/reltools/winnt/libssp-0.dll b/reltools/winnt/i386/libssp-0.dll similarity index 100% rename from reltools/winnt/libssp-0.dll rename to reltools/winnt/i386/libssp-0.dll diff --git a/reltools/winnt/libstdc++-6.dll b/reltools/winnt/i386/libstdc++-6.dll similarity index 100% rename from reltools/winnt/libstdc++-6.dll rename to reltools/winnt/i386/libstdc++-6.dll diff --git a/src/CFGFileParser.cpp b/src/CFGFileParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42d0659fb91d0051a93a22aa2161a51ab9e5f975 --- /dev/null +++ b/src/CFGFileParser.cpp @@ -0,0 +1,45 @@ +#include "CFGFileParser.h" + +CFGFileParser::CFGFileParser(const char* filename) +{ + // Open the config file, get its size, + // allocate the buffer, read it into + // the buffer, close the file + cfg_file = fopen(filename, "r"); + stat(filename, cfg_fileinfo); + buffer = static_cast<char*>(tlsf_calloc(cfg_fileinfo->st_size,sizeof(char))); + fread(buffer,sizeof(char),cfg_fileinfo->st_size,cfg_file); + fclose(cfg_file); +} + +CFGFileParser::~CFGFileParser() +{ + // clean up! + tlsf_free(buffer); +} + +namespace ntr{ + size_t string_hash(const fast_string &str) + { + size_t out = 0; +// instead of tying this to i386/amd64 +// because someone is eventually going to +// port this to ARM or some RISC nonsense +#if UINTPTR_MAX == 0xffffffff + MurmurHash3_x86_128 ( &str, sizeof(str), 7904542L, &out ); +#elif UINTPTR_MAX == 0xffffffffffffffff + MurmurHash3_x64_128 ( &str, sizeof(str), 5484754L, &out ); +#else +#endif + return out; + } + + bool fast_string_compare(fast_string t1, fast_string t2) + { + int i = strcmp(t1.c_str(),t2.c_str()); + if (!i) + return true; + else + return false; + } +} \ No newline at end of file diff --git a/src/CFGFileParser.h b/src/CFGFileParser.h new file mode 100644 index 0000000000000000000000000000000000000000..43d4011404945840e89a416dae341cf43d9939c1 --- /dev/null +++ b/src/CFGFileParser.h @@ -0,0 +1,49 @@ +#ifndef __CFGFILEPARSER_H__ +#define __CFGFILEPARSER_H__ +#include <string> +#include <unordered_map> +#include <utility> +#include <functional> +#include <algorithm> +#include "TLSFAlloc.h" +#include "Murmur3.h" +#include "tlsf.h" +#include <sys/stat.h> +#include <cstdint> + +// let's try fast strings +namespace ntr{ + typedef std::basic_string<char, std::char_traits<char>, TLSFAlloc<char>> fast_string; + size_t string_hash(const fast_string &str); + bool fast_string_compare(fast_string t1, fast_string t2); + typedef std::unordered_map<fast_string,fast_string,std::function<decltype(string_hash)>,std::function<decltype(fast_string_compare)>,TLSFAlloc<std::pair<const fast_string, fast_string>>> stringmap; +} +// Class which holds the parsed configuration options after +// being processed by CFGFileParser. No longer a "trivial class" +// just select by cfg->GlobalSettings.... +struct BrowserConfiguration{ + ntr::stringmap GlobalSettings; +// fast allocation! + static void* operator new(std::size_t n){ + if (void *mem = tlsf_malloc(n)){ + return mem; + } throw std::bad_alloc {}; + } + static void operator delete(void *p){ + tlsf_free(p); + } + void clear(); +}; + +class CFGFileParser { +public: + CFGFileParser(const char* filename); + ~CFGFileParser(); + static void* operator new(std::size_t n){ if (void *mem = tlsf_malloc(n)) return mem; throw std::bad_alloc {}; } + static void operator delete(void *p){tlsf_free(p);} +private: + FILE *cfg_file; + char *buffer; + struct stat *cfg_fileinfo; +}; +#endif // __CFGFILEPARSER_H__ \ No newline at end of file diff --git a/src/Murmur3.cpp b/src/Murmur3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7240e3a5b0a74ce02970140ab6c7c96c5703edc --- /dev/null +++ b/src/Murmur3.cpp @@ -0,0 +1,334 @@ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +// Note - The x86 and x64 versions do _not_ produce the same results, as the +// algorithms are optimized for their respective platforms. You can still +// compile and run any of them on any platform, but your performance with the +// non-native version will be less than optimal. + +#include "Murmur3.h" + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +// Microsoft Visual Studio + +#if defined(_MSC_VER) + +#define FORCE_INLINE __forceinline + +#include <stdlib.h> + +#define ROTL32(x,y) _rotl(x,y) +#define ROTL64(x,y) _rotl64(x,y) + +#define BIG_CONSTANT(x) (x) + +// Other compilers + +#else // defined(_MSC_VER) + +#define FORCE_INLINE inline __attribute__((always_inline)) + +inline uint32_t rotl32 ( uint32_t x, int8_t r ) +{ + return (x << r) | (x >> (32 - r)); +} + +inline uint64_t rotl64 ( uint64_t x, int8_t r ) +{ + return (x << r) | (x >> (64 - r)); +} + +#define ROTL32(x,y) rotl32(x,y) +#define ROTL64(x,y) rotl64(x,y) + +#define BIG_CONSTANT(x) (x##LLU) + +#endif // !defined(_MSC_VER) + +//----------------------------------------------------------------------------- +// Block read - if your platform needs to do endian-swapping or can only +// handle aligned reads, do the conversion here + +FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) +{ + return p[i]; +} + +FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i ) +{ + return p[i]; +} + +//----------------------------------------------------------------------------- +// Finalization mix - force all bits of a hash block to avalanche + +FORCE_INLINE uint32_t fmix32 ( uint32_t h ) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +//---------- + +FORCE_INLINE uint64_t fmix64 ( uint64_t k ) +{ + k ^= k >> 33; + k *= BIG_CONSTANT(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return k; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32 ( const void * key, int len, + uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 4; + + uint32_t h1 = seed; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + //---------- + // body + + const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); + + for(int i = -nblocks; i; i++) + { + uint32_t k1 = getblock32(blocks,i); + + k1 *= c1; + k1 = ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1,13); + h1 = h1*5+0xe6546b64; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*4); + + uint32_t k1 = 0; + + switch(len & 3) + { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; + + h1 = fmix32(h1); + + *(uint32_t*)out = h1; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_128 ( const void * key, const int len, + uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 16; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + const uint32_t c1 = 0x239b961b; + const uint32_t c2 = 0xab0e9789; + const uint32_t c3 = 0x38b34ae5; + const uint32_t c4 = 0xa1e38b93; + + //---------- + // body + + const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); + + for(int i = -nblocks; i; i++) + { + uint32_t k1 = getblock32(blocks,i*4+0); + uint32_t k2 = getblock32(blocks,i*4+1); + uint32_t k3 = getblock32(blocks,i*4+2); + uint32_t k4 = getblock32(blocks,i*4+3); + + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + + h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; + + k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; + + h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; + + k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; + + h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; + + k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; + + h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch(len & 15) + { + case 15: k4 ^= tail[14] << 16; + case 14: k4 ^= tail[13] << 8; + case 13: k4 ^= tail[12] << 0; + k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; + + case 12: k3 ^= tail[11] << 24; + case 11: k3 ^= tail[10] << 16; + case 10: k3 ^= tail[ 9] << 8; + case 9: k3 ^= tail[ 8] << 0; + k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; + + case 8: k2 ^= tail[ 7] << 24; + case 7: k2 ^= tail[ 6] << 16; + case 6: k2 ^= tail[ 5] << 8; + case 5: k2 ^= tail[ 4] << 0; + k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; + + case 4: k1 ^= tail[ 3] << 24; + case 3: k1 ^= tail[ 2] << 16; + case 2: k1 ^= tail[ 1] << 8; + case 1: k1 ^= tail[ 0] << 0; + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + h1 = fmix32(h1); + h2 = fmix32(h2); + h3 = fmix32(h3); + h4 = fmix32(h4); + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + ((uint32_t*)out)[0] = h1; + ((uint32_t*)out)[1] = h2; + ((uint32_t*)out)[2] = h3; + ((uint32_t*)out)[3] = h4; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x64_128 ( const void * key, const int len, + const uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 16; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); + const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); + + //---------- + // body + + const uint64_t * blocks = (const uint64_t *)(data); + + for(int i = 0; i < nblocks; i++) + { + uint64_t k1 = getblock64(blocks,i*2+0); + uint64_t k2 = getblock64(blocks,i*2+1); + + k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; + + h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; + + k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; + + h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch(len & 15) + { + case 15: k2 ^= ((uint64_t)tail[14]) << 48; + case 14: k2 ^= ((uint64_t)tail[13]) << 40; + case 13: k2 ^= ((uint64_t)tail[12]) << 32; + case 12: k2 ^= ((uint64_t)tail[11]) << 24; + case 11: k2 ^= ((uint64_t)tail[10]) << 16; + case 10: k2 ^= ((uint64_t)tail[ 9]) << 8; + case 9: k2 ^= ((uint64_t)tail[ 8]) << 0; + k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; + + case 8: k1 ^= ((uint64_t)tail[ 7]) << 56; + case 7: k1 ^= ((uint64_t)tail[ 6]) << 48; + case 6: k1 ^= ((uint64_t)tail[ 5]) << 40; + case 5: k1 ^= ((uint64_t)tail[ 4]) << 32; + case 4: k1 ^= ((uint64_t)tail[ 3]) << 24; + case 3: k1 ^= ((uint64_t)tail[ 2]) << 16; + case 2: k1 ^= ((uint64_t)tail[ 1]) << 8; + case 1: k1 ^= ((uint64_t)tail[ 0]) << 0; + k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + + ((uint64_t*)out)[0] = h1; + ((uint64_t*)out)[1] = h2; +} + +//----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/Murmur3.h b/src/Murmur3.h new file mode 100644 index 0000000000000000000000000000000000000000..5c1797dbcea8eff3fd85c3c6c43eb2a337f38a43 --- /dev/null +++ b/src/Murmur3.h @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#ifndef _MURMURHASH3_H_ +#define _MURMURHASH3_H_ + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +// Microsoft Visual Studio + +#if defined(_MSC_VER) && (_MSC_VER < 1600) + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; + +// Other compilers + +#else // defined(_MSC_VER) + +#include <stdint.h> + +#endif // !defined(_MSC_VER) + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out ); + +void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out ); + +void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out ); + +//----------------------------------------------------------------------------- + +#endif // _MURMURHASH3_H_ \ No newline at end of file diff --git a/src/TLSFAlloc.h b/src/TLSFAlloc.h new file mode 100644 index 0000000000000000000000000000000000000000..ac0ec4264aaae1cec66ba540992f4a658eeb4473 --- /dev/null +++ b/src/TLSFAlloc.h @@ -0,0 +1,70 @@ +// This is a custom C++ allocator that wraps the 2LSF C heap allocator +// -despair +// in case of emergency, set DEBUG_TLSF_CPP somewhere before including this header + +#include <limits> +#include <iostream> +#include "tlsf.h" + +namespace ntr { + template <class T> + class TLSFAlloc { + public: + typedef T value_type; + typedef T* ptr; + typedef const T* const_ptr; + typedef T& ref; + typedef const T& const_ref; + typedef std::size_t size_type; + typedef std::ptrdiff_t diff_type; + + template <class U> + struct rebind { typedef TLSFAlloc<U> other; }; + + ptr address (ref value) const {return &value;} + const_ptr address (const_ref value) const {return &value;} + + // these are the constructors for same: had I not ported sbrk(2) to winnt, + // the constructor would have generated a memory pool from above. + TLSFAlloc() throw() {} + TLSFAlloc(const TLSFAlloc&) throw() {} + template <class U> TLSFAlloc(const TLSFAlloc<U>&) throw() {} + ~TLSFAlloc() throw() {} + + // return maximum number of elements that can be allocated + size_type max_size() const throw() {return std::numeric_limits<std::size_t>::max() / sizeof(T);} + + // allocate but don't initialize num elements of type T + ptr allocate(size_type num, const void* = 0) { +#ifdef DEBUG_TLSF_CPP + // print message and allocate memory with 2LSF + std::cerr << "allocate " << num << " element(s)" << " of size " << sizeof(T) << std::endl; + ptr ret = (ptr)(tlsf_malloc(num*sizeof(T))); + std::cerr << " allocated at: " << (void*)ret << std::endl; return ret; +#else + ptr ret = static_cast<ptr>(tlsf_malloc(num*sizeof(T))); return ret; +#endif + } + // initialize elements of allocated storage p with value value + // using placement new (defined here) + void construct (ptr p, const T& value) {new (reinterpret_cast<void*>(p))T(value);} + // placement new + void* operator new (std::size_t size, void*){return allocate(size);} + + // destroy elements of initialized storage p + void destroy (ptr p) {p->~T();} + + // deallocate storage p of deleted elements + void deallocate(ptr p, size_type num) { +#ifdef DEBUG_TLSF_CPP + // print message and deallocate memory with global delete + std::cerr << "deallocate " << num << " element(s)" << " of size " << sizeof(T) << " at: " << (void*)p << std::endl; +#endif + tlsf_free(reinterpret_cast<void*>(p)); + } + }; + + // return that all specializations of this allocator are interchangeable + template <class T1, class T2> bool operator== (const TLSFAlloc<T1>&,const TLSFAlloc<T2>&) throw() { return true; } + template <class T1, class T2> bool operator!= (const TLSFAlloc<T1>&, const TLSFAlloc<T2>&) throw() { return false; } +} \ No newline at end of file diff --git a/src/graphics/components/AnimeComponent.cpp b/src/graphics/components/AnimeComponent.cpp index 749021b9fb0f2785c039f6fbf63b483f577a60a1..38059b93c3bc38ae6ba658d736dd8f58aad51ca3 100644 --- a/src/graphics/components/AnimeComponent.cpp +++ b/src/graphics/components/AnimeComponent.cpp @@ -2,6 +2,9 @@ #include <cmath> #include <iostream> #include "../../pnm.h" +#ifdef __MINGW32__ +#include "../../../anime.h" +#endif AnimeComponent::AnimeComponent(const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int passedWindowWidth, const int passedWindowHeight) : BoxComponent(rawX, rawY, rawWidth, rawHeight, 0x00000000, passedWindowWidth, passedWindowHeight) { //std::cout << "AnimeComponent::AnimeComponent" << std::endl; @@ -14,11 +17,20 @@ AnimeComponent::AnimeComponent(const float rawX, const float rawY, const float r width = rawWidth; height = rawHeight; +#ifdef __MINGW32__ // the old "huge string" works fine with mingw +for (int py = 0; py < 1024; py++) { + for (int px = 0; px < 1024; px++) { + for (int i = 0; i < 4; i++) { + data[1023 - py][px][i] = anime.pixel_data[((px * 4) + (py * 4 * 1024)) + i]; + } + } +} +#else // this is either non-Windows or using Microsoft C/C++ RGBAPNMObject *anime = readPPM("anime.pnm"); if (!anime) { std::cout << "Can't set up anime component, couldn't read anime.pnm" << std::endl; } - + for (int py = 0; py < 1024; py++) { for (int px = 0; px < 1024; px++) { if (anime) { @@ -31,6 +43,7 @@ AnimeComponent::AnimeComponent(const float rawX, const float rawY, const float r } } } +#endif float vx = rawX; float vy = rawY; @@ -71,6 +84,8 @@ AnimeComponent::AnimeComponent(const float rawX, const float rawY, const float r glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); - delete[] anime->m_Ptr; + #ifndef __MINGW32__ + tlsf_free(anime->m_Ptr); delete anime; + #endif } diff --git a/src/main.cpp b/src/main.cpp index daee3e74d8dedc7b7281548b3db7ba1ae4159b5d..1f8de3bbac7655b4ed2b57ae837722dd689c8ec1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,10 +4,21 @@ #include "Log.h" #include "URL.h" #include "WebResource.h" - +#include "tlsf.h" #include <ctime> #include <iostream> #include <sys/stat.h> +#ifdef _WIN32 +extern "C"{ + void init_heap(); +} +#endif +#if defined(_WIN32) && !defined(_WIN64) +#define PLATFORM "i686-pc-winnt" +#endif +#ifdef _WIN64 +#define PLATFORM "amd64-pc-winnt" +#endif const std::unique_ptr<Window> window = std::make_unique<Window>(); //URL currentURL; @@ -74,7 +85,10 @@ int main(int argc, char *argv[]) { return 1; } */ - std::cout << "/g/ntr - NetRunner build " << __DATE__ << std::endl; +# ifdef _WIN32 + init_heap(); // the NT port requires it. We do it at startup now, to allow 2LSF to run at any time +# endif + std::cout << "/g/ntr - NetRunner build " << __DATE__ << ": rev-" << VERSION << " for " << PLATFORM << std::endl; // we need to set up OGL before we can setDOM (because component can't be constructed (currently) without OGL) // but should be after CommandLineParams incase we need to change some type of window config diff --git a/src/networking/HTTPSRequest.cpp b/src/networking/HTTPSRequest.cpp index 942c95036ebea89bade7d5dd3be4a4cde194c2c4..7d359275e7e9c367873b674a9ada79c4ba146375 100644 --- a/src/networking/HTTPSRequest.cpp +++ b/src/networking/HTTPSRequest.cpp @@ -134,7 +134,7 @@ bool HTTPSRequest::initTLS() mbedtls_x509_crt_init( &cacert ); mbedtls_ctr_drbg_init( &ctr_drbg ); - const char *seed = "netrunner_ssl_seed$%?rvx86_despair^^%$#@"; + const char *seed = "!@netrunner_ssl_seed$%?rvx86_despair##^^%$#@"; mbedtls_entropy_init( &entropy ); if(mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, reinterpret_cast<const unsigned char*>(seed), strlen(seed) ) != 0 ) { diff --git a/src/networking/HTTPSRequest.h b/src/networking/HTTPSRequest.h index 52eb82f8da65eb993333cb4841a91808e8215fd1..64c14ca98def0e5d72fb1228c978dc5d7e59e816 100644 --- a/src/networking/HTTPSRequest.h +++ b/src/networking/HTTPSRequest.h @@ -6,6 +6,10 @@ #include "../URL.h" #include <functional> #include <string> +#ifdef NULL +#undef NULL +#define NULL nullptr +#endif // PolarSSL #include <mbedtls/ssl.h> #include <mbedtls/entropy.h> diff --git a/src/pnm.cpp b/src/pnm.cpp index dfd629c05e1b1c7e8d021ee238df8da77e213c8a..ecf4a3a47c59a7341b101f75df1432d35c9b2aa2 100644 --- a/src/pnm.cpp +++ b/src/pnm.cpp @@ -58,7 +58,7 @@ RGBAPNMObject * readPPM(const char* fileName) { } // allocate array for pixels - char* pixels = new char[size]; + char* pixels = reinterpret_cast<char*>(tlsf_calloc(size, sizeof(char)));/*new char[size]*/; // unformatted read of binary pixel data res = fread(pixels, sizeof(int), size, fr); diff --git a/src/pnm.h b/src/pnm.h index 4633fc968eb55ba69f6d13a525835ddecd9397b8..271f86ebef699035fe6cd83690a823d67dc1a40b 100644 --- a/src/pnm.h +++ b/src/pnm.h @@ -1,10 +1,15 @@ #include <string> +#include "tlsf.h" // this structure expects RGBA struct RGBAPNMObject { std::string magicNum; unsigned int width, height, maxColVal; char * m_Ptr; + + // fast allocation! + static void* operator new(size_t n){if (void *mem = tlsf_malloc(n)) return mem; throw std::bad_alloc {}; } + static void operator delete(void *p){tlsf_free(p);} }; RGBAPNMObject * readPPM(const char* fileName); diff --git a/src/target.h b/src/target.h new file mode 100644 index 0000000000000000000000000000000000000000..1afd62aef20978e7fb998d11be68266fb834f062 --- /dev/null +++ b/src/target.h @@ -0,0 +1,12 @@ +#ifndef _TARGET_H_ +#define _TARGET_H_ + +#include <pthread.h> + +#define TLSF_MLOCK_T pthread_mutex_t +#define TLSF_CREATE_LOCK(l) pthread_mutex_init (l, NULL) +#define TLSF_DESTROY_LOCK(l) pthread_mutex_destroy(l) +#define TLSF_ACQUIRE_LOCK(l) pthread_mutex_lock(l) +#define TLSF_RELEASE_LOCK(l) pthread_mutex_unlock(l) + +#endif diff --git a/src/tlsf-winnt.h b/src/tlsf-winnt.h new file mode 100644 index 0000000000000000000000000000000000000000..118c0080e91b4f3c26ba786ae153bca680b1c3cd --- /dev/null +++ b/src/tlsf-winnt.h @@ -0,0 +1,84 @@ +/* Heap management routines (including unexec) for NetRunner on Windows NT. + +This file was taken from GNU Emacs. +Copyright (C) 1994, 2001, 2002, 2003, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. +*/ + +#ifndef NTHEAP_H_ +#define NTHEAP_H_ + +#include <windows.h> + +#define ROUND_UP(p, align) (((DWORD)(p) + (align)-1) & ~((align)-1)) +#define ROUND_DOWN(p, align) ((DWORD)(p) & ~((align)-1)) + +/* + * Heap related stuff. + */ +#define get_reserved_heap_size() reserved_heap_size +#define get_committed_heap_size() (get_data_end () - get_data_start ()) +#define get_heap_start() get_data_start () +#define get_heap_end() get_data_end () +#define get_page_size() nt_sysinfo.dwPageSize +#define get_allocation_unit() nt_sysinfo.dwAllocationGranularity +#define get_processor_type() nt_sysinfo.dwProcessorType +#define get_w32_major_version() nt_major_version +#define get_w32_minor_version() nt_minor_version + +extern unsigned char *get_data_start(); +extern unsigned char *get_data_end(); +extern unsigned long reserved_heap_size; +extern SYSTEM_INFO nt_sysinfo; +extern OSVERSIONINFO nt_apilevel; +extern BOOL using_dynamic_heap; +extern int nt_major_version; +extern int nt_minor_version; +extern int nt_build_number; + +enum { + OS_WIN95 = 1, + OS_NT +}; + +extern int os_subtype; + +/* Emulation of Unix sbrk(). */ +extern void *sbrk (unsigned long size); + +/* Initialize heap structures for sbrk on startup. */ +extern void init_heap (); + +/* Round the heap to this size. */ +extern void round_heap (unsigned long size); + +/* Cache system info, e.g., the NT page size. */ +extern void cache_system_info (void); + +/* ----------------------------------------------------------------- */ +/* Useful routines for manipulating memory-mapped files. */ + +typedef struct file_data { + char *name; + unsigned long size; + HANDLE file; + HANDLE file_mapping; + unsigned char *file_base; +} file_data; + +int open_input_file (file_data *p_file, char *name); +int open_output_file (file_data *p_file, char *name, unsigned long size); +void close_file_data (file_data *p_file); + +/* Return pointer to section header for named section. */ +IMAGE_SECTION_HEADER * find_section (char * name, IMAGE_NT_HEADERS * nt_header); + +/* Return pointer to section header for section containing the given + relative virtual address. */ +IMAGE_SECTION_HEADER * rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header); +#define RVA_TO_PTR(rva) ((unsigned char *)((DWORD)(rva) + (DWORD)GetModuleHandle(NULL))) +#ifndef VALBITS +#define VALBITS (32 - 3) +#endif +#define VALMASK ((((int) 1) << VALBITS) - 1) +#endif /* NTHEAP_H_ */ \ No newline at end of file diff --git a/src/tlsf.c b/src/tlsf.c new file mode 100644 index 0000000000000000000000000000000000000000..27651a847812398010d61e6ce7235aa49a8f1f93 --- /dev/null +++ b/src/tlsf.c @@ -0,0 +1,1236 @@ +#ifdef __cplusplus +extern "C" { +#endif +/* + * Two Levels Segregate Fit memory allocator (TLSF) + * Version 2.4.6 + * + * Written by Miguel Masmano Tello <mimastel@doctor.upv.es> + * + * Thanks to Ismael Ripoll for his suggestions and reviews + * + * Copyright (C) 2008, 2007, 2006, 2005, 2004 + * + * This code is released using a dual license strategy: GPL/LGPL + * You can choose the licence that better fits your requirements. + * + * Released under the terms of the GNU General Public License Version 2.0 + * Released under the terms of the GNU Lesser General Public License Version 2.1 + * + */ + +/* + * Code contributions: + * + * (Jul 28 2007) Herman ten Brugge <hermantenbrugge@home.nl>: + * + * - Add 64 bit support. It now runs on x86_64 and solaris64. + * - I also tested this on vxworks/32and solaris/32 and i386/32 processors. + * - Remove assembly code. I could not measure any performance difference + * on my core2 processor. This also makes the code more portable. + * - Moved defines/typedefs from tlsf.h to tlsf.c + * - Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to + * (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact + * that the minumum size is still sizeof + * (bhdr_t). + * - Changed all C++ comment style to C style. (// -> /.* ... *./) + * - Used ls_bit instead of ffs and ms_bit instead of fls. I did this to + * avoid confusion with the standard ffs function which returns + * different values. + * - Created set_bit/clear_bit fuctions because they are not present + * on x86_64. + * - Added locking support + extra file target.h to show how to use it. + * - Added get_used_size function (REMOVED in 2.4) + * - Added rtl_realloc and rtl_calloc function + * - Implemented realloc clever support. + * - Added some test code in the example directory. + * - Bug fixed (discovered by the rockbox project: www.rockbox.org). + * + * (Oct 23 2006) Adam Scislowicz: + * + * - Support for ARMv5 implemented + * + */ + +/*#define USE_SBRK (0) */ +/*#define USE_MMAP (0) */ + +#ifndef USE_PRINTF +#define USE_PRINTF (1) +#endif + +#include <string.h> + +#ifndef TLSF_USE_LOCKS +#define TLSF_USE_LOCKS (0) +#endif + +#ifndef TLSF_STATISTIC +#define TLSF_STATISTIC (0) +#endif + +#ifndef USE_MMAP +#define USE_MMAP (0) +#endif + +#ifndef USE_SBRK +#define USE_SBRK (0) +#endif + + +#if TLSF_USE_LOCKS +#include "target.h" +#else +#define TLSF_CREATE_LOCK(_unused_) do{}while(0) +#define TLSF_DESTROY_LOCK(_unused_) do{}while(0) +#define TLSF_ACQUIRE_LOCK(_unused_) do{}while(0) +#define TLSF_RELEASE_LOCK(_unused_) do{}while(0) +#endif + +#if TLSF_STATISTIC +#define TLSF_ADD_SIZE(tlsf, b) do { \ + tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ + if (tlsf->used_size > tlsf->max_size) \ + tlsf->max_size = tlsf->used_size; \ + } while(0) + +#define TLSF_REMOVE_SIZE(tlsf, b) do { \ + tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ + } while(0) +#else +#define TLSF_ADD_SIZE(tlsf, b) do{}while(0) +#define TLSF_REMOVE_SIZE(tlsf, b) do{}while(0) +#endif + +#ifndef _WIN32 +#if USE_MMAP || USE_SBRK +#include <unistd.h> +#endif +#endif + +#ifndef _WIN32 +#if USE_MMAP +#include <sys/mman.h> +#endif +#endif + +#include "tlsf.h" + +#if !defined(__GNUC__) +#ifndef __inline__ +#define __inline__ +#endif +#endif + +#ifdef USE_PRINTF +#include <stdio.h> +# define PRINT_MSG(fmt, args...) printf(fmt, ## args) +# define ERROR_MSG(fmt, args...) printf(fmt, ## args) +#else +# if !defined(PRINT_MSG) +# define PRINT_MSG(fmt, args...) +# endif +# if !defined(ERROR_MSG) +# define ERROR_MSG(fmt, args...) +# endif +#endif + +/* The debug functions only can be used when _DEBUG_TLSF_ is set. */ +#ifndef _DEBUG_TLSF_ +#define _DEBUG_TLSF_ (0) +#endif + +#if defined(_WIN32) +#include "tlsf-winnt.h" +BOOL using_dynamic_heap = TRUE; +SYSTEM_INFO nt_sysinfo; +OSVERSIONINFO nt_apilevel; +unsigned long syspage_mask = 0; +/* The major and minor versions of NT. */ +int nt_major_version; +int nt_minor_version; +int nt_build_number; +/* Distinguish between Windows NT and Windows 95. +No longer used, as legacy DOS+Windows+Win32s is dead and buried. */ +int os_subtype; +/* Cache information describing the NT system for later use. */ +void +cache_system_info (void) +{ + union + { + struct info + { + char major; + char minor; + short platform; + } info; + DWORD data; + } version; + + /* Cache the version of the operating system. */ + version.data = GetVersion (); + nt_major_version = version.info.major; + nt_minor_version = version.info.minor; + + /* These days, it will ALWAYS fall through */ + if (version.info.platform & 0x8000) + os_subtype = OS_WIN95; + else + os_subtype = OS_NT; + + /* Cache page size, allocation unit, processor type, etc. */ + GetSystemInfo(&nt_sysinfo); + syspage_mask = nt_sysinfo.dwPageSize - 1; + + /* Cache os info. */ + nt_apilevel.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + GetVersionEx(&nt_apilevel); + + nt_build_number = nt_apilevel.dwBuildNumber; + /* possibly dead code */ + if (os_subtype == OS_WIN95) + nt_build_number &= 0xffff; +} + +#ifndef _WIN64 +int getpagesize() +{ + return nt_sysinfo.dwPageSize; +} +#endif +/* Info for managing our preload heap, which is essentially a fixed size + data area in the executable. */ +PIMAGE_SECTION_HEADER preload_heap_section; + +/* Info for keeping track of our heap. */ +unsigned char *data_region_base = NULL; +unsigned char *data_region_end = NULL; +unsigned char *real_data_region_end = NULL; +unsigned long reserved_heap_size = 0; + +/* The start of the data segment. */ +unsigned char * +get_data_start (void) +{ + return data_region_base; +} + +/* The end of the data segment. */ +unsigned char * +get_data_end (void) +{ + return data_region_end; +} + +static char* +allocate_heap (void) +{ + /* Try to get as much as possible of the address range from the end of + the preload heap section up to the usable address limit. Since GNU + malloc can handle gaps in the memory it gets from sbrk, we can + simply set the sbrk pointer to the base of the new heap region. */ + unsigned long base = + ROUND_UP ((RVA_TO_PTR (preload_heap_section->VirtualAddress) + + preload_heap_section->Misc.VirtualSize), + get_allocation_unit ()); + unsigned long end = 1 << VALBITS; /* 512MB */ + void *ptr = NULL; + + while (!ptr && (base < end)) + { + reserved_heap_size = end - base; + ptr = VirtualAlloc ((void *) base, + get_reserved_heap_size (), + MEM_RESERVE, + PAGE_NOACCESS); + base += 0x00100000; /* 1MB increment */ + } + + return ptr; +} + +/* Emulate Unix sbrk. */ +void * +sbrk (unsigned long increment) +{ + void *result; + long size = (long) increment; + + result = data_region_end; + + /* If size is negative, shrink the heap by decommitting pages. */ + if (size < 0) + { + int new_size; + unsigned char *new_data_region_end; + + size = -size; + + /* Sanity checks. */ + if ((data_region_end - size) < data_region_base) + return NULL; + + /* We can only decommit full pages, so allow for + partial deallocation [cga]. */ + new_data_region_end = (data_region_end - size); + new_data_region_end = (unsigned char *) + ((long) (new_data_region_end + syspage_mask) & ~syspage_mask); + new_size = real_data_region_end - new_data_region_end; + real_data_region_end = new_data_region_end; + if (new_size > 0) + { + /* Decommit size bytes from the end of the heap. */ + if (using_dynamic_heap + && !VirtualFree (real_data_region_end, new_size, MEM_DECOMMIT)) + return NULL; + } + + data_region_end -= size; + } + /* If size is positive, grow the heap by committing reserved pages. */ + else if (size > 0) + { + /* Sanity checks. */ + if ((data_region_end + size) > + (data_region_base + get_reserved_heap_size ())) + return NULL; + + /* Commit more of our heap. */ + if (using_dynamic_heap + && VirtualAlloc (data_region_end, size, MEM_COMMIT, + PAGE_READWRITE) == NULL) + return NULL; + data_region_end += size; + + /* We really only commit full pages, so record where + the real end of committed memory is [cga]. */ + real_data_region_end = (unsigned char *) + ((long) (data_region_end + syspage_mask) & ~syspage_mask); + } + + return result; +} +void +init_heap () +{ + PIMAGE_DOS_HEADER dos_header; + PIMAGE_NT_HEADERS nt_header; + + dos_header = (PIMAGE_DOS_HEADER) RVA_TO_PTR (0); + nt_header = (PIMAGE_NT_HEADERS) (((unsigned long) dos_header) + + dos_header->e_lfanew); + /* this isn't emacs, try allocating from the app stub */ + preload_heap_section = 0x400000; /* should change to 64K instead */ + data_region_base = allocate_heap (); + if (!data_region_base) + { + PRINT_MSG("Error: Could not reserve dynamic heap area.\n"); + exit (1); + } + data_region_end = data_region_base; + real_data_region_end = data_region_end; + + /* Update system version information to match current system. */ + cache_system_info (); +} + +/* Round the heap up to the given alignment. */ +void +round_heap (unsigned long align) +{ + unsigned long needs_to_be; + unsigned long need_to_alloc; + + needs_to_be = (unsigned long) ROUND_UP (get_heap_end (), align); + need_to_alloc = needs_to_be - (unsigned long) get_heap_end (); + + if (need_to_alloc) + sbrk (need_to_alloc); +} + +#endif + +/*************************************************************************/ +/* Definition of the structures used by TLSF */ + + +/* Some IMPORTANT TLSF parameters */ +/* Unlike the preview TLSF versions, now they are statics */ +#define BLOCK_ALIGN (sizeof(void *) * 2) + +#define MAX_FLI (30) +#define MAX_LOG2_SLI (5) +#define MAX_SLI (1 << MAX_LOG2_SLI) /* MAX_SLI = 2^MAX_LOG2_SLI */ + +#define FLI_OFFSET (6) /* tlsf structure just will manage blocks bigger */ +/* than 128 bytes */ +#define SMALL_BLOCK (128) +#define REAL_FLI (MAX_FLI - FLI_OFFSET) +#define MIN_BLOCK_SIZE (sizeof (free_ptr_t)) +#define BHDR_OVERHEAD (sizeof (bhdr_t) - MIN_BLOCK_SIZE) +#define TLSF_SIGNATURE (0x2A59FA59) + +#define PTR_MASK (sizeof(void *) - 1) +#define BLOCK_SIZE (0xFFFFFFFF - PTR_MASK) + +#define GET_NEXT_BLOCK(_addr, _r) ((bhdr_t *) ((char *) (_addr) + (_r))) +#define MEM_ALIGN ((BLOCK_ALIGN) - 1) +#define ROUNDUP_SIZE(_r) (((_r) + MEM_ALIGN) & ~MEM_ALIGN) +#define ROUNDDOWN_SIZE(_r) ((_r) & ~MEM_ALIGN) +#define ROUNDUP(_x, _v) ((((~(_x)) + 1) & ((_v)-1)) + (_x)) + +#define BLOCK_STATE (0x1) +#define PREV_STATE (0x2) + +/* bit 0 of the block size */ +#define FREE_BLOCK (0x1) +#define USED_BLOCK (0x0) + +/* bit 1 of the block size */ +#define PREV_FREE (0x2) +#define PREV_USED (0x0) + + +#define DEFAULT_AREA_SIZE (1024*10) + +#ifdef USE_MMAP +#define PAGE_SIZE (getpagesize()) +#endif + +typedef unsigned int u32_t; /* NOTE: Make sure that this type is 4 bytes long on your computer */ +typedef unsigned char u8_t; /* NOTE: Make sure that this type is 1 byte on your computer */ + +typedef struct free_ptr_struct { + struct bhdr_struct *prev; + struct bhdr_struct *next; +} free_ptr_t; + +typedef struct bhdr_struct { + /* This pointer is just valid if the first bit of size is set */ + struct bhdr_struct *prev_hdr; + /* The size is stored in bytes */ + size_t size; /* bit 0 indicates whether the block is used and */ + /* bit 1 allows to know whether the previous block is free */ + union { + struct free_ptr_struct free_ptr; + u8_t buffer[1]; /*sizeof(struct free_ptr_struct)]; */ + } ptr; +} bhdr_t; + +/* This structure is embedded at the beginning of each area, giving us + * enough information to cope with a set of areas */ + +typedef struct area_info_struct { + bhdr_t *end; + struct area_info_struct *next; +} area_info_t; + +typedef struct TLSF_struct { + /* the TLSF's structure signature */ + u32_t tlsf_signature; + +#if TLSF_USE_LOCKS + TLSF_MLOCK_T lock; +#endif + +#if TLSF_STATISTIC + /* These can not be calculated outside tlsf because we + * do not know the sizes when freeing/reallocing memory. */ + size_t used_size; + size_t max_size; +#endif + + /* A linked list holding all the existing areas */ + area_info_t *area_head; + + /* the first-level bitmap */ + /* This array should have a size of REAL_FLI bits */ + u32_t fl_bitmap; + + /* the second-level bitmap */ + u32_t sl_bitmap[REAL_FLI]; + + bhdr_t *matrix[REAL_FLI][MAX_SLI]; +} tlsf_t; + + +/******************************************************************/ +/************** Helping functions **************************/ +/******************************************************************/ +static __inline__ void set_bit(int nr, u32_t * addr); +static __inline__ void clear_bit(int nr, u32_t * addr); +static __inline__ int ls_bit(int x); +static __inline__ int ms_bit(int x); +static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl); +static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl); +static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl); +static __inline__ bhdr_t *process_area(void *area, size_t size); +#if USE_SBRK || USE_MMAP +static __inline__ void *get_new_area(size_t * size); +#endif + +static const int table[] = { + -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, + 4, 4, + 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, + 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, + 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, + 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, + 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, + 7, 7, 7, 7, 7, 7, 7 +}; + +static __inline__ int ls_bit(int i) +{ + unsigned int a; + unsigned int x = i & -i; + + a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24); + return table[x >> a] + a; +} + +static __inline__ int ms_bit(int i) +{ + unsigned int a; + unsigned int x = (unsigned int) i; + + a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24); + return table[x >> a] + a; +} + +static __inline__ void set_bit(int nr, u32_t * addr) +{ + addr[nr >> 5] |= 1 << (nr & 0x1f); +} + +static __inline__ void clear_bit(int nr, u32_t * addr) +{ + addr[nr >> 5] &= ~(1 << (nr & 0x1f)); +} + +static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl) +{ + int _t; + + if (*_r < SMALL_BLOCK) { + *_fl = 0; + *_sl = *_r / (SMALL_BLOCK / MAX_SLI); + } else { + _t = (1 << (ms_bit(*_r) - MAX_LOG2_SLI)) - 1; + *_r = *_r + _t; + *_fl = ms_bit(*_r); + *_sl = (*_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI; + *_fl -= FLI_OFFSET; + /*if ((*_fl -= FLI_OFFSET) < 0) // FL wil be always >0! + *_fl = *_sl = 0; + */ + *_r &= ~_t; + } +} + +static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl) +{ + if (_r < SMALL_BLOCK) { + *_fl = 0; + *_sl = _r / (SMALL_BLOCK / MAX_SLI); + } else { + *_fl = ms_bit(_r); + *_sl = (_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI; + *_fl -= FLI_OFFSET; + } +} + + +static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl) +{ + u32_t _tmp = _tlsf->sl_bitmap[*_fl] & (~0 << *_sl); + bhdr_t *_b = NULL; + + if (_tmp) { + *_sl = ls_bit(_tmp); + _b = _tlsf->matrix[*_fl][*_sl]; + } else { + *_fl = ls_bit(_tlsf->fl_bitmap & (~0 << (*_fl + 1))); + if (*_fl > 0) { /* likely */ + *_sl = ls_bit(_tlsf->sl_bitmap[*_fl]); + _b = _tlsf->matrix[*_fl][*_sl]; + } + } + return _b; +} + + +#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do { \ + _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next; \ + if (_tlsf -> matrix[_fl][_sl]) \ + _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL; \ + else { \ + clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ + if (!_tlsf -> sl_bitmap [_fl]) \ + clear_bit (_fl, &_tlsf -> fl_bitmap); \ + } \ + _b -> ptr.free_ptr.prev = NULL; \ + _b -> ptr.free_ptr.next = NULL; \ + }while(0) + + +#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do { \ + if (_b -> ptr.free_ptr.next) \ + _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \ + if (_b -> ptr.free_ptr.prev) \ + _b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \ + if (_tlsf -> matrix [_fl][_sl] == _b) { \ + _tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next; \ + if (!_tlsf -> matrix [_fl][_sl]) { \ + clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]); \ + if (!_tlsf -> sl_bitmap [_fl]) \ + clear_bit (_fl, &_tlsf -> fl_bitmap); \ + } \ + } \ + _b -> ptr.free_ptr.prev = NULL; \ + _b -> ptr.free_ptr.next = NULL; \ + } while(0) + +#define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do { \ + _b -> ptr.free_ptr.prev = NULL; \ + _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \ + if (_tlsf -> matrix [_fl][_sl]) \ + _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b; \ + _tlsf -> matrix [_fl][_sl] = _b; \ + set_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ + set_bit (_fl, &_tlsf -> fl_bitmap); \ + } while(0) + +#if USE_SBRK || USE_MMAP +static __inline__ void *get_new_area(size_t * size) +{ + void *area; + +#if USE_SBRK + area = (void *)sbrk(0); + if (((void *)sbrk(*size)) != ((void *) -1)) + return area; +#endif + +#ifndef MAP_ANONYMOUS +/* https://dev.openwrt.org/ticket/322 */ +# define MAP_ANONYMOUS MAP_ANON +#endif + + +#if USE_MMAP + *size = ROUNDUP(*size, PAGE_SIZE); + if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) + return area; +#endif + return ((void *) ~0); +} +#endif + +static __inline__ bhdr_t *process_area(void *area, size_t size) +{ + bhdr_t *b, *lb, *ib; + area_info_t *ai; + + ib = (bhdr_t *) area; + ib->size = + (sizeof(area_info_t) < + MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(sizeof(area_info_t)) | USED_BLOCK | PREV_USED; + b = (bhdr_t *) GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE); + b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED; + b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0; + lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); + lb->prev_hdr = b; + lb->size = 0 | USED_BLOCK | PREV_FREE; + ai = (area_info_t *) ib->ptr.buffer; + ai->next = 0; + ai->end = lb; + return ib; +} + +/******************************************************************/ +/******************** Begin of the allocator code *****************/ +/******************************************************************/ + +static char *mp = NULL; /* Default memory pool. */ + +/******************************************************************/ +size_t init_memory_pool(size_t mem_pool_size, void *mem_pool) +{ +/******************************************************************/ + tlsf_t *tlsf; + bhdr_t *b, *ib; + + if (!mem_pool || !mem_pool_size || mem_pool_size < sizeof(tlsf_t) + BHDR_OVERHEAD * 8) { + ERROR_MSG("init_memory_pool (): memory_pool invalid\n"); + return -1; + } + + if (((unsigned long) mem_pool & PTR_MASK)) { + ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n"); + return -1; + } + tlsf = (tlsf_t *) mem_pool; + /* Check if already initialised */ + if (tlsf->tlsf_signature == TLSF_SIGNATURE) { + mp = mem_pool; + b = GET_NEXT_BLOCK(mp, ROUNDUP_SIZE(sizeof(tlsf_t))); + return b->size & BLOCK_SIZE; + } + + mp = mem_pool; + + /* Zeroing the memory pool */ + memset(mem_pool, 0, sizeof(tlsf_t)); + + tlsf->tlsf_signature = TLSF_SIGNATURE; + + TLSF_CREATE_LOCK(&tlsf->lock); + + ib = process_area(GET_NEXT_BLOCK + (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t))); + b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE); + free_ex(b->ptr.buffer, tlsf); + tlsf->area_head = (area_info_t *) ib->ptr.buffer; + +#if TLSF_STATISTIC + tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE); + tlsf->max_size = tlsf->used_size; +#endif + + return (b->size & BLOCK_SIZE); +} + +/******************************************************************/ +size_t add_new_area(void *area, size_t area_size, void *mem_pool) +{ +/******************************************************************/ + tlsf_t *tlsf = (tlsf_t *) mem_pool; + area_info_t *ptr, *ptr_prev, *ai; + bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b; + + memset(area, 0, area_size); + ptr = tlsf->area_head; + ptr_prev = 0; + + ib0 = process_area(area, area_size); + b0 = GET_NEXT_BLOCK(ib0->ptr.buffer, ib0->size & BLOCK_SIZE); + lb0 = GET_NEXT_BLOCK(b0->ptr.buffer, b0->size & BLOCK_SIZE); + + /* Before inserting the new area, we have to merge this area with the + already existing ones */ + + while (ptr) { + ib1 = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD); + b1 = GET_NEXT_BLOCK(ib1->ptr.buffer, ib1->size & BLOCK_SIZE); + lb1 = ptr->end; + + /* Merging the new area with the next physically contigous one */ + if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) { + if (tlsf->area_head == ptr) { + tlsf->area_head = ptr->next; + ptr = ptr->next; + } else { + ptr_prev->next = ptr->next; + ptr = ptr->next; + } + + b0->size = + ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) + + (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED; + + b1->prev_hdr = b0; + lb0 = lb1; + + continue; + } + + /* Merging the new area with the previous physically contigous + one */ + if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) { + if (tlsf->area_head == ptr) { + tlsf->area_head = ptr->next; + ptr = ptr->next; + } else { + ptr_prev->next = ptr->next; + ptr = ptr->next; + } + + lb1->size = + ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) + + (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE); + next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE); + next_b->prev_hdr = lb1; + b0 = lb1; + ib0 = ib1; + + continue; + } + ptr_prev = ptr; + ptr = ptr->next; + } + + /* Inserting the area in the list of linked areas */ + ai = (area_info_t *) ib0->ptr.buffer; + ai->next = tlsf->area_head; + ai->end = lb0; + tlsf->area_head = ai; + free_ex(b0->ptr.buffer, mem_pool); + return (b0->size & BLOCK_SIZE); +} + + +/******************************************************************/ +size_t get_used_size(void *mem_pool) +{ +/******************************************************************/ +#if TLSF_STATISTIC + return ((tlsf_t *) mem_pool)->used_size; +#else + return 0; +#endif +} + +/******************************************************************/ +size_t get_max_size(void *mem_pool) +{ +/******************************************************************/ +#if TLSF_STATISTIC + return ((tlsf_t *) mem_pool)->max_size; +#else + return 0; +#endif +} + +/******************************************************************/ +void destroy_memory_pool(void *mem_pool) +{ +/******************************************************************/ + tlsf_t *tlsf = (tlsf_t *) mem_pool; + + tlsf->tlsf_signature = 0; + + TLSF_DESTROY_LOCK(&tlsf->lock); + +} + + +/******************************************************************/ +void *tlsf_malloc(size_t size) +{ +/******************************************************************/ + void *ret; + +#if USE_MMAP || USE_SBRK + if (!mp) { + size_t area_size; + void *area; + + area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */ + area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE; + area = get_new_area(&area_size); + if (area == ((void *) ~0)) + return NULL; /* Not enough system memory */ + init_memory_pool(area_size, area); + } +#endif + + TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock); + + ret = malloc_ex(size, mp); + + TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock); + + return ret; +} + +/******************************************************************/ +void tlsf_free(void *ptr) +{ +/******************************************************************/ + + TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock); + + free_ex(ptr, mp); + + TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock); + +} + +/******************************************************************/ +void *tlsf_realloc(void *ptr, size_t size) +{ +/******************************************************************/ + void *ret; + +#if USE_MMAP || USE_SBRK + if (!mp) { + return tlsf_malloc(size); + } +#endif + + TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock); + + ret = realloc_ex(ptr, size, mp); + + TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock); + + return ret; +} + +/******************************************************************/ +void *tlsf_calloc(size_t nelem, size_t elem_size) +{ +/******************************************************************/ + void *ret; + + TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock); + + ret = calloc_ex(nelem, elem_size, mp); + + TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock); + + return ret; +} + +/******************************************************************/ +void *malloc_ex(size_t size, void *mem_pool) +{ +/******************************************************************/ + tlsf_t *tlsf = (tlsf_t *) mem_pool; + bhdr_t *b, *b2, *next_b; + int fl, sl; + size_t tmp_size; + + size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size); + + /* Rounding up the requested size and calculating fl and sl */ + MAPPING_SEARCH(&size, &fl, &sl); + + /* Searching a free block, recall that this function changes the values of fl and sl, + so they are not longer valid when the function fails */ + b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl); +#if USE_MMAP || USE_SBRK + if (!b) { + size_t area_size; + void *area; + /* Growing the pool size when needed */ + area_size = size + BHDR_OVERHEAD * 8; /* size plus enough room for the requered headers. */ + area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE; + area = get_new_area(&area_size); /* Call sbrk or mmap */ + if (area == ((void *) ~0)) + return NULL; /* Not enough system memory */ + add_new_area(area, area_size, mem_pool); + /* Rounding up the requested size and calculating fl and sl */ + MAPPING_SEARCH(&size, &fl, &sl); + /* Searching a free block */ + b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl); + } +#endif + if (!b) + return NULL; /* Not found */ + + EXTRACT_BLOCK_HDR(b, tlsf, fl, sl); + + /*-- found: */ + next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); + /* Should the block be split? */ + tmp_size = (b->size & BLOCK_SIZE) - size; + if (tmp_size >= sizeof(bhdr_t)) { + tmp_size -= BHDR_OVERHEAD; + b2 = GET_NEXT_BLOCK(b->ptr.buffer, size); + b2->size = tmp_size | FREE_BLOCK | PREV_USED; + next_b->prev_hdr = b2; + MAPPING_INSERT(tmp_size, &fl, &sl); + INSERT_BLOCK(b2, tlsf, fl, sl); + + b->size = size | (b->size & PREV_STATE); + } else { + next_b->size &= (~PREV_FREE); + b->size &= (~FREE_BLOCK); /* Now it's used */ + } + + TLSF_ADD_SIZE(tlsf, b); + + return (void *) b->ptr.buffer; +} + +/******************************************************************/ +void free_ex(void *ptr, void *mem_pool) +{ +/******************************************************************/ + tlsf_t *tlsf = (tlsf_t *) mem_pool; + bhdr_t *b, *tmp_b; + int fl = 0, sl = 0; + + if (!ptr) { + return; + } + b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD); + b->size |= FREE_BLOCK; + + TLSF_REMOVE_SIZE(tlsf, b); + + b->ptr.free_ptr.prev = NULL; + b->ptr.free_ptr.next = NULL; + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); + if (tmp_b->size & FREE_BLOCK) { + MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl); + EXTRACT_BLOCK(tmp_b, tlsf, fl, sl); + b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; + } + if (b->size & PREV_FREE) { + tmp_b = b->prev_hdr; + MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl); + EXTRACT_BLOCK(tmp_b, tlsf, fl, sl); + tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; + b = tmp_b; + } + MAPPING_INSERT(b->size & BLOCK_SIZE, &fl, &sl); + INSERT_BLOCK(b, tlsf, fl, sl); + + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); + tmp_b->size |= PREV_FREE; + tmp_b->prev_hdr = b; +} + +/******************************************************************/ +void *realloc_ex(void *ptr, size_t new_size, void *mem_pool) +{ +/******************************************************************/ + tlsf_t *tlsf = (tlsf_t *) mem_pool; + void *ptr_aux; + unsigned int cpsize; + bhdr_t *b, *tmp_b, *next_b; + int fl, sl; + size_t tmp_size; + + if (!ptr) { + if (new_size) + return (void *) malloc_ex(new_size, mem_pool); + if (!new_size) + return NULL; + } else if (!new_size) { + free_ex(ptr, mem_pool); + return NULL; + } + + b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD); + next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); + new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size); + tmp_size = (b->size & BLOCK_SIZE); + if (new_size <= tmp_size) { + TLSF_REMOVE_SIZE(tlsf, b); + if (next_b->size & FREE_BLOCK) { + MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl); + EXTRACT_BLOCK(next_b, tlsf, fl, sl); + tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; + next_b = GET_NEXT_BLOCK(next_b->ptr.buffer, next_b->size & BLOCK_SIZE); + /* We allways reenter this free block because tmp_size will + be greater then sizeof (bhdr_t) */ + } + tmp_size -= new_size; + if (tmp_size >= sizeof(bhdr_t)) { + tmp_size -= BHDR_OVERHEAD; + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size); + tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED; + next_b->prev_hdr = tmp_b; + next_b->size |= PREV_FREE; + MAPPING_INSERT(tmp_size, &fl, &sl); + INSERT_BLOCK(tmp_b, tlsf, fl, sl); + b->size = new_size | (b->size & PREV_STATE); + } + TLSF_ADD_SIZE(tlsf, b); + return (void *) b->ptr.buffer; + } + if ((next_b->size & FREE_BLOCK)) { + if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) { + TLSF_REMOVE_SIZE(tlsf, b); + MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl); + EXTRACT_BLOCK(next_b, tlsf, fl, sl); + b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; + next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); + next_b->prev_hdr = b; + next_b->size &= ~PREV_FREE; + tmp_size = (b->size & BLOCK_SIZE) - new_size; + if (tmp_size >= sizeof(bhdr_t)) { + tmp_size -= BHDR_OVERHEAD; + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size); + tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED; + next_b->prev_hdr = tmp_b; + next_b->size |= PREV_FREE; + MAPPING_INSERT(tmp_size, &fl, &sl); + INSERT_BLOCK(tmp_b, tlsf, fl, sl); + b->size = new_size | (b->size & PREV_STATE); + } + TLSF_ADD_SIZE(tlsf, b); + return (void *) b->ptr.buffer; + } + } + + if (!(ptr_aux = malloc_ex(new_size, mem_pool))){ + return NULL; + } + + cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE); + + memcpy(ptr_aux, ptr, cpsize); + + free_ex(ptr, mem_pool); + return ptr_aux; +} + + +/******************************************************************/ +void *calloc_ex(size_t nelem, size_t elem_size, void *mem_pool) +{ +/******************************************************************/ + void *ptr; + + if (nelem <= 0 || elem_size <= 0) + return NULL; + + if (!(ptr = malloc_ex(nelem * elem_size, mem_pool))) + return NULL; + memset(ptr, 0, nelem * elem_size); + + return ptr; +} + + + +#if _DEBUG_TLSF_ + +/*************** DEBUG FUNCTIONS **************/ + +/* The following functions have been designed to ease the debugging of */ +/* the TLSF structure. For non-developing purposes, it may be they */ +/* haven't too much worth. To enable them, _DEBUG_TLSF_ must be set. */ + +extern void dump_memory_region(unsigned char *mem_ptr, unsigned int size); +extern void print_block(bhdr_t * b); +extern void print_tlsf(tlsf_t * tlsf); +void print_all_blocks(tlsf_t * tlsf); + +void dump_memory_region(unsigned char *mem_ptr, unsigned int size) +{ + + unsigned long begin = (unsigned long) mem_ptr; + unsigned long end = (unsigned long) mem_ptr + size; + int column = 0; + + begin >>= 2; + begin <<= 2; + + end >>= 2; + end++; + end <<= 2; + + PRINT_MSG("\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end); + + column = 0; + PRINT_MSG("0x%lx ", begin); + + while (begin < end) { + if (((unsigned char *) begin)[0] == 0) + PRINT_MSG("00"); + else + PRINT_MSG("%02x", ((unsigned char *) begin)[0]); + if (((unsigned char *) begin)[1] == 0) + PRINT_MSG("00 "); + else + PRINT_MSG("%02x ", ((unsigned char *) begin)[1]); + begin += 2; + column++; + if (column == 8) { + PRINT_MSG("\n0x%lx ", begin); + column = 0; + } + + } + PRINT_MSG("\n\n"); +} + +void print_block(bhdr_t * b) +{ + if (!b) + return; + PRINT_MSG(">> [%p] (", b); + if ((b->size & BLOCK_SIZE)) + PRINT_MSG("%lu bytes, ", (unsigned long) (b->size & BLOCK_SIZE)); + else + PRINT_MSG("sentinel, "); + if ((b->size & BLOCK_STATE) == FREE_BLOCK) + PRINT_MSG("free [%p, %p], ", b->ptr.free_ptr.prev, b->ptr.free_ptr.next); + else + PRINT_MSG("used, "); + if ((b->size & PREV_STATE) == PREV_FREE) + PRINT_MSG("prev. free [%p])\n", b->prev_hdr); + else + PRINT_MSG("prev used)\n"); +} + +void print_tlsf(tlsf_t * tlsf) +{ + bhdr_t *next; + int i, j; + + PRINT_MSG("\nTLSF at %p\n", tlsf); + + PRINT_MSG("FL bitmap: 0x%x\n\n", (unsigned) tlsf->fl_bitmap); + + for (i = 0; i < REAL_FLI; i++) { + if (tlsf->sl_bitmap[i]) + PRINT_MSG("SL bitmap 0x%x\n", (unsigned) tlsf->sl_bitmap[i]); + for (j = 0; j < MAX_SLI; j++) { + next = tlsf->matrix[i][j]; + if (next) + PRINT_MSG("-> [%d][%d]\n", i, j); + while (next) { + print_block(next); + next = next->ptr.free_ptr.next; + } + } + } +} + +void print_all_blocks(tlsf_t * tlsf) +{ + area_info_t *ai; + bhdr_t *next; + PRINT_MSG("\nTLSF at %p\nALL BLOCKS\n\n", tlsf); + ai = tlsf->area_head; + while (ai) { + next = (bhdr_t *) ((char *) ai - BHDR_OVERHEAD); + while (next) { + print_block(next); + if ((next->size & BLOCK_SIZE)) + next = GET_NEXT_BLOCK(next->ptr.buffer, next->size & BLOCK_SIZE); + else + next = NULL; + } + ai = ai->next; + } +} + +#endif +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/tlsf.h b/src/tlsf.h new file mode 100644 index 0000000000000000000000000000000000000000..610f4fd9dfc9b17cc2d1f8f5140ec3c350c14513 --- /dev/null +++ b/src/tlsf.h @@ -0,0 +1,44 @@ +/* + * Two Levels Segregate Fit memory allocator (TLSF) + * Version 2.4.6 + * + * Written by Miguel Masmano Tello <mimastel@doctor.upv.es> + * + * Thanks to Ismael Ripoll for his suggestions and reviews + * + * Copyright (C) 2008, 2007, 2006, 2005, 2004 + * + * This code is released using a dual license strategy: GPL/LGPL + * You can choose the licence that better fits your requirements. + * + * Released under the terms of the GNU General Public License Version 2.0 + * Released under the terms of the GNU Lesser General Public License Version 2.1 + * + */ + +#ifndef _TLSF_H_ +#define _TLSF_H_ +#ifdef __cplusplus +extern "C" { +#endif +#include <sys/types.h> + +extern size_t init_memory_pool(size_t, void *); +extern size_t get_used_size(void *); +extern size_t get_max_size(void *); +extern void destroy_memory_pool(void *); +extern size_t add_new_area(void *, size_t, void *); +extern void *malloc_ex(size_t, void *); +extern void free_ex(void *, void *); +extern void *realloc_ex(void *, size_t, void *); +extern void *calloc_ex(size_t, size_t, void *); + +extern void *tlsf_malloc(size_t size); +extern void tlsf_free(void *ptr); +extern void *tlsf_realloc(void *ptr, size_t size); +extern void *tlsf_calloc(size_t nelem, size_t elem_size); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/winnt-ci.sh b/winnt-ci.sh new file mode 100644 index 0000000000000000000000000000000000000000..bdab0f23a161272b94893fa414cbd9fec9f1bc0b --- /dev/null +++ b/winnt-ci.sh @@ -0,0 +1,20 @@ +#!/usr/bin/sh +if [ $MSYSTEM == "MINGW32" ] +then + make -fNTMakeFile +else + make -fNTMakefile AMD64=1 +fi +strip -s netrunner.exe +[ -e 'bin' ] || mkdir bin +mv *.pnm bin 2> /dev/null +mv *.crt bin 2> /dev/null +mv *.ttf bin 2> /dev/null +if [ $MSYSTEM == "MINGW32" ] +then + cp reltools/winnt/i386/*.dll bin +else + cp reltools/winnt/amd64/*.dll bin +fi +mv LICENSE bin +mv netrunner.exe bin \ No newline at end of file