Skip to content
Open
15 changes: 9 additions & 6 deletions src/brpc/mongo_head.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@ struct mongo_head_t {
int32_t op_code; // request type, see MongoOpCode.

void make_host_endian() {
if (!ARCH_CPU_LITTLE_ENDIAN) {
message_length = butil::ByteSwap((uint32_t)message_length);
request_id = butil::ByteSwap((uint32_t)request_id);
response_to = butil::ByteSwap((uint32_t)response_to);
op_code = butil::ByteSwap((uint32_t)op_code);
}
#if !defined(ARCH_CPU_LITTLE_ENDIAN)
message_length = butil::ByteSwap((uint32_t)message_length);
request_id = butil::ByteSwap((uint32_t)request_id);
response_to = butil::ByteSwap((uint32_t)response_to);
op_code = butil::ByteSwap((uint32_t)op_code);
Comment thread
pkubaj marked this conversation as resolved.
Resolved
#endif
}
// The wire format is little-endian, so the conversion between it and the
// host byte order is the same swap in both directions.
void make_wire_endian() { make_host_endian(); }
};
#pragma pack()

Expand Down
2 changes: 2 additions & 0 deletions src/brpc/mongo_service_adaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class MongoServiceAdaptor {

// Make an error msg when the cntl fails. If cntl fails, we must send mongo client a msg not
// only to indicate the error, but also to finish the round trip.
// The msg must be in the wire format, which is little-endian on every
// host (mongo_head_t::make_wire_endian(), butil::ByteSwapToLE32()).
virtual void SerializeError(int response_to, butil::IOBuf* out_buf) const = 0;

// Create a custom context which is attached to socket. This func is called only when the first
Expand Down
30 changes: 17 additions & 13 deletions src/brpc/policy/mongo_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "butil/iobuf.h" // butil::IOBuf
#include "butil/strings/string_util.h"
#include "butil/sys_byteorder.h"
#include "butil/time.h"

#include "brpc/controller.h" // Controller
Expand Down Expand Up @@ -86,11 +87,13 @@ void SendMongoResponse::Run() {
res.header().response_to(),
res.header().op_code()
};
header.make_wire_endian();
res_buf.append(static_cast<const void*>(&header), sizeof(mongo_head_t));
int32_t response_flags = res.response_flags();
int64_t cursor_id = res.cursor_id();
int32_t starting_from = res.starting_from();
int32_t number_returned = res.number_returned();
// The wire format is little-endian.
const uint32_t response_flags = butil::ByteSwapToLE32(res.response_flags());
const uint64_t cursor_id = butil::ByteSwapToLE64(res.cursor_id());
const uint32_t starting_from = butil::ByteSwapToLE32(res.starting_from());
const uint32_t number_returned = butil::ByteSwapToLE32(res.number_returned());
res_buf.append(&response_flags, sizeof(response_flags));
res_buf.append(&cursor_id, sizeof(cursor_id));
res_buf.append(&starting_from, sizeof(starting_from));
Expand Down Expand Up @@ -200,7 +203,8 @@ void ProcessMongoRequest(InputMessageBase* msg_base) {

char buf[sizeof(mongo_head_t)];
const char *p = (const char *)msg->meta.fetch(buf, sizeof(buf));
const mongo_head_t *header = (const mongo_head_t*)p;
mongo_head_t header = *(const mongo_head_t*)p;
header.make_host_endian();

const google::protobuf::ServiceDescriptor* srv_des = MongoService::descriptor();
if (1 != srv_des->method_count()) {
Expand Down Expand Up @@ -280,20 +284,20 @@ void ProcessMongoRequest(InputMessageBase* msg_base) {
}
}

if (!MongoOp_IsValid(header->op_code)) {
mongo_done->cntl.SetFailed(EREQUEST, "Unknown op_code:%d", header->op_code);
if (!MongoOp_IsValid(header.op_code)) {
mongo_done->cntl.SetFailed(EREQUEST, "Unknown op_code:%d", header.op_code);
break;
}

mongo_done->cntl.set_log_id(header->request_id);
mongo_done->cntl.set_log_id(header.request_id);
const std::string &body_str = msg->payload.to_string();
mongo_done->req.set_message(body_str.c_str(), body_str.size());
mongo_done->req.mutable_header()->set_message_length(header->message_length);
mongo_done->req.mutable_header()->set_request_id(header->request_id);
mongo_done->req.mutable_header()->set_response_to(header->response_to);
mongo_done->req.mutable_header()->set_message_length(header.message_length);
mongo_done->req.mutable_header()->set_request_id(header.request_id);
mongo_done->req.mutable_header()->set_response_to(header.response_to);
mongo_done->req.mutable_header()->set_op_code(
static_cast<MongoOp>(header->op_code));
mongo_done->res.mutable_header()->set_response_to(header->request_id);
static_cast<MongoOp>(header.op_code));
mongo_done->res.mutable_header()->set_response_to(header.request_id);
mongo_done->received_us = msg->received_us();

google::protobuf::Service* svc = mp->service;
Expand Down
252 changes: 252 additions & 0 deletions src/bthread/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,3 +1012,255 @@ __asm (
" call _exit\n"
);
#endif

#if defined(BTHREAD_CONTEXT_PLATFORM_ppc64_elfv2) && defined(BTHREAD_CONTEXT_COMPILER_gcc)
__asm (
".text\n"
".align 2\n"
".machine push\n"
".machine altivec\n"
".globl bthread_jump_fcontext\n"
".type bthread_jump_fcontext, @function\n"
"bthread_jump_fcontext:\n"
" addis %r2, %r12, .TOC.-bthread_jump_fcontext@ha\n"
" addi %r2, %r2, .TOC.-bthread_jump_fcontext@l\n"
Comment thread
pkubaj marked this conversation as resolved.
Resolved
" .localentry bthread_jump_fcontext, . - bthread_jump_fcontext\n"
" # reserve space on stack\n"
" subi %r1, %r1, 528\n"
" std %r14, 352(%r1)\n"
" std %r15, 360(%r1)\n"
" std %r16, 368(%r1)\n"
" std %r17, 376(%r1)\n"
" std %r18, 384(%r1)\n"
" std %r19, 392(%r1)\n"
" std %r20, 400(%r1)\n"
" std %r21, 408(%r1)\n"
" std %r22, 416(%r1)\n"
" std %r23, 424(%r1)\n"
" std %r24, 432(%r1)\n"
" std %r25, 440(%r1)\n"
" std %r26, 448(%r1)\n"
" std %r27, 456(%r1)\n"
" std %r28, 464(%r1)\n"
" std %r29, 472(%r1)\n"
" std %r30, 480(%r1)\n"
" std %r31, 488(%r1)\n"
" # save CR\n"
" mfcr %r0\n"
" std %r0, 496(%r1)\n"
" # save LR, and LR as PC\n"
" mflr %r0\n"
" std %r0, 504(%r1)\n"
" std %r0, 512(%r1)\n"
" # the fourth argument (preserve_fpu) is ignored: the compiler may keep\n"
" # any value in the non-volatile FPRs/VRs across the call\n"
" stfd %f14, 200(%r1)\n"
" stfd %f15, 208(%r1)\n"
" stfd %f16, 216(%r1)\n"
" stfd %f17, 224(%r1)\n"
" stfd %f18, 232(%r1)\n"
" stfd %f19, 240(%r1)\n"
" stfd %f20, 248(%r1)\n"
" stfd %f21, 256(%r1)\n"
" stfd %f22, 264(%r1)\n"
" stfd %f23, 272(%r1)\n"
" stfd %f24, 280(%r1)\n"
" stfd %f25, 288(%r1)\n"
" stfd %f26, 296(%r1)\n"
" stfd %f27, 304(%r1)\n"
" stfd %f28, 312(%r1)\n"
" stfd %f29, 320(%r1)\n"
" stfd %f30, 328(%r1)\n"
" stfd %f31, 336(%r1)\n"
" mffs %f0\n"
" stfd %f0, 344(%r1)\n"
" mfspr %r0, 256\n"
" std %r0, 192(%r1)\n"
" li %r11, 0\n"
" stvx %v20, %r1, %r11\n"
" li %r11, 16\n"
" stvx %v21, %r1, %r11\n"
" li %r11, 32\n"
" stvx %v22, %r1, %r11\n"
" li %r11, 48\n"
" stvx %v23, %r1, %r11\n"
" li %r11, 64\n"
" stvx %v24, %r1, %r11\n"
" li %r11, 80\n"
" stvx %v25, %r1, %r11\n"
" li %r11, 96\n"
" stvx %v26, %r1, %r11\n"
" li %r11, 112\n"
" stvx %v27, %r1, %r11\n"
" li %r11, 128\n"
" stvx %v28, %r1, %r11\n"
" li %r11, 144\n"
" stvx %v29, %r1, %r11\n"
" li %r11, 160\n"
" stvx %v30, %r1, %r11\n"
" li %r11, 176\n"
" stvx %v31, %r1, %r11\n"
" # store RSP (pointing to context-data) in R3\n"
" std %r1, 0(%r3)\n"
" # restore RSP (pointing to context-data) from R4\n"
" mr %r1, %r4\n"
" li %r11, 0\n"
" lvx %v20, %r1, %r11\n"
" li %r11, 16\n"
" lvx %v21, %r1, %r11\n"
" li %r11, 32\n"
" lvx %v22, %r1, %r11\n"
" li %r11, 48\n"
" lvx %v23, %r1, %r11\n"
" li %r11, 64\n"
" lvx %v24, %r1, %r11\n"
" li %r11, 80\n"
" lvx %v25, %r1, %r11\n"
" li %r11, 96\n"
" lvx %v26, %r1, %r11\n"
" li %r11, 112\n"
" lvx %v27, %r1, %r11\n"
" li %r11, 128\n"
" lvx %v28, %r1, %r11\n"
" li %r11, 144\n"
" lvx %v29, %r1, %r11\n"
" li %r11, 160\n"
" lvx %v30, %r1, %r11\n"
" li %r11, 176\n"
" lvx %v31, %r1, %r11\n"
" ld %r0, 192(%r1)\n"
" mtspr 256, %r0\n"
" lfd %f0, 344(%r1)\n"
" mtfsf 0xff, %f0\n"
" lfd %f14, 200(%r1)\n"
" lfd %f15, 208(%r1)\n"
" lfd %f16, 216(%r1)\n"
" lfd %f17, 224(%r1)\n"
" lfd %f18, 232(%r1)\n"
" lfd %f19, 240(%r1)\n"
" lfd %f20, 248(%r1)\n"
" lfd %f21, 256(%r1)\n"
" lfd %f22, 264(%r1)\n"
" lfd %f23, 272(%r1)\n"
" lfd %f24, 280(%r1)\n"
" lfd %f25, 288(%r1)\n"
" lfd %f26, 296(%r1)\n"
" lfd %f27, 304(%r1)\n"
" lfd %f28, 312(%r1)\n"
" lfd %f29, 320(%r1)\n"
" lfd %f30, 328(%r1)\n"
" lfd %f31, 336(%r1)\n"
" ld %r14, 352(%r1)\n"
" ld %r15, 360(%r1)\n"
" ld %r16, 368(%r1)\n"
" ld %r17, 376(%r1)\n"
" ld %r18, 384(%r1)\n"
" ld %r19, 392(%r1)\n"
" ld %r20, 400(%r1)\n"
" ld %r21, 408(%r1)\n"
" ld %r22, 416(%r1)\n"
" ld %r23, 424(%r1)\n"
" ld %r24, 432(%r1)\n"
" ld %r25, 440(%r1)\n"
" ld %r26, 448(%r1)\n"
" ld %r27, 456(%r1)\n"
" ld %r28, 464(%r1)\n"
" ld %r29, 472(%r1)\n"
" ld %r30, 480(%r1)\n"
" ld %r31, 488(%r1)\n"
" # restore CR\n"
" ld %r0, 496(%r1)\n"
" mtcr %r0\n"
" # restore LR\n"
" ld %r0, 504(%r1)\n"
" mtlr %r0\n"
" # load PC into CTR (and R12 for the callee's TOC setup)\n"
" ld %r12, 512(%r1)\n"
" mtctr %r12\n"
" # adjust stack\n"
" addi %r1, %r1, 528\n"
" # use third arg as return value after jump\n"
" # and as first arg in context function\n"
" mr %r3, %r5\n"
" # jump to context\n"
" bctr\n"
".machine pop\n"
".size bthread_jump_fcontext, .-bthread_jump_fcontext\n"
".section .note.GNU-stack,\"\",%progbits\n"
Comment thread
pkubaj marked this conversation as resolved.
Resolved
".previous\n"
);

#endif

#if defined(BTHREAD_CONTEXT_PLATFORM_ppc64_elfv2) && defined(BTHREAD_CONTEXT_COMPILER_gcc)
__asm (
".text\n"
".align 2\n"
".machine push\n"
".machine altivec\n"
".globl bthread_make_fcontext\n"
".type bthread_make_fcontext, @function\n"
"bthread_make_fcontext:\n"
" addis %r2, %r12, .TOC.-bthread_make_fcontext@ha\n"
" addi %r2, %r2, .TOC.-bthread_make_fcontext@l\n"
Comment thread
pkubaj marked this conversation as resolved.
Resolved
" .localentry bthread_make_fcontext, . - bthread_make_fcontext\n"
" # save return address into R6\n"
" mflr %r6\n"
" # first arg of bthread_make_fcontext() == top address of context-stack\n"
" # shift address in R3 to lower 16 byte boundary\n"
" clrrdi %r3, %r3, 4\n"
" # reserve space for context-data on context-stack\n"
" # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n"
" subi %r3, %r3, 592\n"
" # third arg of bthread_make_fcontext() == address of context-function\n"
" # save address of context-function entry point\n"
" std %r5, 512(%r3)\n"
" # set the back chain of the context's first frame to zero\n"
" li %r0, 0\n"
" std %r0, 528(%r3)\n"
" # initial CR, FPSCR and VRSAVE of the context: the current ones\n"
" mfcr %r0\n"
" std %r0, 496(%r3)\n"
" mffs %f0\n"
" stfd %f0, 344(%r3)\n"
" mfspr %r0, 256\n"
" std %r0, 192(%r3)\n"
" # load LR\n"
" mflr %r0\n"
" # jump to label 1\n"
" bl 1f\n"
"1:\n"
" # load LR into R4\n"
" mflr %r4\n"
" # compute abs address of label finish\n"
" addi %r4, %r4, finish - 1b\n"
" # restore LR\n"
" mtlr %r0\n"
" # save address of finish as return-address for context-function\n"
" # will be entered after context-function returns\n"
" std %r4, 504(%r3)\n"
" # restore return address from R6\n"
" mtlr %r6\n"
" blr # return pointer to context-data\n"
"finish:\n"
" # LR holds the address of finish: derive this module's TOC from it for\n"
" # the _exit call, the context function may live in another DSO\n"
" mflr %r12\n"
" addis %r2, %r12, .TOC.-finish@ha\n"
" addi %r2, %r2, .TOC.-finish@l\n"
" # save return address on stack, set up stack frame\n"
" std %r12, 16(%r1)\n"
" # allocate stack space, R1 % 16 == 0\n"
" stdu %r1, -32(%r1)\n"
" # exit code is zero\n"
" li %r3, 0\n"
" # exit application\n"
" bl _exit\n"
" nop\n"
".machine pop\n"
".size bthread_make_fcontext, .-bthread_make_fcontext\n"
".section .note.GNU-stack,\"\",%progbits\n"
".previous\n"
);

#endif
11 changes: 11 additions & 0 deletions src/bthread/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@
#endif
#endif

// The 64-bit PowerPC ELFv2 ABI is the same on every OS that uses it:
// ppc64le everywhere, big-endian ppc64 on FreeBSD and musl.
#if defined(__powerpc64__)
#if defined(_CALL_ELF) && _CALL_ELF == 2
#define BTHREAD_CONTEXT_PLATFORM_ppc64_elfv2
#define BTHREAD_CONTEXT_CALL_CONVENTION
#else
#error "64-bit PowerPC is supported with the ELFv2 ABI only"
#endif
#endif

#endif

#if defined(_WIN32_WCE)
Expand Down
2 changes: 2 additions & 0 deletions src/butil/atomicops.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
#include "butil/atomicops_internals_loongarch64_gcc.h"
#elif defined(COMPILER_GCC) && defined(ARCH_CPU_RISCV_FAMILY)
#include "butil/atomicops_internals_riscv_gcc.h"
#elif defined(COMPILER_GCC) && defined(ARCH_CPU_PPC64_FAMILY)
#include "butil/atomicops_internals_gcc.h"
#else
#error "Atomic operations are not supported on your platform"
#endif
Expand Down
Loading
Loading