<commit_before>//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the RecordLayout interface.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"

using namespace clang;

void ASTRecordLayout::Destroy(ASTContext &Ctx) {
  if (FieldOffsets)
    Ctx.Deallocate(FieldOffsets);
  if (CXXInfo)
    Ctx.Deallocate(CXXInfo);
  this->~ASTRecordLayout();
  Ctx.Deallocate(this);
}

ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
                unsigned datasize, const uint64_t *fieldoffsets,
                unsigned fieldcount)
  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
    FieldCount(fieldcount), CXXInfo(0) {
  if (FieldCount > 0)  {
    FieldOffsets = new (Ctx) uint64_t[FieldCount];
    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  }
}

// Constructor for C++ records.
ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
                                 uint64_t size, unsigned alignment,
                                 uint64_t datasize,
                                 const uint64_t *fieldoffsets,
                                 unsigned fieldcount,
                                 uint64_t nonvirtualsize,
                                 unsigned nonvirtualalign,
                                 uint64_t SizeOfLargestEmptySubobject,
                                 const CXXRecordDecl *PrimaryBase,
                                 bool PrimaryBaseIsVirtual,
                                 const BaseOffsetsMapTy& BaseOffsets,
                                 const BaseOffsetsMapTy& VBaseOffsets)
  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
{
  if (FieldCount > 0)  {
    FieldOffsets = new (Ctx) uint64_t[FieldCount];
    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  }

  CXXInfo->PrimaryBase = PrimaryBaseInfo(PrimaryBase, PrimaryBaseIsVirtual);
  CXXInfo->NonVirtualSize = nonvirtualsize;
  CXXInfo->NonVirtualAlign = nonvirtualalign;
  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
  CXXInfo->BaseOffsets = BaseOffsets;
  CXXInfo->VBaseOffsets = VBaseOffsets;

#ifndef NDEBUG
    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
      if (getPrimaryBaseWasVirtual())
        assert(getVBaseClassOffset(PrimaryBase) == 0 &&
               "Primary virtual base must be at offset 0!");
      else
        assert(getBaseClassOffset(PrimaryBase) == 0 &&
               "Primary base must be at offset 0!");
    }
#endif
}
<commit_msg>Plug leak. The DenseMaps of CXXRecordLayoutInfo weren't freed.<commit_after>//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the RecordLayout interface.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"

using namespace clang;

void ASTRecordLayout::Destroy(ASTContext &Ctx) {
  if (FieldOffsets)
    Ctx.Deallocate(FieldOffsets);
  if (CXXInfo) {
    Ctx.Deallocate(CXXInfo);
    CXXInfo->~CXXRecordLayoutInfo();
  }
  this->~ASTRecordLayout();
  Ctx.Deallocate(this);
}

ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
                unsigned datasize, const uint64_t *fieldoffsets,
                unsigned fieldcount)
  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
    FieldCount(fieldcount), CXXInfo(0) {
  if (FieldCount > 0)  {
    FieldOffsets = new (Ctx) uint64_t[FieldCount];
    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  }
}

// Constructor for C++ records.
ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
                                 uint64_t size, unsigned alignment,
                                 uint64_t datasize,
                                 const uint64_t *fieldoffsets,
                                 unsigned fieldcount,
                                 uint64_t nonvirtualsize,
                                 unsigned nonvirtualalign,
                                 uint64_t SizeOfLargestEmptySubobject,
                                 const CXXRecordDecl *PrimaryBase,
                                 bool PrimaryBaseIsVirtual,
                                 const BaseOffsetsMapTy& BaseOffsets,
                                 const BaseOffsetsMapTy& VBaseOffsets)
  : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
{
  if (FieldCount > 0)  {
    FieldOffsets = new (Ctx) uint64_t[FieldCount];
    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  }

  CXXInfo->PrimaryBase = PrimaryBaseInfo(PrimaryBase, PrimaryBaseIsVirtual);
  CXXInfo->NonVirtualSize = nonvirtualsize;
  CXXInfo->NonVirtualAlign = nonvirtualalign;
  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
  CXXInfo->BaseOffsets = BaseOffsets;
  CXXInfo->VBaseOffsets = VBaseOffsets;

#ifndef NDEBUG
    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
      if (getPrimaryBaseWasVirtual())
        assert(getVBaseClassOffset(PrimaryBase) == 0 &&
               "Primary virtual base must be at offset 0!");
      else
        assert(getBaseClassOffset(PrimaryBase) == 0 &&
               "Primary base must be at offset 0!");
    }
#endif
}
<|endoftext|>


<commit_before>//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit blocks.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"

#include <algorithm>

using namespace clang;
using namespace CodeGen;

enum {
  BLOCK_NEEDS_FREE =        (1 << 24),
  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
  BLOCK_HAS_CXX_OBJ =       (1 << 26),
  BLOCK_IS_GC =             (1 << 27),
  BLOCK_IS_GLOBAL =         (1 << 28),
  BLOCK_HAS_DESCRIPTOR =    (1 << 29)
};

llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl(uint64_t Size) {
  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  const llvm::Type *UnsignedLongTy
    = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
  llvm::Constant *C;
  std::vector<llvm::Constant*> Elts;

  // reserved
  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
  Elts.push_back(C);

  // Size
  // FIXME: What is the right way to say this doesn't fit?  We should give
  // a user diagnostic in that case.  Better fix would be to change the
  // API to size_t.
  C = llvm::ConstantInt::get(UnsignedLongTy, Size);
  Elts.push_back(C);

  if (BlockHasCopyDispose) {
    // copy_func_helper_decl
    // FIXME: implement
    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // destroy_func_decl
    // FIXME: implement
    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);
  }

  C = llvm::ConstantStruct::get(Elts);

  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, "__block_descriptor_tmp", &CGM.getModule());
  return C;
}

llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
  if (NSConcreteGlobalBlock)
    return NSConcreteGlobalBlock;

  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the
  // same thing as CreateRuntimeFunction if there's already a variable with
  // the same name.
  NSConcreteGlobalBlock
    = new llvm::GlobalVariable(PtrToInt8Ty, false,
                               llvm::GlobalValue::ExternalLinkage,
                               0, "_NSConcreteGlobalBlock",
                               &getModule());

  return NSConcreteGlobalBlock;
}

llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
  if (NSConcreteStackBlock)
    return NSConcreteStackBlock;

  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the
  // same thing as CreateRuntimeFunction if there's already a variable with
  // the same name.
  NSConcreteStackBlock
    = new llvm::GlobalVariable(PtrToInt8Ty, false,
                               llvm::GlobalValue::ExternalLinkage,
                               0, "_NSConcreteStackBlock",
                               &getModule());

  return NSConcreteStackBlock;
}

// FIXME: Push most into CGM, passing down a few bits, like current
// function name.
llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
  bool insideFunction = false;
  bool BlockRefDeclList = false;
  bool BlockByrefDeclList = false;

  std::vector<llvm::Constant*> Elts;
  llvm::Constant *C;

  {
    // C = BuildBlockStructInitlist();
    unsigned int flags = BLOCK_HAS_DESCRIPTOR;

    if (BlockHasCopyDispose)
      flags |= BLOCK_HAS_COPY_DISPOSE;

    // __isa
    C = CGM.getNSConcreteStackBlock();
    if (!insideFunction ||
        (!BlockRefDeclList && !BlockByrefDeclList)) {
      C = CGM.getNSConcreteGlobalBlock();
      flags |= BLOCK_IS_GLOBAL;
    }
    const llvm::PointerType *PtrToInt8Ty
      = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // __flags
    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
    C = llvm::ConstantInt::get(IntTy, flags);
    Elts.push_back(C);

    // __reserved
    C = llvm::ConstantInt::get(IntTy, 0);
    Elts.push_back(C);

    // __invoke
    const char *Name = "";
    if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl))
      if (ND->getIdentifier())
        Name = ND->getNameAsCString();
    BlockInfo Info(0, Name);
    uint64_t subBlockSize;
    llvm::Function *Fn
      = CodeGenFunction(*this).GenerateBlockFunction(BE, Info, subBlockSize);
    Elts.push_back(Fn);

    // __descriptor
    Elts.push_back(BuildDescriptorBlockDecl(subBlockSize));

    // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
  }

  C = llvm::ConstantStruct::get(Elts);

  char Name[32];
  sprintf(Name, "__block_holder_tmp_%d", CGM.getGlobalUniqueCount());
  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, Name, &CGM.getModule());
  QualType BPT = BE->getType();
  C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
  return C;
}

const llvm::Type *CodeGenModule::getBlockDescriptorType() {
  if (BlockDescriptorType)
    return BlockDescriptorType;

  const llvm::Type *UnsignedLongTy =
    getTypes().ConvertType(getContext().UnsignedLongTy);

  // struct __block_descriptor {
  //   unsigned long reserved;
  //   unsigned long block_size;
  // };
  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy,
                                              UnsignedLongTy,
                                              NULL);

  getModule().addTypeName("struct.__block_descriptor",
                          BlockDescriptorType);

  return BlockDescriptorType;
}

