diff --git a/README.md b/README.md index 066c45e4..cd6d876e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Extremely efficient object serialization library. It's like JSON, but very fast ## What's MessagePack? -MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small. +**MessagePack** is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small. Typical small integer (like flags or error code) is saved only in 1 byte, and typical short string only needs 1 byte except the length of the string itself. \[1,2,3\] (3 elements array) is serialized in 4 bytes using MessagePack as follows: @@ -13,25 +13,30 @@ Typical small integer (like flags or error code) is saved only in 1 byte, and ty msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03" MessagePack.unpack(msg) #=> [1,2,3] +**MessagePack-RPC** is cross-language RPC library for client, server and cluster applications. Because it releases you from complicated network programming completely and provides well-designed API, you can easily implement advanced network applications with MessagePack-RPC. -## Performance + require 'msgpack/rpc' + class MyHandler + def add(x,y) return x+y end + end + svr = MessagePack::RPC::Server.new + svr.listen('0.0.0.0', 18800, MyHandler.new) + svr.run -![Serialization + Deserialization Speed Test](http://msgpack.sourceforge.net/index/speedtest.png) - -In this test, it measured the elapsed time of serializing and deserializing 200,000 target objects. The target object consists of the three integers and 512 bytes string. -The source code of this test is available from [frsyuki' serializer-speed-test repository.](http://github.com/frsyuki/serializer-speed-test) + require 'msgpack/rpc' + c = MessagePack::RPC::Client.new('127.0.0.1',18800) + result = c.call(:add, 1, 2) #=> 3 ## Getting Started -Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.sourceforge.net/) +Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.org/) ## Learn More - - [Project Web Site](http://msgpack.sourceforge.net/) - - [MessagePack format specification](http://msgpack.sourceforge.net/spec) - - [Repository at github](http://github.com/msgpack/msgpack) - - [Wiki](http://msgpack.sourceforge.net/start) - - [MessagePack-RPC](http://github.com/msgpack/msgpack-rpc) + - [Web Site](http://msgpack.org/) + - [Wiki](http://wiki.msgpack.org/display/MSGPACK/Home) + - [Issues](http://jira.msgpack.org/browse/MSGPACK) + - [Sources](https://github.com/msgpack) diff --git a/cpp/configure.in b/cpp/configure.in index 95635c3c..b05f9183 100644 --- a/cpp/configure.in +++ b/cpp/configure.in @@ -16,7 +16,7 @@ AC_PROG_CC AC_MSG_CHECKING([if C++ API is enabled]) AC_ARG_ENABLE(cxx, AS_HELP_STRING([--disable-cxx], - [don't build C++ API]) ) + [don't build C++ API]) ) #' AC_MSG_RESULT([$enable_cxx]) if test "$enable_cxx" != "no"; then AC_PROG_CXX @@ -50,17 +50,41 @@ AC_CACHE_CHECK([for __sync_* atomic operations], msgpack_cv_atomic_ops, [ ], [], msgpack_cv_atomic_ops="yes") ]) if test "$msgpack_cv_atomic_ops" != "yes"; then - AC_MSG_ERROR([__sync_* atomic operations are not supported. + if test "$enable_cxx" = "no"; then + AC_MSG_ERROR([__sync_* atomic operations are not found. Try to enable C++ support. +If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to +add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows: -Note that gcc < 4.1 is not supported. + $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686" + ]) + fi + + AC_LANG_PUSH([C++]) + AC_CACHE_CHECK([for __gnu_cxx::__exchange_and_add], msgpack_cv_gcc_cxx_atomic_ops, [ + AC_TRY_LINK([ + #include + int atomic_sub(int i) { return __gnu_cxx::__exchange_and_add(&i, -1); } + int atomic_add(int i) { return __gnu_cxx::__exchange_and_add(&i, 1); } + ], [], msgpack_cv_gcc_cxx_atomic_ops="yes") + ]) + AC_LANG_POP([C++]) + + if test "$msgpack_cv_gcc_cxx_atomic_ops" != "yes"; then + AC_MSG_ERROR([__sync_* atomic operations nor __gnu_cxx::__exchange_and_add are not found. If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows: $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686" ]) + + else + enable_gcc_cxx_atomic=yes + fi fi +AM_CONDITIONAL(ENABLE_GCC_CXX_ATOMIC, test "$enable_gcc_cxx_atomic" = "yes") + major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am index 0979d235..4a5dae26 100644 --- a/cpp/src/Makefile.am +++ b/cpp/src/Makefile.am @@ -13,6 +13,12 @@ libmsgpack_la_SOURCES += \ object.cpp endif +if ENABLE_GCC_CXX_ATOMIC +libmsgpack_la_SOURCES += \ + gcc_atomic.cpp +endif + + # -version-info CURRENT:REVISION:AGE libmsgpack_la_LDFLAGS = -version-info 3:0:0 diff --git a/cpp/src/gcc_atomic.cpp b/cpp/src/gcc_atomic.cpp new file mode 100644 index 00000000..599e832b --- /dev/null +++ b/cpp/src/gcc_atomic.cpp @@ -0,0 +1,17 @@ +#if defined(__GNUC__) && ((__GNUC__*10 + __GNUC_MINOR__) < 41) + +#include "gcc_atomic.h" +#include + +int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr) +{ + return __gnu_cxx::__exchange_and_add(ptr, -1); +} + +int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr) +{ + return __gnu_cxx::__exchange_and_add(ptr, 1); +} + + +#endif // old gcc workaround diff --git a/cpp/src/gcc_atomic.h b/cpp/src/gcc_atomic.h new file mode 100644 index 00000000..842a48fb --- /dev/null +++ b/cpp/src/gcc_atomic.h @@ -0,0 +1,33 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MSGPACK_GCC_ATOMIC_H__ +#define MSGPACK_GCC_ATOMIC_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef int _msgpack_atomic_counter_t; + +int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr); +int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr); + + +#if defined(__cplusplus) +} +#endif + + +#endif // MSGPACK_GCC_ATOMIC_H__ diff --git a/java/ivy.xml b/java/ivy.xml index 2c8b727f..18ebe08e 100644 --- a/java/ivy.xml +++ b/java/ivy.xml @@ -3,7 +3,7 @@ - + MessagePack diff --git a/msgpack/sysdep.h b/msgpack/sysdep.h index 557c7cd6..b21dc009 100644 --- a/msgpack/sysdep.h +++ b/msgpack/sysdep.h @@ -36,19 +36,19 @@ typedef unsigned __int64 uint64_t; #include #endif - #ifdef _WIN32 #define _msgpack_atomic_counter_header typedef long _msgpack_atomic_counter_t; #define _msgpack_sync_decr_and_fetch(ptr) InterlockedDecrement(ptr) #define _msgpack_sync_incr_and_fetch(ptr) InterlockedIncrement(ptr) +#elif defined(__GNUC__) && ((__GNUC__*10 + __GNUC_MINOR__) < 41) +#define _msgpack_atomic_counter_header "gcc_atomic.h" #else typedef unsigned int _msgpack_atomic_counter_t; #define _msgpack_sync_decr_and_fetch(ptr) __sync_sub_and_fetch(ptr, 1) #define _msgpack_sync_incr_and_fetch(ptr) __sync_add_and_fetch(ptr, 1) #endif - #ifdef _WIN32 #ifdef __cplusplus @@ -141,9 +141,25 @@ typedef unsigned int _msgpack_atomic_counter_t; do { uint64_t val = _msgpack_be64(num); memcpy(to, &val, 8); } while(0) -#define _msgpack_load16(cast, from) ((cast)_msgpack_be16(*(uint16_t*)from)) -#define _msgpack_load32(cast, from) ((cast)_msgpack_be32(*(uint32_t*)from)) -#define _msgpack_load64(cast, from) ((cast)_msgpack_be64(*(uint64_t*)from)) +#define _msgpack_load16(cast, from) ((cast)_msgpack_be16( \ + (((uint8_t*)from)[1] << 8) | ((uint8_t*)from)[0])) + +#define _msgpack_load32(cast, from) ((cast)_msgpack_be32( \ + (((uint8_t*)from)[3] << 24) | \ + (((uint8_t*)from)[2] << 16) | \ + (((uint8_t*)from)[1] << 8) | \ + (((uint8_t*)from)[0] ) )) + +#define _msgpack_load64(cast, from) ((cast)_msgpack_be64( \ + (((uint64_t)(((uint8_t*)from)[7])) << 56) | \ + (((uint64_t)(((uint8_t*)from)[6])) << 48) | \ + (((uint64_t)(((uint8_t*)from)[5])) << 40) | \ + (((uint64_t)(((uint8_t*)from)[4])) << 32) | \ + (((uint64_t)((uint8_t*)from)[3]) << 24) | \ + (((uint64_t)((uint8_t*)from)[2]) << 16) | \ + (((uint64_t)((uint8_t*)from)[1]) << 8) | \ + (((uint8_t*)from)[0] ))) + #endif /* msgpack/sysdep.h */ diff --git a/php/README b/php/README index ac8e4857..6e22a92d 100644 --- a/php/README +++ b/php/README @@ -8,4 +8,4 @@ But unlike JSON, it is very fast and small. Resources --------- - * [msgpack](http://msgpack.sourceforge.net/) + * [msgpack](http://msgpack.org/) diff --git a/python/ChangeLog.rst b/python/ChangeLog.rst index a0aae257..10ddf4f0 100644 --- a/python/ChangeLog.rst +++ b/python/ChangeLog.rst @@ -4,7 +4,7 @@ New feature ----------- -* Add ``encoding`` and ``unicode_erros`` option to packer and unpacker. +* Add ``encoding`` and ``unicode_errors`` option to packer and unpacker. When this option is specified, (un)packs unicode object instead of bytes. This enables using msgpack as a replacement of json. diff --git a/ruby/msgpack.gemspec b/ruby/msgpack.gemspec index 95a2bd0a..942c4bb0 100644 --- a/ruby/msgpack.gemspec +++ b/ruby/msgpack.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.summary = "MessagePack, a binary-based efficient data interchange format." s.author = "FURUHASHI Sadayuki" s.email = "frsyuki@users.sourceforge.jp" - s.homepage = "http://msgpack.sourceforge.net/" + s.homepage = "http://msgpack.org/" s.rubyforge_project = "msgpack" s.has_rdoc = true s.rdoc_options = ["ext"]