Permalink
Browse files

lring: initial

  • Loading branch information...
1 parent 061f207 commit 2d95a1b416940f5f1530f58c4089d008d05a7e11 @indutny committed Oct 12, 2012
View
@@ -41,7 +41,7 @@ node_g: config.gypi out/Makefile
ln -fs out/Debug/node $@
endif
-out/Makefile: common.gypi deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/common.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
+out/Makefile: common.gypi deps/lring/lring.gyp deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/common.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
ifeq ($(USE_NINJA),1)
touch out/Makefile
$(PYTHON) tools/gyp_node -f ninja
View
@@ -0,0 +1,2 @@
+build/
+out/
View
@@ -0,0 +1,42 @@
+# Lock-less ring
+
+Lock-less One-producer-one-consumer ring in C.
+
+## Example
+
+```C
+char data[1024];
+lring_t ring;
+
+lring_init(&ring);
+
+lring_write(&ring, data, sizeof(data));
+ssize_t bytes_read = lring_read(&ring, data, sizeof(data));
+
+lring_destroy(&ring);
+```
+
+### License
+
+This software is licensed under the MIT License.
+
+Copyright Fedor Indutny, 2012.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
View
@@ -0,0 +1,183 @@
+{
+ 'variables': {
+ 'visibility%': 'hidden', # V8's visibility setting
+ 'target_arch%': 'ia32', # set v8's target architecture
+ 'host_arch%': 'ia32', # set v8's host architecture
+ 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
+ 'component%': 'static_library', # NB. these names match with what V8 expects
+ 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
+ 'gcc_version%': 'unknown',
+ 'clang%': 0,
+ },
+
+ 'target_defaults': {
+ 'default_configuration': 'Debug',
+ 'configurations': {
+ 'Debug': {
+ 'defines': [ 'DEBUG', '_DEBUG' ],
+ 'cflags': [ '-g', '-O0' ],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'target_conditions': [
+ ['library=="static_library"', {
+ 'RuntimeLibrary': 1, # static debug
+ }, {
+ 'RuntimeLibrary': 3, # DLL debug
+ }],
+ ],
+ 'Optimization': 0, # /Od, no optimization
+ 'MinimalRebuild': 'false',
+ 'OmitFramePointers': 'false',
+ 'BasicRuntimeChecks': 3, # /RTC1
+ },
+ 'VCLinkerTool': {
+ 'LinkIncremental': 2, # enable incremental linking
+ },
+ },
+ 'xcode_settings': {
+ 'GCC_OPTIMIZATION_LEVEL': '0',
+ },
+ 'conditions': [
+ ['OS != "win"', {
+ 'defines': [ 'EV_VERIFY=2' ],
+ }],
+ ]
+ },
+ 'Release': {
+ 'defines': [ 'NDEBUG' ],
+ 'cflags': [ '-O3', '-fomit-frame-pointer', '-fdata-sections', '-ffunction-sections' ],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'target_conditions': [
+ ['library=="static_library"', {
+ 'RuntimeLibrary': 0, # static release
+ }, {
+ 'RuntimeLibrary': 2, # debug release
+ }],
+ ],
+ 'Optimization': 3, # /Ox, full optimization
+ 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
+ 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
+ 'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
+ 'OmitFramePointers': 'true',
+ 'EnableFunctionLevelLinking': 'true',
+ 'EnableIntrinsicFunctions': 'true',
+ },
+ 'VCLibrarianTool': {
+ 'AdditionalOptions': [
+ '/LTCG', # link time code generation
+ ],
+ },
+ 'VCLinkerTool': {
+ 'LinkTimeCodeGeneration': 1, # link-time code generation
+ 'OptimizeReferences': 2, # /OPT:REF
+ 'EnableCOMDATFolding': 2, # /OPT:ICF
+ 'LinkIncremental': 1, # disable incremental linking
+ },
+ },
+ }
+ },
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'StringPooling': 'true', # pool string literals
+ 'DebugInformationFormat': 3, # Generate a PDB
+ 'WarningLevel': 3,
+ 'BufferSecurityCheck': 'true',
+ 'ExceptionHandling': 1, # /EHsc
+ 'SuppressStartupBanner': 'true',
+ 'WarnAsError': 'false',
+ 'AdditionalOptions': [
+ '/MP', # compile across multiple CPUs
+ ],
+ },
+ 'VCLibrarianTool': {
+ },
+ 'VCLinkerTool': {
+ 'GenerateDebugInformation': 'true',
+ 'RandomizedBaseAddress': 2, # enable ASLR
+ 'DataExecutionPrevention': 2, # enable DEP
+ 'AllowIsolation': 'true',
+ 'SuppressStartupBanner': 'true',
+ 'target_conditions': [
+ ['_type=="executable"', {
+ 'SubSystem': 1, # console executable
+ }],
+ ],
+ },
+ },
+ 'conditions': [
+ ['OS == "win"', {
+ 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
+ 'defines': [
+ 'WIN32',
+ # we don't really want VC++ warning us about
+ # how dangerous C functions are...
+ '_CRT_SECURE_NO_DEPRECATE',
+ # ... or that C implementations shouldn't use
+ # POSIX names
+ '_CRT_NONSTDC_NO_DEPRECATE',
+ ],
+ 'target_conditions': [
+ ['target_arch=="x64"', {
+ 'msvs_configuration_platform': 'x64'
+ }]
+ ]
+ }],
+ [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ 'cflags': [ '-Wall' ],
+ 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
+ 'conditions': [
+ [ 'host_arch != target_arch and target_arch=="ia32"', {
+ 'cflags': [ '-m32' ],
+ 'ldflags': [ '-m32' ],
+ }],
+ [ 'OS=="linux"', {
+ 'cflags': [ '-ansi' ],
+ }],
+ [ 'OS=="solaris"', {
+ 'cflags': [ '-pthreads' ],
+ 'ldflags': [ '-pthreads' ],
+ }, {
+ 'cflags': [ '-pthread' ],
+ 'ldflags': [ '-pthread' ],
+ }],
+ [ 'visibility=="hidden" and (clang==1 or gcc_version >= 40)', {
+ 'cflags': [ '-fvisibility=hidden' ],
+ }],
+ ],
+ }],
+ ['OS=="mac"', {
+ 'xcode_settings': {
+ 'ALWAYS_SEARCH_USER_PATHS': 'NO',
+ 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
+ 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
+ # (Equivalent to -fPIC)
+ 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
+ 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
+ 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
+ # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
+ 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
+ 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
+ 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
+ 'PREBINDING': 'NO', # No -Wl,-prebind
+ 'USE_HEADERMAP': 'NO',
+ 'OTHER_CFLAGS': [
+ '-fno-strict-aliasing',
+ ],
+ 'WARNING_CFLAGS': [
+ '-Wall',
+ '-Wendif-labels',
+ '-W',
+ '-Wno-unused-parameter',
+ ],
+ },
+ 'target_conditions': [
+ ['_type!="static_library"', {
+ 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
+ }],
+ ],
+ }],
+ ],
+ },
+}
View
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+
+import glob
+import os
+import subprocess
+import sys
+
+CC = os.environ.get('CC', 'cc')
+script_dir = os.path.dirname(__file__)
+lring_root = os.path.normpath(script_dir)
+output_dir = os.path.join(os.path.abspath(lring_root), 'out')
+
+sys.path.insert(0, os.path.join(lring_root, 'build', 'gyp', 'pylib'))
+try:
+ import gyp
+except ImportError:
+ print('You need to install gyp in build/gyp first. See the README.')
+ sys.exit(42)
+
+
+def compiler_version():
+ proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
+ is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
+ proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
+ version = proc.communicate()[0].split('.')
+ version = map(int, version[:2])
+ version = tuple(version)
+ return (version, is_clang)
+
+
+def run_gyp(args):
+ rc = gyp.main(args)
+ if rc != 0:
+ print 'Error running GYP'
+ sys.exit(rc)
+
+
+if __name__ == '__main__':
+ args = sys.argv[1:]
+
+ # GYP bug.
+ # On msvs it will crash if it gets an absolute path.
+ # On Mac/make it will crash if it doesn't get an absolute path.
+ if sys.platform == 'win32':
+ args.append(os.path.join(lring_root, 'lring.gyp'))
+ common_fn = os.path.join(lring_root, 'common.gypi')
+ options_fn = os.path.join(lring_root, 'options.gypi')
+ # we force vs 2010 over 2008 which would otherwise be the default for gyp
+ if not os.environ.get('GYP_MSVS_VERSION'):
+ os.environ['GYP_MSVS_VERSION'] = '2010'
+ else:
+ args.append(os.path.join(os.path.abspath(lring_root), 'lring.gyp'))
+ common_fn = os.path.join(os.path.abspath(lring_root), 'common.gypi')
+ options_fn = os.path.join(os.path.abspath(lring_root), 'options.gypi')
+
+ if os.path.exists(common_fn):
+ args.extend(['-I', common_fn])
+
+ if os.path.exists(options_fn):
+ args.extend(['-I', options_fn])
+
+ args.append('--depth=' + lring_root)
+
+ # There's a bug with windows which doesn't allow this feature.
+ if sys.platform != 'win32':
+ if '-f' not in args:
+ args.extend('-f make'.split())
+ if 'ninja' not in args:
+ args.extend(['-Goutput_dir=' + output_dir])
+ args.extend(['--generator-output', output_dir])
+ (major, minor), is_clang = compiler_version()
+ args.append('-Dgcc_version=%d' % (10 * major + minor))
+ args.append('-Dclang=%d' % int(is_clang))
+
+ if not any(a.startswith('-Dtarget_arch') for a in args):
+ args.append('-Dtarget_arch=ia32')
+
+ if not any(a.startswith('-Dlibrary') for a in args):
+ args.append('-Dlibrary=static_library')
+
+ args.append('-Dcomponent=static_library')
+
+ gyp_args = list(args)
+ print gyp_args
+ run_gyp(gyp_args)
View
@@ -0,0 +1,55 @@
+#ifndef _INCLUDE_LRING_H_
+#define _INCLUDE_LRING_H_
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct lring_s lring_t;
+typedef struct lring_page_s lring_page_t;
+
+struct lring_page_s {
+ lring_page_t* next;
+ volatile ssize_t roffset;
+ volatile ssize_t woffset;
+ char data[10 * 1024];
+};
+
+struct lring_s {
+ lring_page_t head;
+ lring_page_t* rhead;
+ lring_page_t* whead;
+ volatile ssize_t total;
+};
+
+/* Initialize ring */
+void lring_init(lring_t* ring);
+
+/* Deinitialize ring (won't free memory) */
+void lring_destroy(lring_t* ring);
+
+/* Returns current size of the ring */
+ssize_t lring_size(lring_t* ring);
+
+/* Put data into ring */
+void lring_write(lring_t* ring, const char* data, ssize_t size);
+
+/*
+ * Read at maximum `size` data from the ring,
+ * returns actual amount of data that was read.
+ * (NOTE: if `data` is NULL, lring_read will just flush that data).
+ */
+ssize_t lring_read(lring_t* ring, char* data, ssize_t size);
+
+/*
+ * Read data from ring without dequeuing it
+ * (Works exactly like `lring_read`)
+ */
+ssize_t lring_peek(lring_t* ring, char* data, ssize_t size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _INCLUDE_LRING_H_ */
Oops, something went wrong.

0 comments on commit 2d95a1b

Please sign in to comment.