const llvm::Type *
CodeGenModule::getGenericBlockLiteralType() {
  if (GenericBlockLiteralType)
    return GenericBlockLiteralType;

  const llvm::Type *Int8PtrTy =
    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

  const llvm::Type *BlockDescPtrTy =
    llvm::PointerType::getUnqual(getBlockDescriptorType());

  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  // struct __block_literal_generic {
  //   void *__isa;
  //   int __flags;
  //   int __reserved;
  //   void (*__invoke)(void *);
  //   struct __block_descriptor *__descriptor;
  // };
  GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                  IntTy,
                                                  IntTy,
                                                  Int8PtrTy,
                                                  BlockDescPtrTy,
                                                  NULL);

  getModule().addTypeName("struct.__block_literal_generic",
                          GenericBlockLiteralType);

  return GenericBlockLiteralType;
}

const llvm::Type *
CodeGenModule::getGenericExtendedBlockLiteralType() {
  if (GenericExtendedBlockLiteralType)
    return GenericExtendedBlockLiteralType;

  const llvm::Type *Int8PtrTy =
    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

  const llvm::Type *BlockDescPtrTy =
    llvm::PointerType::getUnqual(getBlockDescriptorType());

  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  // struct __block_literal_generic {
  //   void *__isa;
  //   int __flags;
  //   int __reserved;
  //   void (*__invoke)(void *);
  //   struct __block_descriptor *__descriptor;
  //   void *__copy_func_helper_decl;
  //   void *__destroy_func_decl;
  // };
  GenericExtendedBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                          IntTy,
                                                          IntTy,
                                                          Int8PtrTy,
                                                          BlockDescPtrTy,
                                                          Int8PtrTy,
                                                          Int8PtrTy,
                                                          NULL);

  getModule().addTypeName("struct.__block_literal_extended_generic",
                          GenericExtendedBlockLiteralType);

  return GenericExtendedBlockLiteralType;
}

/// getBlockFunctionType - Given a BlockPointerType, will return the
/// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx,
                                     const BlockPointerType *BPT) {
  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());

  llvm::SmallVector<QualType, 8> Types;
  Types.push_back(Ctx.getPointerType(Ctx.VoidTy));

  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
       e = FTy->arg_type_end(); i != e; ++i)
    Types.push_back(*i);

  return Ctx.getFunctionType(FTy->getResultType(),
                             &Types[0], Types.size(),
                             FTy->isVariadic(), 0);
}

RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {
  const BlockPointerType *BPT =
    E->getCallee()->getType()->getAsBlockPointerType();

  llvm::Value *Callee = EmitScalarExpr(E->getCallee());

  // Get a pointer to the generic block literal.
  const llvm::Type *BlockLiteralTy =
    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());

  // Bitcast the callee to a block literal.
  llvm::Value *BlockLiteral =
    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");

  // Get the function pointer from the literal.
  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
  llvm::Value *Func = Builder.CreateLoad(FuncPtr, false, "tmp");

  // Cast the function pointer to the right type.
  const llvm::Type *BlockFTy =
    ConvertType(getBlockFunctionType(getContext(), BPT));
  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
  Func = Builder.CreateBitCast(Func, BlockFTyPtr);

  BlockLiteral =
    Builder.CreateBitCast(BlockLiteral,
                          llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
                          "tmp");

  // Add the block literal.
  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
  CallArgList Args;
  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));

  // And the rest of the arguments.
  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
       i != e; ++i)
    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i),
                                  i->getType()));

  // And call the block.
  return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args),
                  Func, Args);
}

llvm::Constant *
CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
  // Generate the block descriptor.
  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  llvm::Constant *DescriptorFields[2];

  // Reserved
  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);

  // Block literal size. For global blocks we just use the size of the generic
  // block literal struct.
  uint64_t BlockLiteralSize =
    TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8;
  DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize);

  llvm::Constant *DescriptorStruct =
    llvm::ConstantStruct::get(&DescriptorFields[0], 2);

  llvm::GlobalVariable *Descriptor =
    new llvm::GlobalVariable(DescriptorStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             DescriptorStruct, "__block_descriptor_global",
                             &getModule());

  // Generate the constants for the block literal.
  llvm::Constant *LiteralFields[5];

  CodeGenFunction::BlockInfo Info(0, n);
  uint64_t subBlockSize;
  llvm::Function *Fn
    = CodeGenFunction(*this).GenerateBlockFunction(BE, Info, subBlockSize);
  assert(subBlockSize == BlockLiteralSize
         && "no imports allowed for global block");

  // isa
  LiteralFields[0] = getNSConcreteGlobalBlock();

  // Flags
  LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL);

  // Reserved
  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);

  // Function
  LiteralFields[3] = Fn;

  // Descriptor
  LiteralFields[4] = Descriptor;

  llvm::Constant *BlockLiteralStruct =
    llvm::ConstantStruct::get(&LiteralFields[0], 5);

  llvm::GlobalVariable *BlockLiteral =
    new llvm::GlobalVariable(BlockLiteralStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             BlockLiteralStruct, "__block_literal_global",
                             &getModule());

  return BlockLiteral;
}

llvm::Value *CodeGenFunction::LoadBlockStruct() {
  return Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()], "self");
}

llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
                                                       const BlockInfo& Info,
                                                       uint64_t &Size) {
  const FunctionTypeProto *FTy =
    cast<FunctionTypeProto>(Expr->getFunctionType());

  FunctionArgList Args;

  const BlockDecl *BD = Expr->getBlockDecl();

  // FIXME: there are tons of variables in CGF that are copied, we probably
  // don't want many of them, any of them.  When we trim that, this can go away.
  // Help ensure no control flow in or out of the block.
  BreakContinueStack.clear();

  // FIXME: This leaks
  ImplicitParamDecl *SelfDecl =
    ImplicitParamDecl::Create(getContext(), 0,
                              SourceLocation(), 0,
                              getContext().getPointerType(getContext().VoidTy));

  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
  BlockStructDecl = SelfDecl;

  for (BlockDecl::param_iterator i = BD->param_begin(),
       e = BD->param_end(); i != e; ++i)
    Args.push_back(std::make_pair(*i, (*i)->getType()));

  const CGFunctionInfo &FI =
    CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args);

  std::string Name = std::string("__") + Info.Name + "_block_invoke_";
  CodeGenTypes &Types = CGM.getTypes();
  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic());

  llvm::Function *Fn =
    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
                           Name,
                           &CGM.getModule());

  StartFunction(BD, FTy->getResultType(), Fn, Args,
                Expr->getBody()->getLocEnd());
  EmitStmt(Expr->getBody());
  FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc());

  Size = BlockOffset;

  return Fn;
}
<commit_msg>Pass the CodeGenModule object to GenerateBlockFunction, instead of *this (which will call the copy constructor). <commit_after>//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit blocks.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"

#include <algorithm>

using namespace clang;
using namespace CodeGen;

enum {
  BLOCK_NEEDS_FREE =        (1 << 24),
  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
  BLOCK_HAS_CXX_OBJ =       (1 << 26),
  BLOCK_IS_GC =             (1 << 27),
  BLOCK_IS_GLOBAL =         (1 << 28),
  BLOCK_HAS_DESCRIPTOR =    (1 << 29)
};

llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl(uint64_t Size) {
  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  const llvm::Type *UnsignedLongTy
    = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
  llvm::Constant *C;
  std::vector<llvm::Constant*> Elts;

  // reserved
  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
  Elts.push_back(C);

  // Size
  // FIXME: What is the right way to say this doesn't fit?  We should give
  // a user diagnostic in that case.  Better fix would be to change the
  // API to size_t.
  C = llvm::ConstantInt::get(UnsignedLongTy, Size);
  Elts.push_back(C);

  if (BlockHasCopyDispose) {
    // copy_func_helper_decl
    // FIXME: implement
    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // destroy_func_decl
    // FIXME: implement
    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);
  }

  C = llvm::ConstantStruct::get(Elts);

  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, "__block_descriptor_tmp", &CGM.getModule());
  return C;
}

llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
  if (NSConcreteGlobalBlock)
    return NSConcreteGlobalBlock;

  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the
  // same thing as CreateRuntimeFunction if there's already a variable with
  // the same name.
  NSConcreteGlobalBlock
    = new llvm::GlobalVariable(PtrToInt8Ty, false,
                               llvm::GlobalValue::ExternalLinkage,
                               0, "_NSConcreteGlobalBlock",
                               &getModule());

  return NSConcreteGlobalBlock;
}

llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
  if (NSConcreteStackBlock)
    return NSConcreteStackBlock;

  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the
  // same thing as CreateRuntimeFunction if there's already a variable with
  // the same name.
  NSConcreteStackBlock
    = new llvm::GlobalVariable(PtrToInt8Ty, false,
                               llvm::GlobalValue::ExternalLinkage,
                               0, "_NSConcreteStackBlock",
                               &getModule());

  return NSConcreteStackBlock;
}

// FIXME: Push most into CGM, passing down a few bits, like current
// function name.
llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
  bool insideFunction = false;
  bool BlockRefDeclList = false;
  bool BlockByrefDeclList = false;

  std::vector<llvm::Constant*> Elts;
  llvm::Constant *C;

  {
    // C = BuildBlockStructInitlist();
    unsigned int flags = BLOCK_HAS_DESCRIPTOR;

    if (BlockHasCopyDispose)
      flags |= BLOCK_HAS_COPY_DISPOSE;

    // __isa
    C = CGM.getNSConcreteStackBlock();
    if (!insideFunction ||
        (!BlockRefDeclList && !BlockByrefDeclList)) {
      C = CGM.getNSConcreteGlobalBlock();
      flags |= BLOCK_IS_GLOBAL;
    }
    const llvm::PointerType *PtrToInt8Ty
      = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // __flags
    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
    C = llvm::ConstantInt::get(IntTy, flags);
    Elts.push_back(C);

    // __reserved
    C = llvm::ConstantInt::get(IntTy, 0);
    Elts.push_back(C);

    // __invoke
    const char *Name = "";
    if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl))
      if (ND->getIdentifier())
        Name = ND->getNameAsCString();
    BlockInfo Info(0, Name);
    uint64_t subBlockSize;
    llvm::Function *Fn
      = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, subBlockSize);
    Elts.push_back(Fn);

    // __descriptor
    Elts.push_back(BuildDescriptorBlockDecl(subBlockSize));

    // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
  }

  C = llvm::ConstantStruct::get(Elts);

  char Name[32];
  sprintf(Name, "__block_holder_tmp_%d", CGM.getGlobalUniqueCount());
  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, Name, &CGM.getModule());
  QualType BPT = BE->getType();
  C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
  return C;
}

const llvm::Type *CodeGenModule::getBlockDescriptorType() {
  if (BlockDescriptorType)
    return BlockDescriptorType;

  const llvm::Type *UnsignedLongTy =
    getTypes().ConvertType(getContext().UnsignedLongTy);

  // struct __block_descriptor {
  //   unsigned long reserved;
  //   unsigned long block_size;
  // };
  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy,
                                              UnsignedLongTy,
                                              NULL);

  getModule().addTypeName("struct.__block_descriptor",
                          BlockDescriptorType);

  return BlockDescriptorType;
}

const llvm::Type *
CodeGenModule::getGenericBlockLiteralType() {
  if (GenericBlockLiteralType)
    return GenericBlockLiteralType;

  const llvm::Type *Int8PtrTy =
    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

  const llvm::Type *BlockDescPtrTy =
    llvm::PointerType::getUnqual(getBlockDescriptorType());

  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  // struct __block_literal_generic {
  //   void *__isa;
  //   int __flags;
  //   int __reserved;
  //   void (*__invoke)(void *);
  //   struct __block_descriptor *__descriptor;
  // };
  GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                  IntTy,
                                                  IntTy,
                                                  Int8PtrTy,
                                                  BlockDescPtrTy,
                                                  NULL);

  getModule().addTypeName("struct.__block_literal_generic",
                          GenericBlockLiteralType);

  return GenericBlockLiteralType;
}

const llvm::Type *
CodeGenModule::getGenericExtendedBlockLiteralType() {
  if (GenericExtendedBlockLiteralType)
    return GenericExtendedBlockLiteralType;

  const llvm::Type *Int8PtrTy =
    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

  const llvm::Type *BlockDescPtrTy =
    llvm::PointerType::getUnqual(getBlockDescriptorType());

  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  // struct __block_literal_generic {
  //   void *__isa;
  //   int __flags;
  //   int __reserved;
  //   void (*__invoke)(void *);
  //   struct __block_descriptor *__descriptor;
  //   void *__copy_func_helper_decl;
  //   void *__destroy_func_decl;
  // };
  GenericExtendedBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                          IntTy,
                                                          IntTy,
                                                          Int8PtrTy,
                                                          BlockDescPtrTy,
                                                          Int8PtrTy,
                                                          Int8PtrTy,
                                                          NULL);

  getModule().addTypeName("struct.__block_literal_extended_generic",
                          GenericExtendedBlockLiteralType);

  return GenericExtendedBlockLiteralType;
}

/// getBlockFunctionType - Given a BlockPointerType, will return the
/// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx,
                                     const BlockPointerType *BPT) {
  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());

  llvm::SmallVector<QualType, 8> Types;
  Types.push_back(Ctx.getPointerType(Ctx.VoidTy));

  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
       e = FTy->arg_type_end(); i != e; ++i)
    Types.push_back(*i);

  return Ctx.getFunctionType(FTy->getResultType(),
                             &Types[0], Types.size(),
                             FTy->isVariadic(), 0);
}

RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {
  const BlockPointerType *BPT =
    E->getCallee()->getType()->getAsBlockPointerType();

  llvm::Value *Callee = EmitScalarExpr(E->getCallee());

  // Get a pointer to the generic block literal.
  const llvm::Type *BlockLiteralTy =
    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());

  // Bitcast the callee to a block literal.
  llvm::Value *BlockLiteral =
    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");

  // Get the function pointer from the literal.
  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
  llvm::Value *Func = Builder.CreateLoad(FuncPtr, false, "tmp");

  // Cast the function pointer to the right type.
  const llvm::Type *BlockFTy =
    ConvertType(getBlockFunctionType(getContext(), BPT));
  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
  Func = Builder.CreateBitCast(Func, BlockFTyPtr);

  BlockLiteral =
    Builder.CreateBitCast(BlockLiteral,
                          llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
                          "tmp");

  // Add the block literal.
  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
  CallArgList Args;
  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));

  // And the rest of the arguments.
  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
       i != e; ++i)
    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i),
                                  i->getType()));

  // And call the block.
  return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args),
                  Func, Args);
}

llvm::Constant *
CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
  // Generate the block descriptor.
  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  llvm::Constant *DescriptorFields[2];

  // Reserved
  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);

  // Block literal size. For global blocks we just use the size of the generic
  // block literal struct.
  uint64_t BlockLiteralSize =
    TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8;
  DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize);

  llvm::Constant *DescriptorStruct =
    llvm::ConstantStruct::get(&DescriptorFields[0], 2);

  llvm::GlobalVariable *Descriptor =
    new llvm::GlobalVariable(DescriptorStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             DescriptorStruct, "__block_descriptor_global",
                             &getModule());

  // Generate the constants for the block literal.
  llvm::Constant *LiteralFields[5];

  CodeGenFunction::BlockInfo Info(0, n);
  uint64_t subBlockSize;
  llvm::Function *Fn
    = CodeGenFunction(*this).GenerateBlockFunction(BE, Info, subBlockSize);
  assert(subBlockSize == BlockLiteralSize
         && "no imports allowed for global block");

  // isa
  LiteralFields[0] = getNSConcreteGlobalBlock();

  // Flags
  LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL);

  // Reserved
  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);

  // Function
  LiteralFields[3] = Fn;

  // Descriptor
  LiteralFields[4] = Descriptor;

  llvm::Constant *BlockLiteralStruct =
    llvm::ConstantStruct::get(&LiteralFields[0], 5);

  llvm::GlobalVariable *BlockLiteral =
    new llvm::GlobalVariable(BlockLiteralStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             BlockLiteralStruct, "__block_literal_global",
                             &getModule());

  return BlockLiteral;
}

llvm::Value *CodeGenFunction::LoadBlockStruct() {
  return Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()], "self");
}

llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
                                                       const BlockInfo& Info,
                                                       uint64_t &Size) {
  const FunctionTypeProto *FTy =
    cast<FunctionTypeProto>(Expr->getFunctionType());

  FunctionArgList Args;

  const BlockDecl *BD = Expr->getBlockDecl();

  // FIXME: This leaks
  ImplicitParamDecl *SelfDecl =
    ImplicitParamDecl::Create(getContext(), 0,
                              SourceLocation(), 0,
                              getContext().getPointerType(getContext().VoidTy));

  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
  BlockStructDecl = SelfDecl;

  for (BlockDecl::param_iterator i = BD->param_begin(),
       e = BD->param_end(); i != e; ++i)
    Args.push_back(std::make_pair(*i, (*i)->getType()));

  const CGFunctionInfo &FI =
    CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args);

  std::string Name = std::string("__") + Info.Name + "_block_invoke_";
  CodeGenTypes &Types = CGM.getTypes();
  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic());

  llvm::Function *Fn =
    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
                           Name,
                           &CGM.getModule());

  StartFunction(BD, FTy->getResultType(), Fn, Args,
                Expr->getBody()->getLocEnd());
  EmitStmt(Expr->getBody());
  FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc());

  Size = BlockOffset;

  return Fn;
}
<|endoftext|>


