Skip to content

Commit

Permalink
lring: initial
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny committed Oct 12, 2012
1 parent 061f207 commit 2d95a1b
Show file tree
Hide file tree
Showing 15 changed files with 1,079 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions deps/lring/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
out/
42 changes: 42 additions & 0 deletions deps/lring/README.md
Original file line number Diff line number Diff line change
@@ -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.
183 changes: 183 additions & 0 deletions deps/lring/common.gypi
Original file line number Diff line number Diff line change
@@ -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']},
}],
],
}],
],
},
}
85 changes: 85 additions & 0 deletions deps/lring/gyp_lring
Original file line number Diff line number Diff line change
@@ -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)
55 changes: 55 additions & 0 deletions deps/lring/include/lring.h
Original file line number Diff line number Diff line change
@@ -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_ */
Loading

0 comments on commit 2d95a1b

Please sign in to comment.