blob: 0a23d689e298d68f87a79c9bd1eb09054cb7d268 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
#ifndef EXSM_COMMON_H
#define EXSM_COMMON_H
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include "Platform.h"
#include "sm.h"
#include "NAAssert.h"
// Forward declarations
class ExSMGlobals;
class NAMemory;
class ExSMTask;
class ExExeStmtGlobals;
// This "main thread PIN" identifies the SQL main thread when the SM
// reader thread raises an LRABBIT event. The main thread associates
// itself with this PIN when SM is initialized (see
// ExSMGlobals::InitSMGlobals()) and the reader thread uses this PIN
// in calls to XAWAKE.
const int EXSM_MAIN_THREAD_PIN = 1;
//-------------------------------------------------------------------------
// Report the largest chunk size we can transmit using SeaMonster. We
// call SM to retrieve the absolute maximum and then use 50% of that
// value as our effective maximum.
//-------------------------------------------------------------------------
uint32_t ExSM_GetMaxChunkSize(NABoolean intranode = FALSE);
//-------------------------------------------------------------------------
// Map between virtual and real SQ node numbers. Note that we need to
// be aware if the size of the node number id changes
//-------------------------------------------------------------------------
int32_t ExSM_GetNodeID(int32_t nodeNum);
//-------------------------------------------------------------------------
// Compare two SM targets
//-------------------------------------------------------------------------
bool ExSM_TargetsEqual(const sm_target_t &a, const sm_target_t &b);
//-------------------------------------------------------------------------
// Assert macros for SeaMonster reader thread
//-------------------------------------------------------------------------
#define exsm_assert(expr, msg) \
{ if (!(expr)) assert_botch_abend(__FILE__, __LINE__, msg, "" # expr ""); }
extern __thread char ExSM_AssertBuf[];
#define exsm_assert_rc(rc, func) { \
if (rc != 0) { \
sprintf(ExSM_AssertBuf, "rc = %d", (int) rc); \
assert_botch_abend(__FILE__, __LINE__, func, ExSM_AssertBuf); \
} \
}
//-------------------------------------------------------------------------
// SeaMonster message types used in the executor
//-------------------------------------------------------------------------
enum ExSM_MessageType
{
// Data reqeust
EXSM_MSG_REQUEST = 1,
// Data reply
EXSM_MSG_REPLY = 2,
// Short message
EXSM_MSG_SHORT = 3
};
//-------------------------------------------------------------------------
// SM initialize
//-------------------------------------------------------------------------
int32_t ExSM_Initialize(ExSMGlobals *smGlobals,
ExExeStmtGlobals *stmtGlobals);
//-------------------------------------------------------------------------
// SM finalize
//-------------------------------------------------------------------------
int32_t ExSM_Finalize(ExSMGlobals *smGlobals);
//-------------------------------------------------------------------------
// Send a SeaMonster message
//-------------------------------------------------------------------------
int32_t ExSM_Send(ExSMGlobals *smGlobals, // IN
const sm_target_t &target, // IN
const void *data, // IN
size_t numBytes, // IN
ExSM_MessageType msgType, // IN
bool isPrepostRequired, // IN
bool &messageWasSent, // OUT
int maxRetries, // IN (-1 = retry forever)
int64_t sendCount, // IN (for tracing only)
const void *startBuf);
//-------------------------------------------------------------------------
// Post a SeaMonster receive buffer
//-------------------------------------------------------------------------
int32_t ExSM_Post(const sm_target_t &target, // IN
size_t dataSize, // IN
const void *data, // IN
ExSMTask *smTask, // IN
NABoolean isServer); // IN (for tracing only)
//-------------------------------------------------------------------------
// Send a SeaMonster short message
//-------------------------------------------------------------------------
int32_t ExSM_SendShortMessage(ExSMGlobals *smGlobals,
const sm_target_t &target,
const void *data,
size_t bytesToSend);
//-------------------------------------------------------------------------
// Wrapper function used by the reader thread to set the length of an
// IPC message buffer. Eliminates the need for the reader thread
// function to include or be aware of our IPC classes.
//-------------------------------------------------------------------------
void ExSM_SetMessageLength(void *buf, size_t len);
//-------------------------------------------------------------------------
// Wrapper function used by the reader thread to allocate an
// IpcMessageBuffer on the C++ heap. The size of the data region in the
// new buffer will be dataBytes. Eliminates the need for the reader
// thread function to include or be aware of our IPC classes.
//-------------------------------------------------------------------------
void *ExSM_AllocateMessageBuffer(size_t dataBytes,
NAMemory *threadSafeHeap);
//-------------------------------------------------------------------------
// Return the SeaMonster prepost address of a message buffer. The
// prepost address is the first byte of data that gets transmitted. The
// IpcMessageBuffer header is not transmitted.
//-------------------------------------------------------------------------
void *ExSM_GetMessageBufferPrepostAddr(void *data);
//-------------------------------------------------------------------------
// Return the address of a message buffer given the SeaMonster prepost
// address. The prepost address immediately follows an IpcMessageBuffer
// instance.
//-------------------------------------------------------------------------
void *ExSM_GetMessageBufferAddr(void *prepostAddr);
//-------------------------------------------------------------------------
// Return the IPC message object type of the first object that follows
// the header (the header is an InternalMsgHdrInfoStruct) in the
// IpcMessageBuffer pointed to by the data argument.
//
// If the object type cannot be determined "UNKNOWN" is returned.
//-------------------------------------------------------------------------
const char *ExSM_GetMessageBufferType(void *data, size_t dataBytes);
//-------------------------------------------------------------------------
// Function to return the threadId of the calling thread
//-------------------------------------------------------------------------
int ExSM_GetThreadID();
//-------------------------------------------------------------------------
// Functions and values to manipulate and test SeaMonster tag qualifiers
//
// Each SM message travels with:
// * The ID associated with the query
// * The tag associated with the TCB
// * Zero or more tag qualifier bits
//
// Tag qualifiers occupy the four high-order bits of the tag. We
// currently have the following qualifiers:
//
// REPLY - Prepost message or short message sent from server to
// client
//
// SQL_CHUNK - Prepost message sent using the SQL chunking protocol
//
// Note:
//
// Chunk protocol is sometimes used for messages that travel as a
// single chunk. This happens when message size exceeds the max
// expected size on the receiving end but does not exceed the
// SeaMonster max buffer size. Such messages will have the CHUNK
// qualifier set.
//
// The SHUTDOWN message is a special short message. It travels with
// a SeaMonster ID of 0, tag of 0, and no tag qualifiers.
//
//-------------------------------------------------------------------------
// The tag qualifier bits
const int32_t EXSM_TAG_REPLY = 0x10000000;
const int32_t EXSM_TAG_SQL_CHUNK = 0x20000000;
// A filter for masking out the qualifier bits from a 32-bit tag
const int32_t EXSM_TAG_FILTER = 0x0fffffff;
// Get, set and toggle the REPLY bit in the tag. The set function
// modifies the caller's tag. The toggle function returns a new tag
// and does not modify the caller's tag.
inline bool ExSMTag_GetReplyFlag(int t) { return t & EXSM_TAG_REPLY; }
inline void ExSMTag_SetReplyFlag(int *t) { *t |= EXSM_TAG_REPLY; }
inline int ExSMTag_ToggleReplyFlag(int t) { return t ^ EXSM_TAG_REPLY; }
// Get, set and toggle the SQL CHUNK bit in the tag. The set function
// modifies the caller's tag. The clear function also modifies the
// caller's tag.
inline bool ExSMTag_GetSQLChunkFlag(int t) { return t & EXSM_TAG_SQL_CHUNK; }
inline void ExSMTag_SetSQLChunkFlag(int *t) { *t |= EXSM_TAG_SQL_CHUNK; }
inline void ExSMTag_ClearSQLChunkFlag(int *t) { *t &= ~EXSM_TAG_SQL_CHUNK; }
// Return the tag value with all qualifier bits cleared
inline int ExSMTag_GetTagWithoutQualifier(int t) { return t & EXSM_TAG_FILTER; }
// Return a single hex character representing the 4-bit tag qualifier
inline char ExSMTag_GetQualifierDisplay(int t)
{
char qualifierDisplay[17] = "0123456789abcdef";
return qualifierDisplay[((unsigned int) t) >> 28];
}
//-------------------------------------------------------------------------
// We maintain a global list of completed send buffers. The following
// functions are used to add and remove elements. For more detail see
// the implementation of these functions in ExSMCommon.cpp
//-------------------------------------------------------------------------
void ExSM_AddCompletedSendBuffer(void *buf);
bool ExSM_RemoveCompletedSendBuffer(void *&buf);
//-------------------------------------------------------------------------
// We maintain a global collection of active IDs and functions to
// register, cancel, and find an ID. Access to the collection is
// protected by a mutex. The register function is a no-op if the ID
// is already in the collection, and the cancel function is a no-op
// if the ID is not in the collection.
//-------------------------------------------------------------------------
int32_t ExSM_Register(const int64_t &id);
int32_t ExSM_Cancel(const int64_t &id);
bool ExSM_FindID(const int64_t &id, bool lock = true);
#endif // EXSM_COMMON_H