<commit_before>#ifndef _ANY_H
#define _ANY_H

#include <iostream>
#include <memory>
#include <typeindex>

class Any
{
public:
    Any() : m_typeIndex(std::type_index(typeid(void))) {}
    Any(Any& other) : m_basePtr(other.clone()), m_typeIndex(other.m_typeIndex) {}
    Any(Any&& other) : m_basePtr(std::move(other.m_basePtr)), m_typeIndex(other.m_typeIndex) {}

    // 创建智能指针时，对于一般的类型，通过std::decay来移除引用和cv符，从而获得原始类型
    template<typename U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type>
    Any(U&& value) : m_basePtr(new Derived<typename std::decay<U>::type>(std::forward<U>(value))),
        m_typeIndex(std::type_index(typeid(typename std::decay<U>::type))) {}

    bool isNull() const
    {
        return !bool(m_basePtr);
    }

    template<typename U>
    bool is() const
    {
        return m_typeIndex == std::type_index(typeid(U));
    }

    // 将Any转换为实际的类型
    template<typename U>
    U& anyCast()
    {
        if (!is<U>())
        {
            std::cout << "Can not cast " << typeid(U).name() << " to " << m_typeIndex.name() << std::endl;
            throw std::bad_cast();
        }

        auto dervied = dynamic_cast<Derived<U>*>(m_basePtr.get());
        return dervied->m_value;
    }

    Any& operator=(const Any& other)
    {
        if (m_basePtr == other.m_basePtr)
        {
            return *this;
        }

        m_basePtr = other.clone();
        m_typeIndex = other.m_typeIndex;
        return *this;
    }

private:
    class Base;
    using BasePtr = std::unique_ptr<Base>;

    class Base
    {
    public:
        virtual ~Base() {}
        virtual BasePtr clone() const = 0;
    };

    template<typename T>
    class Derived : public Base
    {
    public:
        template<typename U>
        Derived(U&& value) : m_value(std::forward<U>(value)) {}

        virtual BasePtr clone() const override
        {
            return BasePtr(new Derived<T>(m_value));
        }

        T m_value;
    };

    BasePtr clone() const
    {
        if (m_basePtr != nullptr)
        {
            return m_basePtr->clone();
        }
        return nullptr;
    }

    BasePtr m_basePtr;
    std::type_index m_typeIndex;
};

#endif
<commit_msg>Update any<commit_after>#ifndef _ANY_H
#define _ANY_H

#include <iostream>
#include <memory>
#include <typeindex>

class Any
{
public:
    Any() : m_typeIndex(std::type_index(typeid(void))) {}
    Any(Any& other) : m_basePtr(other.clone()), m_typeIndex(other.m_typeIndex) {}
    Any(Any&& other) : m_basePtr(std::move(other.m_basePtr)), m_typeIndex(other.m_typeIndex) {}

    // 创建智能指针时，对于一般的类型，通过std::decay来移除引用和cv符，从而获得原始类型.
    template<typename U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type>
    Any(U&& value) : m_basePtr(new Derived<typename std::decay<U>::type>(std::forward<U>(value))),
        m_typeIndex(std::type_index(typeid(typename std::decay<U>::type))) {}

    bool isNull() const
    {
        return !bool(m_basePtr);
    }

    template<typename U>
    bool is() const
    {
        return m_typeIndex == std::type_index(typeid(U));
    }

    // 将Any转换为实际的类型.
    template<typename U>
    U& anyCast()
    {
        if (!is<U>())
        {
            std::cout << "Can not cast " << typeid(U).name() << " to " << m_typeIndex.name() << std::endl;
            throw std::bad_cast();
        }

        auto dervied = dynamic_cast<Derived<U>*>(m_basePtr.get());
        return dervied->m_value;
    }

    Any& operator=(const Any& other)
    {
        if (m_basePtr == other.m_basePtr)
        {
            return *this;
        }

        m_basePtr = other.clone();
        m_typeIndex = other.m_typeIndex;
        return *this;
    }

private:
    class Base;
    using BasePtr = std::unique_ptr<Base>;

    class Base
    {
    public:
        virtual ~Base() {}
        virtual BasePtr clone() const = 0;
    };

    template<typename T>
    class Derived : public Base
    {
    public:
        template<typename U>
        Derived(U&& value) : m_value(std::forward<U>(value)) {}

        virtual BasePtr clone() const override
        {
            return BasePtr(new Derived<T>(m_value));
        }

        T m_value;
    };

    BasePtr clone() const
    {
        if (m_basePtr != nullptr)
        {
            return m_basePtr->clone();
        }
        return nullptr;
    }

    BasePtr m_basePtr;
    std::type_index m_typeIndex;
};

#endif
<|endoftext|>


<commit_before>#include "nwg_server.h"

namespace Nwg
{

void EVCB::doAccept(evutil_socket_t listener, short event, void *arg)
{
    // printf("doAccept()\n");

    ListenerEventArg *listenerEventArg = (ListenerEventArg *) arg;

    struct event_base *base = listenerEventArg->base;
    Server &server = *listenerEventArg->server;

    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);

    int fd = accept(listener, (struct sockaddr *) &ss, &slen);
    if (fd < 0) {
        perror("accept()");
    } else if (fd > FD_SETSIZE) {
        close(fd);
    } else {
        evutil_make_socket_nonblocking(fd);

        Session *session = new Session(server.getBuffSize(), base, fd, &server);

        server.getHandler().sessionOpened(*session);

        event_add(session->readEvent, NULL);
    }
}

void EVCB::doRead(evutil_socket_t fd, short events, void *arg)
{
    // printf("doRead()\n");

    Session &session = *((Session *) arg);
    Server &server = session.getServer();
    ProtocolCodec &protocolCodec = server.getProtocolCodec();
    Handler &handler = server.getHandler();
    ByteBuffer &readBuffer = session.getReadBuffer();

    char buf[SMALL_BUFFSIZE];
    ssize_t result;

    while (1) {
        result = recv(fd, buf, sizeof(buf), 0);
        if (result <= 0)
            break;

        readBuffer.putBytes(buf, result);
    }

    readBuffer.flip();

    Nwg::ObjectContainer oc;
    protocolCodec.encode(session.getReadBuffer(), oc);

    handler.messageReceived(session, oc.getObject());

    if (session.isClosed()) {
        close(fd);
        handler.sessionClosed(session);
        delete &session;

        return;
    }

    event_add(session.writeEvent, NULL);
}

void EVCB::doWrite(evutil_socket_t fd, short events, void *arg)
{
    // printf("doWrite()\n");

    Session &session = *((Session *) arg);
    Server &server = session.getServer();
    ProtocolCodec &protocolCodec = server.getProtocolCodec();
    Handler &handler = server.getHandler();
    ByteBuffer &writeBuffer = session.getWriteBuffer();

    protocolCodec.decode(session.getWriteObject(), writeBuffer);

    std::vector<byte> b =  writeBuffer.getBytes(writeBuffer.remaining());
    ssize_t result = send(fd, b.data(), b.size(), 0);

    event_del(session.writeEvent);

    handler.messageSent(session, session.getWriteObject());

    if (session.isClosed()) {
        close(fd);
        handler.sessionClosed(session);
        delete &session;

        return;
    }
}

Server::Server(int port)
    : _protocolCodec(nullptr), _handler(nullptr), _port(port)
{
}

Server::~Server()
{
    _protocolCodec.reset();
    _handler.reset();
}

std::map<std::string, std::shared_ptr<Object>> &Server::globals()
{
    return _globals;
}

void Server::setProtocolCodec(ProtocolCodec *protocolCodec)
{
    _protocolCodec = std::shared_ptr<ProtocolCodec>(protocolCodec);
}

void Server::setHandler(Handler *handler)
{
    _handler = std::shared_ptr<Handler>(handler);
}

ProtocolCodec &Server::getProtocolCodec()
{
    return *_protocolCodec;
}

Handler &Server::getHandler()
{
    return *_handler;
}

int Server::getPort()
{
    return _port;
}

int Server::getBuffSize()
{
    return _buffSize;
}

void Server::setPort(int port)
{
    _port = port;
}

void Server::setBuffSize(int buffSize)
{
    _buffSize = buffSize;
}

