(11/11/10 16:34), MORITA Kazutaka wrote: > At Wed, 09 Nov 2011 18:06:32 +0900, > OZAWA Tsuyoshi wrote: >> >> The combination of cmp() and the other operations can simulate >> atomic increment operations, however it can occur performance problem. >> The new operation, atomic_inc(), can solve it. >> >> Signed-off-by: OZAWA Tsuyoshi<ozawa.tsuyoshi at lab.ntt.co.jp> >> --- >> conductor/acrdops.c | 48 >> ++++++++++++++++++++++++++++++++++++++++++++++++ >> include/accord.h | 3 +++ >> include/accord_proto.h | 1 + >> libacrd/libacrd.c | 7 +++++++ >> test/test-txn.c | 39 +++++++++++++++++++++++++++++++++++++++ >> 5 files changed, 98 insertions(+), 0 deletions(-) > > This patch is malformed. Try using git send-email next time. Okey, thank you for your pointing out my mistake. Thanks, Tsuyoshi > Thanks, > > Kazutaka > >> >> diff --git a/conductor/acrdops.c b/conductor/acrdops.c >> index 8ec950d..ecfa04e 100644 >> --- a/conductor/acrdops.c >> +++ b/conductor/acrdops.c >> @@ -155,6 +155,50 @@ static int exec_del_req(const struct acrd_req *req, >> struct acrd_rsp **rsp, >> return ret; >> } >> >> +static int exec_atomic_inc_req(const struct acrd_req *req, struct >> acrd_rsp **rsp, >> + struct acrd_txid *txid, struct client_info *from) >> +{ >> + int ret = 0; >> + void *data; >> + const void *adddata; >> + const char *path; >> + uint32_t size; >> + uint32_t d32, v; >> + >> + path = get_arg(req, 0)->data; >> + adddata = get_arg(req, 1)->data; >> + size = get_arg(req, 1)->size; >> + dprintf("hogehoge %s %d\n", path, size); >> + >> + if (size != sizeof(uint32_t)) >> + goto err; >> + >> + if (likely(path)) >> + ret = store_read(path,&data,&size, req->offset, txid); >> + else >> + ret = ACRD_ERR_UNKNOWN; >> + >> + if (ret != ACRD_SUCCESS) >> + goto err; >> + >> + if (size != sizeof(uint32_t)) >> + goto err; >> + >> + v = *(uint32_t *) adddata; >> + d32 = *(uint32_t *)data; >> + d32 += v; >> + ret = store_write(path,&d32, size, req->offset, req->flags, txid); >> + >> + if (rsp) >> + (*rsp)->result = ret; >> + >> + return ret; >> +err: >> + if (rsp) >> + (*rsp)->result = ret; >> + return ret; >> +} >> + >> static int exec_cmp_req(const struct acrd_req *req, struct acrd_rsp **rsp, >> struct acrd_txid *txid, struct client_info *from) >> { >> @@ -536,6 +580,10 @@ static struct acrd_op_tmpl acrd_ops[] = { >> .exec_req = exec_copy_req, >> .notify_event = notify_copy_event, >> }, { >> + .opcode = ACRD_OP_ATOMIC_INC, >> + .need_mcast = 1, >> + .exec_req = exec_atomic_inc_req, >> + }, { >> .opcode = ACRD_OP_TX, >> .need_mcast = 1, >> .exec_req = exec_tx_req, >> diff --git a/include/accord.h b/include/accord.h >> index 9a040f1..3fff476 100644 >> --- a/include/accord.h >> +++ b/include/accord.h >> @@ -375,6 +375,9 @@ int acrd_tx_scmp(struct acrd_tx *tx, const char >> *path1, const char *path2, >> int acrd_tx_copy(struct acrd_tx *tx, const char *src, const char *dst, >> uint32_t flags); >> >> +int acrd_tx_atomic_inc(struct acrd_tx *tx, const char *path, const void >> *buf, >> + uint32_t count, uint32_t offset, uint32_t flags); >> + >> /** >> * Commit a transaction >> * >> diff --git a/include/accord_proto.h b/include/accord_proto.h >> index 455b2e8..861d623 100644 >> --- a/include/accord_proto.h >> +++ b/include/accord_proto.h >> @@ -18,6 +18,7 @@ enum OPERATION { >> ACRD_OP_CMP, >> ACRD_OP_SCMP, >> ACRD_OP_COPY, >> + ACRD_OP_ATOMIC_INC, >> ACRD_OP_LIST, >> ACRD_OP_ADD_WATCH, >> ACRD_OP_RM_WATCH, >> diff --git a/libacrd/libacrd.c b/libacrd/libacrd.c >> index a99c680..4249a86 100644 >> --- a/libacrd/libacrd.c >> +++ b/libacrd/libacrd.c >> @@ -610,6 +610,13 @@ int acrd_tx_copy(struct acrd_tx *tx, const char >> *src, const char *dst, >> strlen(dst) + 1, 0, 0, flags, NULL, NULL, NULL); >> } >> >> +int acrd_tx_atomic_inc(struct acrd_tx *tx, const char *path, const void >> *buf, >> + uint32_t count, uint32_t offset, uint32_t flags) >> +{ >> + return acrd_op(tx->handle, tx, ACRD_OP_ATOMIC_INC, path, strlen(path) >> + 1, buf, >> + count, 0, offset, flags, NULL, NULL, NULL); >> +} >> + >> int acrd_tx_commit(struct acrd_tx *tx, uint32_t flags) >> { >> struct acrd_aiocb *aiocb; >> diff --git a/test/test-txn.c b/test/test-txn.c >> index 562befd..57e3bdd 100644 >> --- a/test/test-txn.c >> +++ b/test/test-txn.c >> @@ -281,6 +281,43 @@ static void test_txn_increment(struct acrd_fixture >> *fixture, gconstpointer p) >> acrd_tx_close(tx); >> } >> >> +static void test_txn_ainc(struct acrd_fixture *fixture, gconstpointer p) >> +{ >> + struct acrd_handle *h = fixture->handle; >> + uint32_t data = 5555; >> + uint32_t newdata = 5556; >> + uint32_t *readdata; >> + uint32_t delta = 1; >> + char retdata[32]; >> + uint32_t retdata_len = sizeof(data); >> + int ret; >> + struct acrd_tx *tx; >> + >> + tx = acrd_tx_init(h); >> + g_assert(tx != NULL); >> + ret = acrd_tx_atomic_inc(tx, "/tmp/0",&delta, sizeof(uint32_t), 0, 0); >> + g_assert(ret == ACRD_SUCCESS); >> + ret = acrd_tx_commit(tx, 0); >> + g_assert(ret == ACRD_ERR_NOTFOUND); >> + acrd_tx_close(tx); >> + >> + ret = acrd_write(h, "/tmp/0",&data, sizeof(uint32_t), 0, >> ACRD_FLAG_CREATE); >> + g_assert(ret == ACRD_SUCCESS); >> + >> + tx = acrd_tx_init(h); >> + g_assert(tx != NULL); >> + ret = acrd_tx_atomic_inc(tx, "/tmp/0",&delta, sizeof(uint32_t), 0, 0); >> + g_assert(ret == ACRD_SUCCESS); >> + ret = acrd_tx_commit(tx, 0); >> + g_assert(ret == ACRD_SUCCESS); >> + acrd_tx_close(tx); >> + >> + ret = acrd_read(h, "/tmp/0",&retdata,&retdata_len, 0, ACRD_FLAG_CREATE); >> + g_assert(ret == ACRD_SUCCESS); >> + readdata = (uint32_t *)retdata; >> + g_assert(*readdata == newdata); >> +} >> + >> static void test_txn_merge(struct acrd_fixture *fixture, gconstpointer p) >> { >> struct acrd_handle *h = fixture->handle; >> @@ -406,6 +443,8 @@ int main(int argc, char **argv) >> test_txn_setup, test_txn_merge, test_txn_teardown); >> g_test_add("/txn/swap", struct acrd_fixture, NULL, >> test_txn_setup, test_txn_swap, test_txn_teardown); >> + g_test_add("/txn/ainc", struct acrd_fixture, NULL, >> + test_txn_setup, test_txn_ainc, test_txn_teardown); >> >> return g_test_run(); >> } >> -- >> 1.7.2.5 >> >> -- >> sheepdog mailing list >> sheepdog at lists.wpkg.org >> http://lists.wpkg.org/mailman/listinfo/sheepdog |