[Sheepdog] [PATCH] accord: Added acrd_tx_atomic_inc
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Thu Nov 10 08:34:04 CET 2011
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.
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
More information about the sheepdog
mailing list