void Server::run()
{
    struct sockaddr_in sin;

    struct event_base *base = event_base_new();
    if (!base) {
        perror("event_base_new()");
        return;
    }

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(_port);

    _listener = socket(AF_INET, SOCK_STREAM, 0);
    evutil_make_socket_nonblocking(_listener);

    do {
        int one = 1;
        setsockopt(_listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
    } while(0);

    if (bind(_listener, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
        perror("bind()");
        return;
    }

    if (listen(_listener, 16) < 0) {
        perror("listen()");
        return;
    }

    ListenerEventArg listenerEventArg;
    listenerEventArg.base = base;
    listenerEventArg.server = this;

    _listenerEvent = event_new(base, _listener,
            EV_READ | EV_PERSIST,
            EVCB::doAccept,
            (void *) &listenerEventArg);

    event_add(_listenerEvent, NULL);

    event_base_dispatch(base);
}

} /* namespace Nwg */
<commit_msg>Fix space @ nwg_server.cc:85<commit_after>#include "nwg_server.h"

namespace Nwg
{

void EVCB::doAccept(evutil_socket_t listener, short event, void *arg)
{
    // printf("doAccept()\n");

    ListenerEventArg *listenerEventArg = (ListenerEventArg *) arg;

    struct event_base *base = listenerEventArg->base;
    Server &server = *listenerEventArg->server;

    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);

    int fd = accept(listener, (struct sockaddr *) &ss, &slen);
    if (fd < 0) {
        perror("accept()");
    } else if (fd > FD_SETSIZE) {
        close(fd);
    } else {
        evutil_make_socket_nonblocking(fd);

        Session *session = new Session(server.getBuffSize(), base, fd, &server);

        server.getHandler().sessionOpened(*session);

        event_add(session->readEvent, NULL);
    }
}

void EVCB::doRead(evutil_socket_t fd, short events, void *arg)
{
    // printf("doRead()\n");

    Session &session = *((Session *) arg);
    Server &server = session.getServer();
    ProtocolCodec &protocolCodec = server.getProtocolCodec();
    Handler &handler = server.getHandler();
    ByteBuffer &readBuffer = session.getReadBuffer();

    char buf[SMALL_BUFFSIZE];
    ssize_t result;

    while (1) {
        result = recv(fd, buf, sizeof(buf), 0);
        if (result <= 0)
            break;

        readBuffer.putBytes(buf, result);
    }

    readBuffer.flip();

    Nwg::ObjectContainer oc;
    protocolCodec.encode(session.getReadBuffer(), oc);

    handler.messageReceived(session, oc.getObject());

    if (session.isClosed()) {
        close(fd);
        handler.sessionClosed(session);
        delete &session;

        return;
    }

    event_add(session.writeEvent, NULL);
}

void EVCB::doWrite(evutil_socket_t fd, short events, void *arg)
{
    // printf("doWrite()\n");

    Session &session = *((Session *) arg);
    Server &server = session.getServer();
    ProtocolCodec &protocolCodec = server.getProtocolCodec();
    Handler &handler = server.getHandler();
    ByteBuffer &writeBuffer = session.getWriteBuffer();

    protocolCodec.decode(session.getWriteObject(), writeBuffer);

    std::vector<byte> b = writeBuffer.getBytes(writeBuffer.remaining());
    ssize_t result = send(fd, b.data(), b.size(), 0);

    event_del(session.writeEvent);

    handler.messageSent(session, session.getWriteObject());

    if (session.isClosed()) {
        close(fd);
        handler.sessionClosed(session);
        delete &session;

        return;
    }
}

Server::Server(int port)
    : _protocolCodec(nullptr), _handler(nullptr), _port(port)
{
}

Server::~Server()
{
    _protocolCodec.reset();
    _handler.reset();
}

std::map<std::string, std::shared_ptr<Object>> &Server::globals()
{
    return _globals;
}

void Server::setProtocolCodec(ProtocolCodec *protocolCodec)
{
    _protocolCodec = std::shared_ptr<ProtocolCodec>(protocolCodec);
}

void Server::setHandler(Handler *handler)
{
    _handler = std::shared_ptr<Handler>(handler);
}

ProtocolCodec &Server::getProtocolCodec()
{
    return *_protocolCodec;
}

Handler &Server::getHandler()
{
    return *_handler;
}

int Server::getPort()
{
    return _port;
}

int Server::getBuffSize()
{
    return _buffSize;
}

void Server::setPort(int port)
{
    _port = port;
}

void Server::setBuffSize(int buffSize)
{
    _buffSize = buffSize;
}

void Server::run()
{
    struct sockaddr_in sin;

    struct event_base *base = event_base_new();
    if (!base) {
        perror("event_base_new()");
        return;
    }

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(_port);

    _listener = socket(AF_INET, SOCK_STREAM, 0);
    evutil_make_socket_nonblocking(_listener);

    do {
        int one = 1;
        setsockopt(_listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
    } while(0);

    if (bind(_listener, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
        perror("bind()");
        return;
    }

    if (listen(_listener, 16) < 0) {
        perror("listen()");
        return;
    }

    ListenerEventArg listenerEventArg;
    listenerEventArg.base = base;
    listenerEventArg.server = this;

    _listenerEvent = event_new(base, _listener,
            EV_READ | EV_PERSIST,
            EVCB::doAccept,
            (void *) &listenerEventArg);

    event_add(_listenerEvent, NULL);

    event_base_dispatch(base);
}

} /* namespace Nwg */
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Dan Leinir Turthra Jensen <admin@leinir.dk>
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "keyboardinputcomponent.h"
#include "input/inputmanager.h"

#include <QtCore/QEvent>
#include <QtCore/QDebug>

#include <core/debughelper.h>

REGISTER_OBJECTTYPE(GluonEngine, KeyboardInputComponent);

using namespace GluonEngine;

KeyboardInputComponent::KeyboardInputComponent(QObject* parent)
        : Component(parent)
{
    m_actionHeld = false;
    m_actionStarted = false;
    m_actionStopped = false;

    m_keyCode = KeyboardInputComponent::UNKNOWN;

    m_keyboard = 0;
}

QString
KeyboardInputComponent::category() const
{
    return QString("Input");
}

void KeyboardInputComponent::initialize()
{
    if(!m_keyboard)
        m_keyboard = GluonInput::InputManager::instance()->keyboard();
}

void
KeyboardInputComponent::start()
{
    if(m_keyboard)
    {
        m_keyboard->setEnabled(true);
    }
    else
    {
        debug("WARNING! No keyboard found!");
    }
}

void
KeyboardInputComponent::update(int elapsedMilliseconds)
{
    DEBUG_BLOCK
    if(m_actionStarted)
        m_actionStarted = false;

    if(m_actionStopped)
        m_actionStopped = true;

    if(m_keyboard && m_keyboard->buttonPressed(m_keyCode))
    {
        if(!m_actionHeld)
        {
            m_actionStarted = true;
            m_actionHeld = true;
        }
    }
    else
    {
        if(m_actionHeld)
        {
            m_actionStopped = true;
            m_actionHeld = false;
        }
    }
}

void KeyboardInputComponent::stop()
{
    if(m_keyboard) {
        m_keyboard->setEnabled(false);
    }

    m_actionStopped = false;
    m_actionStarted = false;
    m_actionHeld = false;
}

bool
KeyboardInputComponent::isActionStarted()
{
    return m_actionStarted;
}

bool
KeyboardInputComponent::isActionHeld()
{
    return m_actionHeld;
}

bool
KeyboardInputComponent::isActionStopped()
{
    return m_actionStopped;
}

KeyboardInputComponent::KeyName
KeyboardInputComponent::keyCode() const
{
    return m_keyCode;
}

void
KeyboardInputComponent::setKeyCode(KeyboardInputComponent::KeyName newKeyCode)
{
    m_keyCode = newKeyCode;
}

Q_EXPORT_PLUGIN2(gluon_component_keyboardinput, GluonEngine::KeyboardInputComponent);

#include "keyboardinputcomponent.moc"
<commit_msg>Minor fix in KeyboardInputComponent, reset the "ActionStopped" state correctly.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Dan Leinir Turthra Jensen <admin@leinir.dk>
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "keyboardinputcomponent.h"
#include "input/inputmanager.h"

#include <QtCore/QEvent>
#include <QtCore/QDebug>

#include <core/debughelper.h>

REGISTER_OBJECTTYPE(GluonEngine, KeyboardInputComponent);

using namespace GluonEngine;

KeyboardInputComponent::KeyboardInputComponent(QObject* parent)
        : Component(parent)
{
    m_actionHeld = false;
    m_actionStarted = false;
    m_actionStopped = false;

    m_keyCode = KeyboardInputComponent::UNKNOWN;

    m_keyboard = 0;
}

QString
KeyboardInputComponent::category() const
{
    return QString("Input");
}

void KeyboardInputComponent::initialize()
{
    if(!m_keyboard)
        m_keyboard = GluonInput::InputManager::instance()->keyboard();
}

void
KeyboardInputComponent::start()
{
    if(m_keyboard)
    {
        m_keyboard->setEnabled(true);
    }
    else
    {
        debug("WARNING! No keyboard found!");
    }
}

void
KeyboardInputComponent::update(int elapsedMilliseconds)
{
    DEBUG_BLOCK
    if(m_actionStarted)
        m_actionStarted = false;

    if(m_actionStopped)
        m_actionStopped = false;

    if(m_keyboard && m_keyboard->buttonPressed(m_keyCode))
    {
        if(!m_actionHeld)
        {
            m_actionStarted = true;
            m_actionHeld = true;
        }
    }
    else
    {
        if(m_actionHeld)
        {
            m_actionStopped = true;
            m_actionHeld = false;
        }
    }
}

void KeyboardInputComponent::stop()
{
    if(m_keyboard) {
        m_keyboard->setEnabled(false);
    }

    m_actionStopped = false;
    m_actionStarted = false;
    m_actionHeld = false;
}

bool
KeyboardInputComponent::isActionStarted()
{
    return m_actionStarted;
}

bool
KeyboardInputComponent::isActionHeld()
{
    return m_actionHeld;
}

bool
KeyboardInputComponent::isActionStopped()
{
    return m_actionStopped;
}

KeyboardInputComponent::KeyName
KeyboardInputComponent::keyCode() const
{
    return m_keyCode;
}

void
KeyboardInputComponent::setKeyCode(KeyboardInputComponent::KeyName newKeyCode)
{
    m_keyCode = newKeyCode;
}

Q_EXPORT_PLUGIN2(gluon_component_keyboardinput, GluonEngine::KeyboardInputComponent);

#include "keyboardinputcomponent.moc"
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep16/call_host_activate_slave_cores.C $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2016                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

#include    <errl/errlentry.H>
#include    <errno.h>
#include    <initservice/isteps_trace.H>
#include    <isteps/hwpisteperror.H>
#include    <errl/errludtarget.H>

#include    <arch/pirformat.H>
#include    <console/consoleif.H>

//  targeting support
#include    <targeting/common/commontargeting.H>
#include    <targeting/common/utilFilter.H>
#include    <targeting/namedtarget.H>
#include    <fapi2/target.H>
#include    <errl/errlmanager.H>
#include    <sys/task.h>
#include    <sys/misc.h>

#include    <fapi2/plat_hwp_invoker.H>
#include    <p9_cpu_special_wakeup.H>

using   namespace   ERRORLOG;
using   namespace   TARGETING;
using   namespace   ISTEP;
using   namespace   ISTEP_ERROR;
using   namespace   p9specialWakeup;

namespace ISTEP_16
{
void* call_host_activate_slave_cores (void *io_pArgs)
{
    IStepError  l_stepError;

//     errlHndl_t  l_timeout_errl  =   NULL;
    errlHndl_t  l_errl          =   NULL;

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_host_activate_slave_cores entry" );

    // @@@@@    CUSTOM BLOCK:   @@@@@

    uint64_t l_masterCoreID = PIR_t::coreFromPir(task_getcpuid());

    TargetHandleList l_cores;
    getAllChiplets(l_cores, TYPE_CORE);
    uint32_t l_numCores = 0;

    for(TargetHandleList::const_iterator
        l_core = l_cores.begin();
        l_core != l_cores.end();
        ++l_core)
    {
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                   "Iterating all cores in system - "
                   "This is core: %d", l_numCores);
        l_numCores += 1;

        ConstTargetHandle_t l_processor = getParentChip(*l_core);

        CHIP_UNIT_ATTR l_coreId =
                (*l_core)->getAttr<TARGETING::ATTR_CHIP_UNIT>();
        FABRIC_GROUP_ID_ATTR l_logicalGroupId =
          l_processor->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();
        FABRIC_CHIP_ID_ATTR l_chipId =
          l_processor->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
        TARGETING::Target* sys = NULL;
        TARGETING::targetService().getTopLevelTarget(sys);
        assert( sys != NULL );

        const fapi2::Target<fapi2::TARGET_TYPE_CORE> l_fapi2_coreTarget(
              const_cast<TARGETING::Target*> (*l_core));

        //Determine PIR and threads to enable for this core
        uint64_t pir = PIR_t(l_logicalGroupId, l_chipId, l_coreId).word;
        uint64_t en_threads = sys->getAttr<ATTR_ENABLED_THREADS>();
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                   "pir for this core is: %lx", pir);

        if (pir != l_masterCoreID)
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "call_host_activate_slave_cores: Waking %x.",
                       pir );

            int rc = cpu_start_core(pir, en_threads);

            // Handle time out error
            if (-ETIME == rc)
            {
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                        "call_host_activate_slave_cores: "
                        "Time out rc from kernel %d on core %x",
                        rc,
                        pir);

//@TODO RTC:147376
//Spoke with Thi and he said this is not planned for awhile
//FAPI_INVOKE_HWP( l_timeout_errl, proc_check_slw_done,
//l_fapi2_ex_target);
//                 if (l_timeout_errl)
//                 {
//                     TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
//                             "ERROR : proc_check_slw_done" );
//                     // Add chip target info
//                     ErrlUserDetailsTarget(l_processor).addToLog(
//                                                             l_timeout_errl );
//                     // Create IStep error log
//                     l_stepError.addErrorDetails(l_timeout_errl);
//                     // Commit error
//                     errlCommit( l_timeout_errl, HWPF_COMP_ID );
//                     break;
//                 }
//                 else
//                 {
//                     TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
//                             "SUCCESS : proc_check_slw_done - "
//                               "SLW is in clean state");
//                 }
            }
            // Create error log
            if (0 != rc)
            {
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                        "call_host_activate_slave_cores: "
                        "Error from kernel %d on core %x",
                        rc,
                        pir);
                /*@
                  * @errortype
                  * @reasoncode  RC_BAD_RC
                  * @severity    ERRORLOG::ERRL_SEV_UNRECOVERABLE
                  * @moduleid    MOD_HOST_ACTIVATE_SLAVE_CORES
                  * @userdata1   PIR of failing core.
                  * @userdata2   rc of cpu_start_core().
                  *
                  * @devdesc Kernel returned error when trying to activate
                  *          core.
                  */
                errlHndl_t l_errl =
                    new ERRORLOG::ErrlEntry(
                            ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                            MOD_HOST_ACTIVATE_SLAVE_CORES,
                            RC_BAD_RC,
                            pir,
                            rc );

                // Callout core that failed to wake up.
                l_errl->addHwCallout(*l_core,
                        HWAS::SRCI_PRIORITY_MED,
                        HWAS::DECONFIG,
                        HWAS::GARD_Predictive);

                l_stepError.addErrorDetails( l_errl );
                errlCommit( l_errl, HWPF_COMP_ID );
                break;
            }

            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Running p9_cpu_special_wakeup (ENABLE)"
                    " EX target HUID %.8X",
                    TARGETING::get_huid(*l_core));

            // Enable special wakeup on core
            FAPI_INVOKE_HWP( l_errl,
                    p9_cpu_special_wakeup,
                    l_fapi2_coreTarget,
                    SPCWKUP_ENABLE,
                    HOST);

            if( l_errl )
            {
                ErrlUserDetailsTarget(*l_core).addToLog( l_errl );

                // Create IStep error log and cross ref error that
                // occurred
                l_stepError.addErrorDetails( l_errl );

                // Commit Error
                errlCommit( l_errl, HWPF_COMP_ID );

                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                        "ERROR : enable p9_cpu_special_wakeup, "
                        "PLID=0x%x", l_errl->plid()  );
            }
            else
            {
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                        "SUCCESS: enable p9_cpu_special_wakeup");
            }
        }
    }
    // @@@@@    END CUSTOM BLOCK:   @@@@@

