aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2017-08-12 21:57:15 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2017-08-12 21:57:15 +0800
commitad144ad2e4220dcbf678c515e4670c094413ea6d (patch)
tree830a273bfd288f828167c5445ba15bcd1050c98e
parentaa867dd6770e7956ff08bff55639a4f4d1d74910 (diff)
downloaddexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.tar
dexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.tar.gz
dexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.tar.bz2
dexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.tar.lz
dexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.tar.xz
dexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.tar.zst
dexon-bls-ad144ad2e4220dcbf678c515e4670c094413ea6d.zip
add blsInitThreadSafe
-rw-r--r--Makefile1
-rw-r--r--include/bls/bls.h4
-rw-r--r--src/bls_c.cpp17
-rw-r--r--test/bls_c384_test.cpp40
4 files changed, 62 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index f798e71..1260ed7 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ LIB_DIR=lib
OBJ_DIR=obj
EXE_DIR=bin
CFLAGS += -std=c++11
+LDFLAGS += -lpthread
SRC_SRC=bls.cpp bls_c.cpp
TEST_SRC=bls_test.cpp bls_c384_test.cpp
diff --git a/include/bls/bls.h b/include/bls/bls.h
index f063ca6..2a9df84 100644
--- a/include/bls/bls.h
+++ b/include/bls/bls.h
@@ -50,6 +50,10 @@ typedef struct {
@note init() is not thread safe
*/
BLS_DLL_API int blsInit(int curve, int maxUnitSize);
+/*
+ wait for the finish of the first call blsInit() and do nothing
+*/
+BLS_DLL_API int blsInitThreadSafe(int curve, int maxUnitSize);
BLS_DLL_API size_t blsGetOpUnitSize(void);
// return strlen(buf) if success else 0
diff --git a/src/bls_c.cpp b/src/bls_c.cpp
index ccdc909..563ecc9 100644
--- a/src/bls_c.cpp
+++ b/src/bls_c.cpp
@@ -36,6 +36,23 @@ int blsInit(int curve, int maxUnitSize)
return -1;
}
+#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
+#include <mutex>
+static std::mutex g_mutex;
+static int g_curve = -1;
+
+int blsInitThreadSafe(int curve, int maxUnitSize)
+{
+ int ret = 0;
+ std::lock_guard<std::mutex> lock(g_mutex);
+ if (g_curve != curve) {
+ ret = blsInit(curve, maxUnitSize);
+ g_curve = curve;
+ }
+ return ret;
+}
+#endif
+
static inline const mclBnG1 *cast(const G1* x) { return (const mclBnG1*)x; }
static inline const mclBnG2 *cast(const G2* x) { return (const mclBnG2*)x; }
diff --git a/test/bls_c384_test.cpp b/test/bls_c384_test.cpp
index 8c3761f..2e61e2c 100644
--- a/test/bls_c384_test.cpp
+++ b/test/bls_c384_test.cpp
@@ -62,6 +62,46 @@ void blsOrderTest(const char *curveOrder, const char *fieldOrder)
CYBOZU_TEST_EQUAL(buf, fieldOrder);
}
+#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
+#include <thread>
+#include <vector>
+struct Thread {
+ std::unique_ptr<std::thread> t;
+ Thread() : t() {}
+ ~Thread()
+ {
+ if (t) {
+ t->join();
+ }
+ }
+ template<class F>
+ void run(F func, int p1, int p2)
+ {
+ t.reset(new std::thread(func, p1, p2));
+ }
+};
+CYBOZU_TEST_AUTO(multipleInit)
+{
+ const size_t n = 100;
+ {
+ std::vector<Thread> vt(n);
+ for (size_t i = 0; i < n; i++) {
+ vt[i].run(blsInitThreadSafe, mclBn_CurveFp254BNb, MCLBN_FP_UNIT_SIZE);
+ }
+ }
+ CYBOZU_TEST_EQUAL(blsGetOpUnitSize(), 4u);
+#if MCLBN_FP_UNIT_SIZE == 6
+ {
+ std::vector<Thread> vt(n);
+ for (size_t i = 0; i < n; i++) {
+ vt[i].run(blsInitThreadSafe, mclBn_CurveFp382_1, MCLBN_FP_UNIT_SIZE);
+ }
+ }
+ CYBOZU_TEST_EQUAL(blsGetOpUnitSize(), 6u);
+#endif
+}
+#endif
+
CYBOZU_TEST_AUTO(all)
{
const int tbl[] = {