diff options
author | Craig Tiller <craig.tiller@gmail.com> | 2015-04-28 13:39:21 -0700 |
---|---|---|
committer | Craig Tiller <craig.tiller@gmail.com> | 2015-04-28 13:39:21 -0700 |
commit | 7e61d52d03954b98a1ea2645b2c43d6dfe655bba (patch) | |
tree | 609b0e88eae988784c23d662f23b2f444ae97129 | |
parent | bae41c847f084fe64b5920f09d7ffbac579c507a (diff) |
Faster stream_op_buffer swap
-rw-r--r-- | src/core/transport/stream_op.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/core/transport/stream_op.c b/src/core/transport/stream_op.c index e1a75adcb6..8996ecac35 100644 --- a/src/core/transport/stream_op.c +++ b/src/core/transport/stream_op.c @@ -59,15 +59,30 @@ void grpc_sopb_reset(grpc_stream_op_buffer *sopb) { } void grpc_sopb_swap(grpc_stream_op_buffer *a, grpc_stream_op_buffer *b) { - grpc_stream_op_buffer temp = *a; - *a = *b; - *b = temp; - - if (a->ops == b->inlined_ops) { + GPR_SWAP(size_t, a->nops, b->nops); + GPR_SWAP(size_t, a->capacity, b->capacity); + + if (a->ops == a->inlined_ops) { + if (b->ops == b->inlined_ops) { + /* swap contents of inlined buffer */ + gpr_slice temp[GRPC_SOPB_INLINE_ELEMENTS]; + memcpy(temp, a->ops, b->nops * sizeof(grpc_stream_op)); + memcpy(a->ops, b->ops, a->nops * sizeof(grpc_stream_op)); + memcpy(b->ops, temp, b->nops * sizeof(grpc_stream_op)); + } else { + /* a is inlined, b is not - copy a inlined into b, fix pointers */ + a->ops = b->ops; + b->ops = b->inlined_ops; + memcpy(b->ops, a->inlined_ops, b->nops * sizeof(grpc_stream_op)); + } + } else if (b->ops == b->inlined_ops) { + /* b is inlined, a is not - copy b inlined int a, fix pointers */ + b->ops = a->ops; a->ops = a->inlined_ops; - } - if (b->ops == a->inlined_ops) { - b->ops = b->inlined_ops; + memcpy(a->ops, b->inlined_ops, a->nops * sizeof(grpc_stream_op)); + } else { + /* no inlining: easy swap */ + GPR_SWAP(grpc_stream_op *, a->ops, b->ops); } } |