#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
    if( l_stepError.isNull() )
    {
        // update firdata inputs for OCC
        TARGETING::Target* masterproc = NULL;
        TARGETING::targetService().masterProcChipTargetHandle(masterproc);
        l_errl = HBOCC::loadHostDataToSRAM(masterproc,
                                            PRDF::ALL_HARDWARE);
        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Error returned from call to HBOCC::loadHostDataToSRAM");

            //Create IStep error log and cross reference error that occurred
            l_stepError.addErrorDetails(l_errl);

            // Commit Error
            errlCommit(l_errl, HWPF_COMP_ID);
        }
    }
#endif

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_host_activate_slave_cores exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_stepError.getErrorHandle();
}

};
<commit_msg>Correctly check for master core during slave wakeup<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep16/call_host_activate_slave_cores.C $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2016                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

#include    <errl/errlentry.H>
#include    <errno.h>
#include    <initservice/isteps_trace.H>
#include    <isteps/hwpisteperror.H>
#include    <errl/errludtarget.H>

#include    <arch/pirformat.H>
#include    <console/consoleif.H>

//  targeting support
#include    <targeting/common/commontargeting.H>
#include    <targeting/common/utilFilter.H>
#include    <targeting/namedtarget.H>
#include    <fapi2/target.H>
#include    <errl/errlmanager.H>
#include    <sys/task.h>
#include    <sys/misc.h>

#include    <fapi2/plat_hwp_invoker.H>
#include    <p9_cpu_special_wakeup.H>

using   namespace   ERRORLOG;
using   namespace   TARGETING;
using   namespace   ISTEP;
using   namespace   ISTEP_ERROR;
using   namespace   p9specialWakeup;

namespace ISTEP_16
{
void* call_host_activate_slave_cores (void *io_pArgs)
{
    IStepError  l_stepError;

//     errlHndl_t  l_timeout_errl  =   NULL;
    errlHndl_t  l_errl          =   NULL;

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_host_activate_slave_cores entry" );

    // @@@@@    CUSTOM BLOCK:   @@@@@

    //track master group/chip/core (no threads)
    uint64_t l_masterPIR_wo_thread = PIR_t(task_getcpuid()).word &
                                     ~PIR_t::THREAD_MASK;

    TargetHandleList l_cores;
    getAllChiplets(l_cores, TYPE_CORE);
    uint32_t l_numCores = 0;

    for(TargetHandleList::const_iterator
        l_core = l_cores.begin();
        l_core != l_cores.end();
        ++l_core)
    {
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                   "Iterating all cores in system - "
                   "This is core: %d", l_numCores);
        l_numCores += 1;

        ConstTargetHandle_t l_processor = getParentChip(*l_core);

        CHIP_UNIT_ATTR l_coreId =
                (*l_core)->getAttr<TARGETING::ATTR_CHIP_UNIT>();
        FABRIC_GROUP_ID_ATTR l_logicalGroupId =
          l_processor->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();
        FABRIC_CHIP_ID_ATTR l_chipId =
          l_processor->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
        TARGETING::Target* sys = NULL;
        TARGETING::targetService().getTopLevelTarget(sys);
        assert( sys != NULL );

        const fapi2::Target<fapi2::TARGET_TYPE_CORE> l_fapi2_coreTarget(
              const_cast<TARGETING::Target*> (*l_core));

        //Determine PIR and threads to enable for this core
        uint64_t pir = PIR_t(l_logicalGroupId, l_chipId, l_coreId).word;
        uint64_t en_threads = sys->getAttr<ATTR_ENABLED_THREADS>();
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                   "pir for this core is: %lx", pir);

        //If not the master core, skip
        if ((pir & ~PIR_t::THREAD_MASK) != l_masterPIR_wo_thread)
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "call_host_activate_slave_cores: Waking %x.",
                       pir );

            int rc = cpu_start_core(pir, en_threads);

            // Handle time out error
            if (-ETIME == rc)
            {
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                        "call_host_activate_slave_cores: "
                        "Time out rc from kernel %d on core %x",
                        rc,
                        pir);

//@TODO RTC:147376
//Spoke with Thi and he said this is not planned for awhile
//FAPI_INVOKE_HWP( l_timeout_errl, proc_check_slw_done,
//l_fapi2_ex_target);
//                 if (l_timeout_errl)
//                 {
//                     TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
//                             "ERROR : proc_check_slw_done" );
//                     // Add chip target info
//                     ErrlUserDetailsTarget(l_processor).addToLog(
//                                                             l_timeout_errl );
//                     // Create IStep error log
//                     l_stepError.addErrorDetails(l_timeout_errl);
//                     // Commit error
//                     errlCommit( l_timeout_errl, HWPF_COMP_ID );
//                     break;
//                 }
//                 else
//                 {
//                     TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
//                             "SUCCESS : proc_check_slw_done - "
//                               "SLW is in clean state");
//                 }
            }
            // Create error log
            if (0 != rc)
            {
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                        "call_host_activate_slave_cores: "
                        "Error from kernel %d on core %x",
                        rc,
                        pir);
                /*@
                  * @errortype
                  * @reasoncode  RC_BAD_RC
                  * @severity    ERRORLOG::ERRL_SEV_UNRECOVERABLE
                  * @moduleid    MOD_HOST_ACTIVATE_SLAVE_CORES
                  * @userdata1   PIR of failing core.
                  * @userdata2   rc of cpu_start_core().
                  *
                  * @devdesc Kernel returned error when trying to activate
                  *          core.
                  */
                errlHndl_t l_errl =
                    new ERRORLOG::ErrlEntry(
                            ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                            MOD_HOST_ACTIVATE_SLAVE_CORES,
                            RC_BAD_RC,
                            pir,
                            rc );

                // Callout core that failed to wake up.
                l_errl->addHwCallout(*l_core,
                        HWAS::SRCI_PRIORITY_MED,
                        HWAS::DECONFIG,
                        HWAS::GARD_Predictive);

                l_stepError.addErrorDetails( l_errl );
                errlCommit( l_errl, HWPF_COMP_ID );
                break;
            }

            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Running p9_cpu_special_wakeup (ENABLE)"
                    " EX target HUID %.8X",
                    TARGETING::get_huid(*l_core));

            // Enable special wakeup on core
            FAPI_INVOKE_HWP( l_errl,
                    p9_cpu_special_wakeup,
                    l_fapi2_coreTarget,
                    SPCWKUP_ENABLE,
                    HOST);

            if( l_errl )
            {
                ErrlUserDetailsTarget(*l_core).addToLog( l_errl );

                // Create IStep error log and cross ref error that
                // occurred
                l_stepError.addErrorDetails( l_errl );

                // Commit Error
                errlCommit( l_errl, HWPF_COMP_ID );

                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                        "ERROR : enable p9_cpu_special_wakeup, "
                        "PLID=0x%x", l_errl->plid()  );
            }
            else
            {
                TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                        "SUCCESS: enable p9_cpu_special_wakeup");
            }
        }
    }
    // @@@@@    END CUSTOM BLOCK:   @@@@@

#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
    if( l_stepError.isNull() )
    {
        // update firdata inputs for OCC
        TARGETING::Target* masterproc = NULL;
        TARGETING::targetService().masterProcChipTargetHandle(masterproc);
        l_errl = HBOCC::loadHostDataToSRAM(masterproc,
                                            PRDF::ALL_HARDWARE);
        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Error returned from call to HBOCC::loadHostDataToSRAM");

            //Create IStep error log and cross reference error that occurred
            l_stepError.addErrorDetails(l_errl);

            // Commit Error
            errlCommit(l_errl, HWPF_COMP_ID);
        }
    }
#endif

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_host_activate_slave_cores exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_stepError.getErrorHandle();
}

};
<|endoftext|>


<commit_before>#include "MiNodeMIC.h"

MiNodeMIC::MiNodeMIC() :
pin(NULL),currentAD(-1),count(0)
{
  this->baseId = MINODE_ID_MODULE_LIGHT;
  system_timer_add_component(this);
}

MiNodeMIC::~MiNodeMIC()
{
  if(pin) {
    delete pin;
  }
  system_timer_remove_component(this);
}

void MiNodeMIC::attach(AnalogConnName connName)
{
  if(this->cn != MN_NC) {
    return;
  }

  MiNodeComponent::initAConnector(connName);

  PinName pinName = MiNodeConn::calcP0Name(this->cna);
  if(pin) {
    delete pin;
  }
  pin = new AnalogIn(pinName);
}

void MiNodeMIC::systemTick()
{
  count++;
  int temp_ad=0;

  if (count == 20)
  {
    temp_ad = getADvalue();
    if (currentAD == -1)
    {
      currentAD = temp_ad;
    }
    else
    {
      if ((temp_ad - currentAD > MINODE_MIC_NOISE_THRESHOLD) || (temp_ad - currentAD < (0-MINODE_MIC_NOISE_THRESHOLD)))
      {
        MicroBitEvent evt(this->baseId + this->id,MINODE_MIC_EVT_NOISE);
        currentAD = temp_ad;
      }
    }
    count = 0;
  }
}

unsigned int MiNodeMIC::getADvalue()
{
  unsigned int temp=0;

  for (int i = 0; i < 2; ++i)
  {
    temp+=pin->read_u16();
  }
  temp /= 2;

  return temp;
}

int MiNodeMIC::getMicLevel()
{
  unsigned int temp=0;
  temp = getADvalue();

  if ((temp > MICROBIT_MIC_MIN) && (temp < MICROBIT_MIC_LEVEL_A+1))
  {
    return MICROBIT_MIC_LEVEL_1;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_A) && (temp < MICROBIT_MIC_LEVEL_B+1))
  {
    return MICROBIT_MIC_LEVEL_2;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_B) && (temp < MICROBIT_MIC_LEVEL_C+1))
  {
    return MICROBIT_MIC_LEVEL_3;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_C) && (temp < MICROBIT_MIC_LEVEL_D+1))
  {
    return MICROBIT_MIC_LEVEL_4;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_D) && (temp < MICROBIT_MIC_MAX+1))
  {
    return MICROBIT_MIC_LEVEL_5;
  }
  else
  {
    return MICROBIT_MIC_LEVEL_ERROR;
  }
}

<commit_msg>modify the Sounde Sensor<commit_after>#include "MiNodeMIC.h"

MiNodeMIC::MiNodeMIC() :
pin(NULL),currentAD(-1),count(0)
{
  this->baseId = MINODE_ID_MODULE_LIGHT;
  system_timer_add_component(this);
}

MiNodeMIC::~MiNodeMIC()
{
  if(pin) {
    delete pin;
  }
  system_timer_remove_component(this);
}

void MiNodeMIC::attach(AnalogConnName connName)
{
  if(this->cn != MN_NC) {
    return;
  }

  MiNodeComponent::initAConnector(connName);

  PinName pinName = MiNodeConn::calcP0Name(this->cna);
  if(pin) {
    delete pin;
  }
  pin = new AnalogIn(pinName);
}

void MiNodeMIC::systemTick()
{
  count++;
  int temp_ad=0;

  if (count == 20)
  {
    temp_ad = getADvalue();
    if (currentAD == -1)
    {
      currentAD = temp_ad;
    }
    else
    {
      if ((temp_ad - currentAD > MINODE_MIC_NOISE_THRESHOLD) || (temp_ad - currentAD < (0-MINODE_MIC_NOISE_THRESHOLD)))
      {
        MicroBitEvent evt(this->baseId + this->id,MINODE_MIC_EVT_NOISE);
        currentAD = temp_ad;
      }
    }
    count = 0;
  }
}

unsigned int MiNodeMIC::getADvalue()
{
  unsigned long temp=0;

  for (int i = 0; i < 32; ++i)
  {
    temp+=pin->read_u16();
  }
  temp >>= 5;

  return temp;
}

int MiNodeMIC::getMicLevel()
{
  unsigned int temp=0;
  temp = getADvalue();

  if ((temp > MICROBIT_MIC_MIN) && (temp < MICROBIT_MIC_LEVEL_A+1))
  {
    return MICROBIT_MIC_LEVEL_1;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_A) && (temp < MICROBIT_MIC_LEVEL_B+1))
  {
    return MICROBIT_MIC_LEVEL_2;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_B) && (temp < MICROBIT_MIC_LEVEL_C+1))
  {
    return MICROBIT_MIC_LEVEL_3;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_C) && (temp < MICROBIT_MIC_LEVEL_D+1))
  {
    return MICROBIT_MIC_LEVEL_4;
  }
  else if ((temp > MICROBIT_MIC_LEVEL_D) && (temp < MICROBIT_MIC_MAX+1))
  {
    return MICROBIT_MIC_LEVEL_5;
  }
  else
  {
    return MICROBIT_MIC_LEVEL_ERROR;
  }
}

<|endoftext|>


<commit_before>#include "MoveDummy.h"
#include "ObjectDummy.h"
#include "BodyDummy.h"
#include "ShapeCapsule.h"

#include "Utils.h"
#include "Engine.h"
#include "Physics.h"
#include "Game.h"
#include "World.h"

#define MOVE_DUMMY_IFPS			(1.0f/100.0f)
#define MOVE_DUMMY_CLAMP           89.9f
#define MOVE_DUMMY_COLLISIONS		1

using namespace MathLib;

CMoveDummy::CMoveDummy()		//캯
{
	m_pObject = new CObjectDummy();		//һʵ
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(0.5f, 1.0f);

	SetCollisionMask(1);
	Clear();
}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "MoveDummy.h"
#include "ObjectDummy.h"
#include "BodyDummy.h"
#include "ShapeCapsule.h"

#include "Utils.h"
#include "Engine.h"
#include "Physics.h"
#include "Game.h"
#include "World.h"

#define MOVE_DUMMY_IFPS			(1.0f/100.0f)
#define MOVE_DUMMY_CLAMP           89.9f
#define MOVE_DUMMY_COLLISIONS		1

using namespace MathLib;

CMoveDummy::CMoveDummy()		//캯
{
	m_pObject = new CObjectDummy();		//һʵ
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(0.5f, 1.0f);

	SetCollisionMask(1);
	Clear();
}

CMoveDummy::~CMoveDummy()
{
	m_pDummy->SetObject(NULL);
	SAFE_DELETE(m_pObject);
	SAFE_DELETE(m_pDummy);
}

<|endoftext|>


<commit_before>
#ifndef AT_FILE_HPP
#define AT_FILE_HPP

#include "atSymbols.h++"

// Microsoft has a different name for the access function.
// The flags for read access, write access, and so on also need to be defined.
#ifdef _MSC_VER
   #include <direct.h>
   #include <io.h>

   #define chdir    _chdir
   #define access   _access
   #define F_OK   0x00
   #define W_OK   0x02
   #define R_OK   0x04

   #define DIRECTORY_SEPARATOR   '\\'
   #define PATH_SEPARATOR        ';'
   #define TMP_DIR               getenv("TEMP")
#elif __ANDROID__
   #include <unistd.h>

   #define DIRECTORY_SEPARATOR   '/'
   #define PATH_SEPARATOR        ':'
   #define TMP_DIR               "/sdcard"
#else
   #include <unistd.h>

   #define DIRECTORY_SEPARATOR   '/'
   #define PATH_SEPARATOR        ':'
   #define TMP_DIR               "/tmp"
#endif

enum atPersonalPathKey
{
   AT_PATH_HOME,
   AT_PATH_DESKTOP,
   AT_PATH_DOCUMENTS,
   AT_PATH_DOWNLOADS,
   AT_PATH_MUSIC,
   AT_PATH_PICTURES,
   AT_PATH_PUBLIC,
   AT_PATH_TEMPLATES,
   AT_PATH_VIDEOS
};

#ifdef __cplusplus
   extern "C"
   {
      ATLAS_SYM bool     isDirectory(char * path);
      ATLAS_SYM bool     createDirectory(char * path);
      ATLAS_SYM int      listFiles(char * path, char ** results, int count);
      ATLAS_SYM char *   getPersonalPath(atPersonalPathKey key);
   }
#else
   ATLAS_SYM bool     isDirectory(char * path);
   ATLAS_SYM bool     createDirectory(char * path);
   ATLAS_SYM int      listFiles(char * path, char ** results, int count);
   ATLAS_SYM char *   getPersonalPath(atPersonalPathKey key);
#endif

#endif

<commit_msg>Added OS-specific constants for executable and icon extensions.<commit_after>
#ifndef AT_FILE_HPP
#define AT_FILE_HPP

#include "atSymbols.h++"

// Microsoft has a different name for the access function.
// The flags for read access, write access, and so on also need to be defined.
#ifdef _MSC_VER
   #include <direct.h>
   #include <io.h>

   #define chdir    _chdir
   #define access   _access
   #define F_OK   0x00
   #define W_OK   0x02
   #define R_OK   0x04

   #define DIRECTORY_SEPARATOR   '\\'
   #define PATH_SEPARATOR        ';'
   #define TMP_DIR               getenv("TEMP")

   #define EXEC_EXTENSION        ".exe"
   #define ICON_EXTENSION        ".ico"
#elif __ANDROID__
   #include <unistd.h>

   #define DIRECTORY_SEPARATOR   '/'
   #define PATH_SEPARATOR        ':'
   #define TMP_DIR               "/sdcard"

   #define EXEC_EXTENSION        ""
   #define ICON_EXTENSION        ".png"
#else
   #include <unistd.h>

   #define DIRECTORY_SEPARATOR   '/'
   #define PATH_SEPARATOR        ':'
   #define TMP_DIR               "/tmp"

   #define EXEC_EXTENSION        ""
   #define ICON_EXTENSION        ".png"
#endif

enum atPersonalPathKey
{
   AT_PATH_HOME,
   AT_PATH_DESKTOP,
   AT_PATH_DOCUMENTS,
   AT_PATH_DOWNLOADS,
   AT_PATH_MUSIC,
   AT_PATH_PICTURES,
   AT_PATH_PUBLIC,
   AT_PATH_TEMPLATES,
   AT_PATH_VIDEOS
};

#ifdef __cplusplus
   extern "C"
   {
      ATLAS_SYM bool     isDirectory(char * path);
      ATLAS_SYM bool     createDirectory(char * path);
      ATLAS_SYM int      listFiles(char * path, char ** results, int count);
      ATLAS_SYM char *   getPersonalPath(atPersonalPathKey key);
   }
#else
   ATLAS_SYM bool     isDirectory(char * path);
   ATLAS_SYM bool     createDirectory(char * path);
   ATLAS_SYM int      listFiles(char * path, char ** results, int count);
   ATLAS_SYM char *   getPersonalPath(atPersonalPathKey key);
#endif

#endif

<|endoftext|>