<commit_before>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <assert.h>

// APPLICATION INCLUDES
#include "os/OsServerTask.h"
#include "os/OsMsg.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
const int OsServerTask::DEF_MAX_MSGS = OsMsgQ::DEF_MAX_MSGS;

// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
OsServerTask::OsServerTask(const UtlString& name,
                           void* pArg,
                           const int maxRequestQMsgs,
                           const int priority,
                           const int options,
                           const int stackSize)
:  OsTask(name, pArg, priority, options, stackSize),
   mIncomingQ(maxRequestQMsgs, OsMsgQ::DEF_MAX_MSG_LEN, OsMsgQ::Q_PRIORITY)

   // other than initialization, no work required
{
/*
   // Only useful when debugging queue problems -- very small case and doesn't
   // warrant spam in general case -- my opinion anyways.

   if (OsSysLog::willLog(FAC_KERNEL, PRI_INFO))
   {

           OsSysLog::add(FAC_KERNEL, PRI_INFO,
                                "OsServerTask::OsServerTask %s queue: %p queue limit: %d",
                                mName.data(), &mIncomingQ, maxRequestQMsgs);
   }
*/
}

// Destructor
// As part of destroying the task, flush all messages from the incoming
// OsMsgQ.
OsServerTask::~OsServerTask()
{
   waitUntilShutDown(20000);  // upto 20 seconds

   mIncomingQ.flush();    // dispose of any messages in the request queue
}

/* ============================ MANIPULATORS ============================== */

// Handle an incoming message.
// This is the message handler of last resort. It should only be called when
// the handleMessage() method in the derived class returns FALSE (indicating
// that the message has not been handled.
UtlBoolean OsServerTask::handleMessage(OsMsg& rMsg)
{
   UtlBoolean handled;

   handled = FALSE;

   switch (rMsg.getMsgType())
   {
   case OsMsg::OS_SHUTDOWN:
      handled = TRUE;
      break;
   default:
      osPrintf(
         "OsServerTask::handleMessage(): msg type is %d.%d, not OS_SHUTDOWN\n",
         rMsg.getMsgType(), rMsg.getMsgSubType());
   //   assert(FALSE);
      break;
   }

   return handled;
}

// Post a message to this task.
// Return the result of the message send operation.
OsStatus OsServerTask::postMessage(const OsMsg& rMsg, const OsTime& rTimeout,
                                   UtlBoolean sentFromISR)
{
   OsStatus res;

   if (sentFromISR)
      res = mIncomingQ.sendFromISR(rMsg);
   else
      res = mIncomingQ.send(rMsg, rTimeout);
   return res;
}

// Call OsTask::requestShutdown() and then post an OS_SHUTDOWN message
// to the incoming message queue to unblock the task.
void OsServerTask::requestShutdown(void)
{
   OsMsg msg(OsMsg::OS_SHUTDOWN, 0);

   OsTask::requestShutdown();
   postMessage(msg);
}

/* ============================ ACCESSORS ================================= */

// Get the pointer to the incoming message queue
OsMsgQ* OsServerTask::getMessageQueue()
{
    return(&mIncomingQ);
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

// Waits for a message to arrive on the task's incoming message queue.
OsStatus OsServerTask::receiveMessage(OsMsg*& rpMsg)
{
   return mIncomingQ.receive(rpMsg);
}

// Waits for a message to arrive on the task's incoming message queue.
OsStatus OsServerTask::receiveMessage(OsMsg*& rpMsg,
                                      const OsTime& rTimeout)
{
   return mIncomingQ.receive(rpMsg, rTimeout);
}

// The entry point for the task.
// This method executes a message processing loop until either
// requestShutdown(), deleteForce(), or the destructor for this object
// is called.
int OsServerTask::run(void* pArg)
{
   UtlBoolean doShutdown;
   OsMsg*    pMsg = NULL;
   OsStatus  res;

   do
   {
      res = receiveMessage((OsMsg*&) pMsg);          // wait for a message
      assert(res == OS_SUCCESS);

      doShutdown = isShuttingDown();
      if (!doShutdown)
      {                                              // comply with shutdown
         if (!handleMessage(*pMsg))                  // process the message
            OsServerTask::handleMessage(*pMsg);
      }

      if (!pMsg->getSentFromISR())
         pMsg->releaseMsg();                         // free the message
   }
   while (!doShutdown);

   ackShutdown();   // acknowledge the task shutdown request
   return 0;        // and then exit
}

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */
<commit_msg>Add assert to postMessage() call in OsServerTask::requestShutdown().<commit_after>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <assert.h>

// APPLICATION INCLUDES
#include "os/OsServerTask.h"
#include "os/OsMsg.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
const int OsServerTask::DEF_MAX_MSGS = OsMsgQ::DEF_MAX_MSGS;

// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
OsServerTask::OsServerTask(const UtlString& name,
                           void* pArg,
                           const int maxRequestQMsgs,
                           const int priority,
                           const int options,
                           const int stackSize)
:  OsTask(name, pArg, priority, options, stackSize),
   mIncomingQ(maxRequestQMsgs, OsMsgQ::DEF_MAX_MSG_LEN, OsMsgQ::Q_PRIORITY)

   // other than initialization, no work required
{
/*
   // Only useful when debugging queue problems -- very small case and doesn't
   // warrant spam in general case -- my opinion anyways.

   if (OsSysLog::willLog(FAC_KERNEL, PRI_INFO))
   {

           OsSysLog::add(FAC_KERNEL, PRI_INFO,
                                "OsServerTask::OsServerTask %s queue: %p queue limit: %d",
                                mName.data(), &mIncomingQ, maxRequestQMsgs);
   }
*/
}

// Destructor
// As part of destroying the task, flush all messages from the incoming
// OsMsgQ.
OsServerTask::~OsServerTask()
{
   waitUntilShutDown(20000);  // upto 20 seconds

   mIncomingQ.flush();    // dispose of any messages in the request queue
}

/* ============================ MANIPULATORS ============================== */

// Handle an incoming message.
// This is the message handler of last resort. It should only be called when
// the handleMessage() method in the derived class returns FALSE (indicating
// that the message has not been handled.
UtlBoolean OsServerTask::handleMessage(OsMsg& rMsg)
{
   UtlBoolean handled;

   handled = FALSE;

   switch (rMsg.getMsgType())
   {
   case OsMsg::OS_SHUTDOWN:
      handled = TRUE;
      break;
   default:
      osPrintf(
         "OsServerTask::handleMessage(): msg type is %d.%d, not OS_SHUTDOWN\n",
         rMsg.getMsgType(), rMsg.getMsgSubType());
   //   assert(FALSE);
      break;
   }

   return handled;
}

// Post a message to this task.
// Return the result of the message send operation.
OsStatus OsServerTask::postMessage(const OsMsg& rMsg, const OsTime& rTimeout,
                                   UtlBoolean sentFromISR)
{
   OsStatus res;

   if (sentFromISR)
      res = mIncomingQ.sendFromISR(rMsg);
   else
      res = mIncomingQ.send(rMsg, rTimeout);
   return res;
}

// Call OsTask::requestShutdown() and then post an OS_SHUTDOWN message
// to the incoming message queue to unblock the task.
void OsServerTask::requestShutdown(void)
{
   OsStatus res;

   OsMsg msg(OsMsg::OS_SHUTDOWN, 0);

   OsTask::requestShutdown();
   res = postMessage(msg);
   assert(res = OS_SUCCESS);
}

/* ============================ ACCESSORS ================================= */

// Get the pointer to the incoming message queue
OsMsgQ* OsServerTask::getMessageQueue()
{
    return(&mIncomingQ);
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

// Waits for a message to arrive on the task's incoming message queue.
OsStatus OsServerTask::receiveMessage(OsMsg*& rpMsg)
{
   return mIncomingQ.receive(rpMsg);
}

// Waits for a message to arrive on the task's incoming message queue.
OsStatus OsServerTask::receiveMessage(OsMsg*& rpMsg,
                                      const OsTime& rTimeout)
{
   return mIncomingQ.receive(rpMsg, rTimeout);
}

// The entry point for the task.
// This method executes a message processing loop until either
// requestShutdown(), deleteForce(), or the destructor for this object
// is called.
int OsServerTask::run(void* pArg)
{
   UtlBoolean doShutdown;
   OsMsg*    pMsg = NULL;
   OsStatus  res;

   do
   {
      res = receiveMessage((OsMsg*&) pMsg);          // wait for a message
      assert(res == OS_SUCCESS);

      doShutdown = isShuttingDown();
      if (!doShutdown)
      {                                              // comply with shutdown
         if (!handleMessage(*pMsg))                  // process the message
            OsServerTask::handleMessage(*pMsg);
      }

      if (!pMsg->getSentFromISR())
         pMsg->releaseMsg();                         // free the message
   }
   while (!doShutdown);

   ackShutdown();   // acknowledge the task shutdown request
   return 0;        // and then exit
}

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/report/CCopasiObject.cpp,v $
   $Revision: 1.28 $
   $Name:  $
   $Author: gasingh $
   $Date: 2004/02/26 00:37:53 $
   End CVS Header */

/**
 * Class CCopasiObject
 *
 * This class is the base class for all global accessible objects in copasi.
 *
 * Copyright Stefan Hoops 2002
 */

#include <sstream>

#include "copasi.h"
#include "CCopasiObjectName.h"
#include "CCopasiObject.h"
#include "CCopasiContainer.h"

const C_FLOAT64 CCopasiObject::DummyValue = 0.0;

CCopasiObject::CCopasiObject():
    mObjectName(),
    mObjectType(),
    mpObjectParent(NULL),
    mObjectFlag(0)
{}

CCopasiObject::CCopasiObject(const std::string & name,
                             const CCopasiContainer * pParent,
                             const std::string & type,
                             const unsigned C_INT32 & flag):
    mObjectName(name),
    mObjectType(type),
    mpObjectParent(const_cast<CCopasiContainer *>(pParent)),
    mObjectFlag(flag)
{
  if (mpObjectParent)
    if (mpObjectParent->isContainer()) mpObjectParent->add(this);
}

CCopasiObject::CCopasiObject(const CCopasiObject & src,
                             const CCopasiContainer * pParent):
    mObjectName(src.mObjectName),
    mObjectType(src.mObjectType),
    mpObjectParent(const_cast<CCopasiContainer *>(pParent)),
    mObjectFlag(src.mObjectFlag)
{if (mpObjectParent) mpObjectParent->add(this);}

CCopasiObject::~CCopasiObject()
{
  if (mpObjectParent)
    mpObjectParent->remove(this);
}

void CCopasiObject::print(std::ostream * ostream) const {(*ostream) << (*this);}

CCopasiObjectName CCopasiObject::getCN() const
  {
    CCopasiObjectName CN;

    if (mpObjectParent)
      {
        std::stringstream tmp;
        tmp << mpObjectParent->getCN();

        if (mpObjectParent->isNameVector())
          tmp << "[" << CCopasiObjectName::escape(mObjectName) << "]";
        else if (mpObjectParent->isVector())
          tmp << "[" << mpObjectParent->getIndex(this) << "]";
        else
          tmp << "," << CCopasiObjectName::escape(mObjectType)
          << "=" << CCopasiObjectName::escape(mObjectName);

        CN = tmp.str();
      }
    else
      {
        CN = CCopasiObjectName::escape(mObjectType)
             + "=" + CCopasiObjectName::escape(mObjectName);
      }

    return CN;
  }

const CCopasiObject *
CCopasiObject::getObject(const CCopasiObjectName & C_UNUSED(cn)) const
  {return NULL;}

const std::string & CCopasiObject::getName() const {return mObjectName;}

const std::string
CCopasiObject::getObjectUniqueNameEx(const bool & isParent) const
  {
    if (isParent && isVector())
      return mpObjectParent->getObjectUniqueNameEx();

    if (mpObjectParent && 0 < (mObjectFlag & NonUniqueName))
      return mObjectName + "{" + mpObjectParent->getObjectUniqueNameEx() + "}";

    return mObjectName;
  }

const std::string CCopasiObject::getObjectUniqueName() const
{return getObjectUniqueNameEx(false);}

bool CCopasiObject::setObjectName(const std::string & name)
{
  if (name == mObjectName) return true;

  if (mpObjectParent && mpObjectParent->isNameVector())
    {
      CCopasiObjectName NewObject = getObjectType() + "=" + name;

      if (mpObjectParent->getObject(NewObject))
        return false;
    }

  mObjectName = name;

  return true;
}

const std::string & CCopasiObject::getObjectName() const {return mObjectName;}

const std::string & CCopasiObject::getObjectType() const {return mObjectType;}

bool CCopasiObject::setObjectParent(const CCopasiContainer * pParent)
{
  mpObjectParent = const_cast<CCopasiContainer *>(pParent);

  return true;
}

CCopasiContainer * CCopasiObject::getObjectParent() const {return mpObjectParent;}

CCopasiContainer *
CCopasiObject::getObjectAncestor(const std::string & type) const
  {
    CCopasiContainer * p = getObjectParent();

    while (p)
      {
        if (p->getObjectType() == type) return p;
        p = p->getObjectParent();
      }

    return NULL;
  }

unsigned C_INT32
CCopasiObject::getIndex(const CCopasiObject * C_UNUSED(pObject)) const
{return C_INVALID_INDEX;}

unsigned C_INT32
CCopasiObject::getIndex(const std::string & C_UNUSED(name)) const
  {return C_INVALID_INDEX;}

void * CCopasiObject::getReference() const
  {return const_cast<CCopasiObject *>(this);}

bool CCopasiObject::isContainer() const
  {return (0 < (mObjectFlag & Container));}

bool CCopasiObject::isVector() const
  {return (0 < (mObjectFlag & Vector));}

bool CCopasiObject::isMatrix() const
  {return (0 < (mObjectFlag & Matrix));}

bool CCopasiObject::isNameVector() const
  {return (0 < (mObjectFlag & NameVector));}

bool CCopasiObject::isReference() const
  {return (0 < (mObjectFlag & Reference));}

bool CCopasiObject::isValueBool() const
  {return (0 < (mObjectFlag & ValueBool));}

bool CCopasiObject::isValueInt() const
  {return (0 < (mObjectFlag & ValueInt));}

bool CCopasiObject::isValueDbl() const
  {return (0 < (mObjectFlag & ValueDbl));}

bool CCopasiObject::isStaticString() const
  {return (0 < (mObjectFlag & StaticString));}

std::ostream &operator<<(std::ostream &os, const CCopasiObject & o)
{
  os << "Name:      " << o.getObjectName() << std::endl;
  os << "Type:      " << o.getObjectType() << std::endl;
  os << "Container: " << o.isContainer() << std::endl;
  os << "Vector:    " << o.isVector() << std::endl;
  os << "VectorN:   " << o.isNameVector() << std::endl;
  os << "Matrix:    " << o.isMatrix() << std::endl;
  os << "Reference: " << o.isReference() << std::endl;
  os << "Bool:      " << o.isValueBool() << std::endl;
  os << "Int:       " << o.isValueInt() << std::endl;
  os << "Dbl:       " << o.isValueDbl() << std::endl;

  return os;
}
<commit_msg>Fixed setObjectName() to update the parent if needed.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/report/CCopasiObject.cpp,v $
   $Revision: 1.29 $
   $Name:  $
   $Author: shoops $
   $Date: 2004/05/07 18:34:26 $
   End CVS Header */

/**
 * Class CCopasiObject
 *
 * This class is the base class for all global accessible objects in copasi.
 *
 * Copyright Stefan Hoops 2002
 */

#include <sstream>

#include "copasi.h"
#include "CCopasiObjectName.h"
#include "CCopasiObject.h"
#include "CCopasiContainer.h"

const C_FLOAT64 CCopasiObject::DummyValue = 0.0;

CCopasiObject::CCopasiObject():
    mObjectName(),
    mObjectType(),
    mpObjectParent(NULL),
    mObjectFlag(0)
{}

CCopasiObject::CCopasiObject(const std::string & name,
                             const CCopasiContainer * pParent,
                             const std::string & type,
                             const unsigned C_INT32 & flag):
    mObjectName(name),
    mObjectType(type),
    mpObjectParent(const_cast<CCopasiContainer *>(pParent)),
    mObjectFlag(flag)
{
  if (mpObjectParent)
    if (mpObjectParent->isContainer()) mpObjectParent->add(this);
}

CCopasiObject::CCopasiObject(const CCopasiObject & src,
                             const CCopasiContainer * pParent):
    mObjectName(src.mObjectName),
    mObjectType(src.mObjectType),
    mpObjectParent(const_cast<CCopasiContainer *>(pParent)),
    mObjectFlag(src.mObjectFlag)
{if (mpObjectParent) mpObjectParent->add(this);}

CCopasiObject::~CCopasiObject()
{
  if (mpObjectParent)
    mpObjectParent->remove(this);
}

void CCopasiObject::print(std::ostream * ostream) const {(*ostream) << (*this);}

CCopasiObjectName CCopasiObject::getCN() const
  {
    CCopasiObjectName CN;

    if (mpObjectParent)
      {
        std::stringstream tmp;
        tmp << mpObjectParent->getCN();

        if (mpObjectParent->isNameVector())
          tmp << "[" << CCopasiObjectName::escape(mObjectName) << "]";
        else if (mpObjectParent->isVector())
          tmp << "[" << mpObjectParent->getIndex(this) << "]";
        else
          tmp << "," << CCopasiObjectName::escape(mObjectType)
          << "=" << CCopasiObjectName::escape(mObjectName);

        CN = tmp.str();
      }
    else
      {
        CN = CCopasiObjectName::escape(mObjectType)
             + "=" + CCopasiObjectName::escape(mObjectName);
      }

    return CN;
  }

const CCopasiObject *
CCopasiObject::getObject(const CCopasiObjectName & C_UNUSED(cn)) const
  {return NULL;}

const std::string & CCopasiObject::getName() const {return mObjectName;}

const std::string
CCopasiObject::getObjectUniqueNameEx(const bool & isParent) const
  {
    if (isParent && isVector())
      return mpObjectParent->getObjectUniqueNameEx();

    if (mpObjectParent && 0 < (mObjectFlag & NonUniqueName))
      return mObjectName + "{" + mpObjectParent->getObjectUniqueNameEx() + "}";

    return mObjectName;
  }

const std::string CCopasiObject::getObjectUniqueName() const
{return getObjectUniqueNameEx(false);}

bool CCopasiObject::setObjectName(const std::string & name)
{
  if (name == mObjectName) return true;

  if (mpObjectParent && mpObjectParent->isNameVector())
    {
      CCopasiObjectName NewObject = getObjectType() + "=" + name;

      if (mpObjectParent->getObject(NewObject))
        return false;
    }

  mObjectName = name;

  if (mpObjectParent)
    {
      mpObjectParent->remove(this);
      mpObjectParent->add(this, false);
    }

  return true;
}

const std::string & CCopasiObject::getObjectName() const {return mObjectName;}

const std::string & CCopasiObject::getObjectType() const {return mObjectType;}

bool CCopasiObject::setObjectParent(const CCopasiContainer * pParent)
{
  mpObjectParent = const_cast<CCopasiContainer *>(pParent);

  return true;
}

CCopasiContainer * CCopasiObject::getObjectParent() const {return mpObjectParent;}

CCopasiContainer *
CCopasiObject::getObjectAncestor(const std::string & type) const
  {
    CCopasiContainer * p = getObjectParent();

    while (p)
      {
        if (p->getObjectType() == type) return p;
        p = p->getObjectParent();
      }

    return NULL;
  }

unsigned C_INT32
CCopasiObject::getIndex(const CCopasiObject * C_UNUSED(pObject)) const
{return C_INVALID_INDEX;}

unsigned C_INT32
CCopasiObject::getIndex(const std::string & C_UNUSED(name)) const
  {return C_INVALID_INDEX;}

void * CCopasiObject::getReference() const
  {return const_cast<CCopasiObject *>(this);}

bool CCopasiObject::isContainer() const
  {return (0 < (mObjectFlag & Container));}

bool CCopasiObject::isVector() const
  {return (0 < (mObjectFlag & Vector));}

bool CCopasiObject::isMatrix() const
  {return (0 < (mObjectFlag & Matrix));}

bool CCopasiObject::isNameVector() const
  {return (0 < (mObjectFlag & NameVector));}

bool CCopasiObject::isReference() const
  {return (0 < (mObjectFlag & Reference));}

bool CCopasiObject::isValueBool() const
  {return (0 < (mObjectFlag & ValueBool));}

bool CCopasiObject::isValueInt() const
  {return (0 < (mObjectFlag & ValueInt));}

bool CCopasiObject::isValueDbl() const
  {return (0 < (mObjectFlag & ValueDbl));}

bool CCopasiObject::isStaticString() const
  {return (0 < (mObjectFlag & StaticString));}

std::ostream &operator<<(std::ostream &os, const CCopasiObject & o)
{
  os << "Name:      " << o.getObjectName() << std::endl;
  os << "Type:      " << o.getObjectType() << std::endl;
  os << "Container: " << o.isContainer() << std::endl;
  os << "Vector:    " << o.isVector() << std::endl;
  os << "VectorN:   " << o.isNameVector() << std::endl;
  os << "Matrix:    " << o.isMatrix() << std::endl;
  os << "Reference: " << o.isReference() << std::endl;
  os << "Bool:      " << o.isValueBool() << std::endl;
  os << "Int:       " << o.isValueInt() << std::endl;
  os << "Dbl:       " << o.isValueDbl() << std::endl;

  return os;
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliCheb2DStackF.h"
#include "AliCheb2DStackS.h"
#include "AliTPCChebCorr.h"
#include "AliLog.h"
#include <TMath.h>

ClassImp(AliTPCChebCorr)

const float AliTPCChebCorr::fgkAngGap = 5e-4; // allow some empty ang. space between sectors
const float AliTPCChebCorr::fgkY2XHSpan = TMath::Tan(TMath::Pi()/AliTPCChebCorr::kNSectors - AliTPCChebCorr::fgkAngGap);

//____________________________________________________________________
AliTPCChebCorr::AliTPCChebCorr()
  : TNamed()
  ,fNStacksSect(0)
  ,fNStacksZSect(0)
  ,fNStacksZ(0)
  ,fNStacks(0)
  ,fZMaxAbs(-1)
  ,fTimeStampStart(0)
  ,fTimeStampEnd(0xffffffff)
  ,fZScaleI(0)
  ,fY2XScaleI(0)
  ,fParams(0)
{
// def. c-tor
}

//____________________________________________________________________
AliTPCChebCorr::AliTPCChebCorr(const char* name, const char* title,
			       int nps, int nzs, float zmaxAbs)
  : TNamed(name,title)
  ,fNStacksSect(0)
  ,fNStacksZSect(0)
  ,fNStacksZ(0)
  ,fNStacks(0)
  ,fZMaxAbs(-1)
  ,fTimeStampStart(0)
  ,fTimeStampEnd(0xffffffff)
  ,fZScaleI(0)
  ,fY2XScaleI(0)
  ,fParams(0)
{
  // c-tor
  SetBinning(nps,nzs,zmaxAbs);
  //
}

//____________________________________________________________________
AliTPCChebCorr::~AliTPCChebCorr()
{
  // d-tor
  if (fParams) for (int i=fNStacks;i--;) delete fParams[i];
  delete[] fParams;
}

//____________________________________________________________________
void AliTPCChebCorr::Parameterize(stFun_t fun,int dimOut,const int np[2],const float* prec)
{
  // build parameterizations for 2->dimout, on the same grid of np[0]xnp[1] points for
  // every output dimension, optionally with prec[i] precision for i-th dimension
  //
  if (TestBit(kParamDone)) {
    AliError("Parameterization is already done");
    return;
  }
  //
  if (fZMaxAbs<0) AliFatal("First the binning and Z limits should be set");
  //
  float bmn[2],bmx[2];
  Bool_t useS = GetUseShortPrec();  // float or short representation for param
  fParams = new AliCheb2DStack*[fNStacks];
  //
  for (int iz=0;iz<fNStacksZ;iz++) {
    bmn[1] = iz/fZScaleI - fZMaxAbs;     // boundaries in Z
    bmx[1] = iz<fNStacksZ-1 ? (iz+1)/fZScaleI - fZMaxAbs : fZMaxAbs;
    for (int isc=0;isc<kNSectors;isc++) {
      fun(isc,0,0);
      for (int isl=0;isl<fNStacksSect;isl++) {
	bmn[0] = -fgkY2XHSpan+isl/fY2XScaleI; // boundaries in phi
	bmx[0] = isl<fNStacksSect-1 ?  -fgkY2XHSpan+(isl+1)/fY2XScaleI : fgkY2XHSpan;
	int id = GetParID(iz,isc,isl);
	AliInfoF("Doing param #%03d Iz:%d Sect:%02d Slice:%d | %+.1f<Z<%+.1f %+.3f<y2x<%+.3f",
		 id,iz,isc,isl,bmn[1],bmx[1],bmn[0],bmx[0]);
	if (useS) fParams[id] = new  AliCheb2DStackS(fun,kNRows,dimOut,bmn,bmx,np,prec);
	else      fParams[id] = new  AliCheb2DStackF(fun,kNRows,dimOut,bmn,bmx,np,prec);
      }
    }
  }
  //
  SetBit(kParamDone);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Parameterize(stFun_t fun,int dimOut,const int np[][2],const float* prec)
{
  // build parameterizations for 2->dimout, on the same grid of np[0]xnp[1] points for
  // every output dimension, optionally with prec[i] precision for i-th dimension
  //
  if (TestBit(kParamDone)) {
    AliError("Parameterization is already done");
    return;
  }
  //
  float bmn[2],bmx[2];
  float y2xMax = TMath::Tan(TMath::Pi()/kNSectors); // half-sector span
  //
  fParams = new AliCheb2DStack*[fNStacks];
  Bool_t useS = GetUseShortPrec();  // float or short representation for param
  //
  for (int iz=0;iz<fNStacksZ;iz++) {
    bmn[1] = iz/fZScaleI-fZMaxAbs;     // boundaries in Z
    bmx[1] = iz<fNStacksZ-1 ? (iz+1)/fZScaleI-fZMaxAbs : fZMaxAbs;
    for (int isc=0;isc<kNSectors;isc++) {
      fun(isc,0,0);
      for (int isl=0;isl<fNStacksSect;isl++) {
	bmn[0] = -y2xMax+isl/fY2XScaleI; // boundaries in phi
	bmx[0] = isl<fNStacksSect-1 ?  -fgkY2XHSpan+(isl+1)/fY2XScaleI : fgkY2XHSpan;
	int id = GetParID(iz,isc,isl);
	AliInfoF("Doing param #%03d Iz:%d Sect:%02d Slice:%d | %+.1f<Z<%+.1f %+.3f<y2x<%+.3f",
		 id,iz,isc,isl,bmn[1],bmx[1],bmn[0],bmx[0]);
	if (useS) fParams[id] = new  AliCheb2DStackS(fun,kNRows,dimOut,bmn,bmx,np,prec);
	else      fParams[id] = new  AliCheb2DStackF(fun,kNRows,dimOut,bmn,bmx,np,prec);
      }
    }
  }
  //
  SetBit(kParamDone);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Eval(int sector, int row, float y2x, float z, float *corr) const
{
  // Calculate correction for point with x,y,z sector corrdinates
  // If sector in 0-71 ROC convention, possible Z-outlying is checked
  int iz = (z+fZMaxAbs)*fZScaleI, side = sector/18;
  sector %= 18;
  // correct for eventual Z calculated in wrong ROC
  if (side)  {if (iz>=fNStacksZSect) iz = fNStacksZSect-1;} // C side
  else       {if (iz<fNStacksZSect)  iz = fNStacksZSect;}   // A side
  if (iz<0) iz=0; else if (iz>=fNStacksZ) iz=fNStacksZ-1;
  int is = (y2x+fgkY2XHSpan)*fY2XScaleI;
  if (is<0) is=0; else if (is>=fNStacksSect) is=fNStacksSect-1;
  float tz[2] = {y2x,z}; // params use row, Y/X, Z
  GetParam(GetParID(iz,sector,is))->Eval(row,tz,corr);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Eval(int sector, int row, float tz[2], float *corr) const
{
  // Calculate correction for point with x,y,z sector corrdinates
  // If sector in 0-71 ROC convention, possible Z-outlying is checked
  int iz = (tz[1]+fZMaxAbs)*fZScaleI,  side = sector/18;
  sector %= 18;
  // correct for eventual Z calculated in wrong ROC
  if (side)  {if (iz>=fNStacksZSect) iz = fNStacksZSect-1;} // C side
  else       {if (iz<fNStacksZSect)  iz = fNStacksZSect;}   // A side
  if (iz<0) iz=0; else if (iz>=fNStacksZ) iz=fNStacksZ-1;
  int is = (tz[0]+fgkY2XHSpan)*fY2XScaleI;
  if (is<0) is=0; else if (is>=fNStacksSect) is=fNStacksSect-1;
  GetParam(GetParID(iz,sector,is))->Eval(row,tz,corr);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Print(const Option_t* opt) const
{
  // print itself
  printf("%s:%s Cheb2D[%c] Param: %d slices in %+.1f<%s<%+.1f %d per sector\n",
	 GetName(),GetTitle(),GetUseFloatPrec()?'F':'S',
	 fNStacksZ,-fZMaxAbs,GetUseZ2R() ? "Z/R":"Z",fZMaxAbs,fNStacksSect);
  printf("Time span: %10d:%10d TimeDependent flag: %s\n",fTimeStampStart,fTimeStampEnd,
	 GetTimeDependent() ? "ON":"OFF");
  TString opts = opt; opts.ToLower();
  if (opts.Contains("p") && TestBit(kParamDone)) {
    for (int iz=0;iz<fNStacksZ;iz++) {
      for (int isc=0;isc<kNSectors;isc++) {
	for (int isl=0;isl<fNStacksSect;isl++) {
	  int id = GetParID(iz,isc,isl);
	  printf("Z%d Sector%02d Slice%d: ",iz,isc,isl);
	  GetParam(id)->Print(opt);
	}
      }
    }
  }
}

//____________________________________________________________________
void AliTPCChebCorr::SetBinning(int nps,int nzs, float zmxAbs)
{
  // set binning, limits
  fNStacksSect = nps;
  fNStacksZSect = nzs;
  fNStacksZ = nzs*2; // nzs is the number of bins per side!
  fZMaxAbs  = zmxAbs;
  fNStacks  = fNStacksZ*fNStacksSect*kNSectors;
  //
  if (zmxAbs<1e-8 || nzs<1 || nps<1) AliFatalF("Wrong settings: |Zmax|:%f Nz:%d Nphi:%d",
					       zmxAbs,nzs,nps);
  fZScaleI   = nzs/zmxAbs;
  fY2XScaleI = nps/(2*TMath::Tan(TMath::Pi()/kNSectors));
  //
}

<commit_msg>18 -> kNSectors<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliCheb2DStackF.h"
#include "AliCheb2DStackS.h"
#include "AliTPCChebCorr.h"
#include "AliLog.h"
#include <TMath.h>

ClassImp(AliTPCChebCorr)

const float AliTPCChebCorr::fgkAngGap = 5e-4; // allow some empty ang. space between sectors
const float AliTPCChebCorr::fgkY2XHSpan = TMath::Tan(TMath::Pi()/AliTPCChebCorr::kNSectors - AliTPCChebCorr::fgkAngGap);

//____________________________________________________________________
AliTPCChebCorr::AliTPCChebCorr()
  : TNamed()
  ,fNStacksSect(0)
  ,fNStacksZSect(0)
  ,fNStacksZ(0)
  ,fNStacks(0)
  ,fZMaxAbs(-1)
  ,fTimeStampStart(0)
  ,fTimeStampEnd(0xffffffff)
  ,fZScaleI(0)
  ,fY2XScaleI(0)
  ,fParams(0)
{
// def. c-tor
}

//____________________________________________________________________
AliTPCChebCorr::AliTPCChebCorr(const char* name, const char* title,
			       int nps, int nzs, float zmaxAbs)
  : TNamed(name,title)
  ,fNStacksSect(0)
  ,fNStacksZSect(0)
  ,fNStacksZ(0)
  ,fNStacks(0)
  ,fZMaxAbs(-1)
  ,fTimeStampStart(0)
  ,fTimeStampEnd(0xffffffff)
  ,fZScaleI(0)
  ,fY2XScaleI(0)
  ,fParams(0)
{
  // c-tor
  SetBinning(nps,nzs,zmaxAbs);
  //
}

//____________________________________________________________________
AliTPCChebCorr::~AliTPCChebCorr()
{
  // d-tor
  if (fParams) for (int i=fNStacks;i--;) delete fParams[i];
  delete[] fParams;
}

//____________________________________________________________________
void AliTPCChebCorr::Parameterize(stFun_t fun,int dimOut,const int np[2],const float* prec)
{
  // build parameterizations for 2->dimout, on the same grid of np[0]xnp[1] points for
  // every output dimension, optionally with prec[i] precision for i-th dimension
  //
  if (TestBit(kParamDone)) {
    AliError("Parameterization is already done");
    return;
  }
  //
  if (fZMaxAbs<0) AliFatal("First the binning and Z limits should be set");
  //
  float bmn[2],bmx[2];
  Bool_t useS = GetUseShortPrec();  // float or short representation for param
  fParams = new AliCheb2DStack*[fNStacks];
  //
  for (int iz=0;iz<fNStacksZ;iz++) {
    bmn[1] = iz/fZScaleI - fZMaxAbs;     // boundaries in Z
    bmx[1] = iz<fNStacksZ-1 ? (iz+1)/fZScaleI - fZMaxAbs : fZMaxAbs;
    for (int isc=0;isc<kNSectors;isc++) {
      fun(isc,0,0);
      for (int isl=0;isl<fNStacksSect;isl++) {
	bmn[0] = -fgkY2XHSpan+isl/fY2XScaleI; // boundaries in phi
	bmx[0] = isl<fNStacksSect-1 ?  -fgkY2XHSpan+(isl+1)/fY2XScaleI : fgkY2XHSpan;
	int id = GetParID(iz,isc,isl);
	AliInfoF("Doing param #%03d Iz:%d Sect:%02d Slice:%d | %+.1f<Z<%+.1f %+.3f<y2x<%+.3f",
		 id,iz,isc,isl,bmn[1],bmx[1],bmn[0],bmx[0]);
	if (useS) fParams[id] = new  AliCheb2DStackS(fun,kNRows,dimOut,bmn,bmx,np,prec);
	else      fParams[id] = new  AliCheb2DStackF(fun,kNRows,dimOut,bmn,bmx,np,prec);
      }
    }
  }
  //
  SetBit(kParamDone);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Parameterize(stFun_t fun,int dimOut,const int np[][2],const float* prec)
{
  // build parameterizations for 2->dimout, on the same grid of np[0]xnp[1] points for
  // every output dimension, optionally with prec[i] precision for i-th dimension
  //
  if (TestBit(kParamDone)) {
    AliError("Parameterization is already done");
    return;
  }
  //
  float bmn[2],bmx[2];
  float y2xMax = TMath::Tan(TMath::Pi()/kNSectors); // half-sector span
  //
  fParams = new AliCheb2DStack*[fNStacks];
  Bool_t useS = GetUseShortPrec();  // float or short representation for param
  //
  for (int iz=0;iz<fNStacksZ;iz++) {
    bmn[1] = iz/fZScaleI-fZMaxAbs;     // boundaries in Z
    bmx[1] = iz<fNStacksZ-1 ? (iz+1)/fZScaleI-fZMaxAbs : fZMaxAbs;
    for (int isc=0;isc<kNSectors;isc++) {
      fun(isc,0,0);
      for (int isl=0;isl<fNStacksSect;isl++) {
	bmn[0] = -y2xMax+isl/fY2XScaleI; // boundaries in phi
	bmx[0] = isl<fNStacksSect-1 ?  -fgkY2XHSpan+(isl+1)/fY2XScaleI : fgkY2XHSpan;
	int id = GetParID(iz,isc,isl);
	AliInfoF("Doing param #%03d Iz:%d Sect:%02d Slice:%d | %+.1f<Z<%+.1f %+.3f<y2x<%+.3f",
		 id,iz,isc,isl,bmn[1],bmx[1],bmn[0],bmx[0]);
	if (useS) fParams[id] = new  AliCheb2DStackS(fun,kNRows,dimOut,bmn,bmx,np,prec);
	else      fParams[id] = new  AliCheb2DStackF(fun,kNRows,dimOut,bmn,bmx,np,prec);
      }
    }
  }
  //
  SetBit(kParamDone);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Eval(int sector, int row, float y2x, float z, float *corr) const
{
  // Calculate correction for point with x,y,z sector corrdinates
  // If sector in 0-71 ROC convention, possible Z-outlying is checked
  int iz = (z+fZMaxAbs)*fZScaleI, side = sector/kNSectors;
  sector %= kNSectors;
  // correct for eventual Z calculated in wrong ROC
  if (side)  {if (iz>=fNStacksZSect) iz = fNStacksZSect-1;} // C side
  else       {if (iz<fNStacksZSect)  iz = fNStacksZSect;}   // A side
  if (iz<0) iz=0; else if (iz>=fNStacksZ) iz=fNStacksZ-1;
  int is = (y2x+fgkY2XHSpan)*fY2XScaleI;
  if (is<0) is=0; else if (is>=fNStacksSect) is=fNStacksSect-1;
  float tz[2] = {y2x,z}; // params use row, Y/X, Z
  GetParam(GetParID(iz,sector,is))->Eval(row,tz,corr);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Eval(int sector, int row, float tz[2], float *corr) const
{
  // Calculate correction for point with x,y,z sector corrdinates
  // If sector in 0-71 ROC convention, possible Z-outlying is checked
  int iz = (tz[1]+fZMaxAbs)*fZScaleI,  side = sector/kNSectors;
  sector %= kNSectors;
  // correct for eventual Z calculated in wrong ROC
  if (side)  {if (iz>=fNStacksZSect) iz = fNStacksZSect-1;} // C side
  else       {if (iz<fNStacksZSect)  iz = fNStacksZSect;}   // A side
  if (iz<0) iz=0; else if (iz>=fNStacksZ) iz=fNStacksZ-1;
  int is = (tz[0]+fgkY2XHSpan)*fY2XScaleI;
  if (is<0) is=0; else if (is>=fNStacksSect) is=fNStacksSect-1;
  GetParam(GetParID(iz,sector,is))->Eval(row,tz,corr);
  //
}

//____________________________________________________________________
void AliTPCChebCorr::Print(const Option_t* opt) const
{
  // print itself
  printf("%s:%s Cheb2D[%c] Param: %d slices in %+.1f<%s<%+.1f %d per sector\n",
	 GetName(),GetTitle(),GetUseFloatPrec()?'F':'S',
	 fNStacksZ,-fZMaxAbs,GetUseZ2R() ? "Z/R":"Z",fZMaxAbs,fNStacksSect);
  printf("Time span: %10d:%10d TimeDependent flag: %s\n",fTimeStampStart,fTimeStampEnd,
	 GetTimeDependent() ? "ON":"OFF");
  TString opts = opt; opts.ToLower();
  if (opts.Contains("p") && TestBit(kParamDone)) {
    for (int iz=0;iz<fNStacksZ;iz++) {
      for (int isc=0;isc<kNSectors;isc++) {
	for (int isl=0;isl<fNStacksSect;isl++) {
	  int id = GetParID(iz,isc,isl);
	  printf("Z%d Sector%02d Slice%d: ",iz,isc,isl);
	  GetParam(id)->Print(opt);
	}
      }
    }
  }
}

//____________________________________________________________________
void AliTPCChebCorr::SetBinning(int nps,int nzs, float zmxAbs)
{
  // set binning, limits
  fNStacksSect = nps;
  fNStacksZSect = nzs;
  fNStacksZ = nzs*2; // nzs is the number of bins per side!
  fZMaxAbs  = zmxAbs;
  fNStacks  = fNStacksZ*fNStacksSect*kNSectors;
  //
  if (zmxAbs<1e-8 || nzs<1 || nps<1) AliFatalF("Wrong settings: |Zmax|:%f Nz:%d Nphi:%d",
					       zmxAbs,nzs,nps);
  fZScaleI   = nzs/zmxAbs;
  fY2XScaleI = nps/(2*TMath::Tan(TMath::Pi()/kNSectors));
  //
}

<|endoftext|>


<commit_before>#include "CHBulk.h"

template<>
InputParameters validParams<CHBulk>()
{
  InputParameters params = validParams<KernelGrad>();
  params.addParam<std::string>("mob_name","M","The mobility used with the kernel");

  return params;
}

CHBulk::CHBulk(const std::string & name, InputParameters parameters)
  :KernelGrad(name, parameters),
   _mob_name(getParam<std::string>("mob_name")),
   _M(getMaterialProperty<Real>(_mob_name))
{
}

RealGradient
CHBulk::computeGradDFDCons(PFFunctionType type)
{
  switch (type)
  {
  case Residual:
    return 3*_u[_qp]*_u[_qp]*_grad_u[_qp] - _grad_u[_qp]; // return Residual value

  case Jacobian:
    return 6*_u[_qp]*_phi[_j][_qp]*_grad_u[_qp] + 3*_u[_qp]*_u[_qp]*_grad_phi[_j][_qp] - _grad_phi[_j][_qp]; //return Jacobian value

  }

  mooseError("Invalid type passed in");
}

RealGradient
CHBulk::precomputeQpResidual()
{
  return _M[_qp] * computeGradDFDCons(Residual);
}

RealGradient
CHBulk::precomputeQpJacobian()
{
  return _M[_qp] * computeGradDFDCons(Jacobian);
}
<commit_msg>r2857 dd8cd9ef-2931-0410-98ca-75ad22d19dd1<commit_after>#include "CHBulk.h"

template<>
InputParameters validParams<CHBulk>()
{
  InputParameters params = validParams<KernelGrad>();
  params.addParam<std::string>("mob_name","M","The mobility used with the kernel");

  return params;
}

CHBulk::CHBulk(const std::string & name, InputParameters parameters)
  :KernelGrad(name, parameters),
   _mob_name(getParam<std::string>("mob_name")),
   _M(getMaterialProperty<Real>(_mob_name))
{
}

RealGradient
CHBulk::computeGradDFDCons(PFFunctionType type)
{
  switch (type)
  {
  case Residual:
    return 3*_u[_qp]*_u[_qp]*_grad_u[_qp] - _grad_u[_qp]; // return Residual value

  case Jacobian:
    return 6*_u[_qp]*_phi[_j][_qp]*_grad_u[_qp] + 3*_u[_qp]*_u[_qp]*_grad_phi[_j][_qp] - _grad_phi[_j][_qp]; //return Jacobian value
    //return 0.0;

  }

  mooseError("Invalid type passed in");
}

RealGradient
CHBulk::precomputeQpResidual()
{
  return _M[_qp] * computeGradDFDCons(Residual);
}

RealGradient
CHBulk::precomputeQpJacobian()
{
  return _M[_qp] * computeGradDFDCons(Jacobian);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dpoCKernel.h"

#include "dpo_debug.h"
#include "dpoCData.h"
#include "dpoCContext.h"
#include "nsMemory.h"
#include "dpo_security_checks_stub.h"

#include "nsIClassInfoImpl.h"

#ifdef WINDOWS_ROUNDTRIP
#include "windows.h"
#endif /* WINDOWS_ROUNDTRIP */

/*
 * Implement ClassInfo support to make this class feel more like a JavaScript class, i.e.,
 * it is autmatically casted to the right interface and all methods are available
 * without using QueryInterface.
 *
 * see https://developer.mozilla.org/en/Using_nsIClassInfo
 */
NS_IMPL_CLASSINFO( dpoCKernel, 0, 0, DPO_KERNEL_CID)
NS_IMPL_CI_INTERFACE_GETTER2(dpoCKernel, dpoIKernel, nsISecurityCheckedComponent)

/*
 * Implement the hooks for the cycle collector
 */
NS_IMPL_CYCLE_COLLECTION_CLASS(dpoCKernel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(dpoCKernel)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(parent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(dpoCKernel)
NS_IMPL_CYCLE_COLLECTION_TRACE_END

NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(dpoCKernel)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(parent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(dpoCKernel)
  NS_INTERFACE_MAP_ENTRY(dpoIKernel)
  NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, dpoIKernel)
  NS_IMPL_QUERY_CLASSINFO(dpoCKernel)
NS_INTERFACE_MAP_END

NS_IMPL_CYCLE_COLLECTING_ADDREF(dpoCKernel)
NS_IMPL_CYCLE_COLLECTING_RELEASE(dpoCKernel)

DPO_SECURITY_CHECKS_ALL( dpoCKernel)

dpoCKernel::dpoCKernel(dpoIContext *aParent)
{
	DEBUG_LOG_CREATE("dpoCKernel", this);
	parent = aParent;
	kernel = NULL;
	cmdQueue = NULL;
}

dpoCKernel::~dpoCKernel()
{
	DEBUG_LOG_DESTROY("dpoCKernel", this);
	if (kernel != NULL) {
		clReleaseKernel(kernel);
	}
	parent = NULL;
}

nsresult dpoCKernel::InitKernel(cl_command_queue aCmdQueue, cl_kernel aKernel, cl_mem aFailureMem)
{
	cl_int err_code;

	kernel = aKernel;
	err_code = clRetainCommandQueue( aCmdQueue);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("initCData", err_code);
		return NS_ERROR_NOT_AVAILABLE;
	}
	cmdQueue = aCmdQueue;

	failureMem = aFailureMem;

	err_code = clSetKernelArg(kernel, 0, sizeof(cl_mem), &failureMem);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("initCData", err_code);
		return NS_ERROR_NOT_AVAILABLE;
	}

	return NS_OK;
}

/* readonly attribute uint32_t numberOfArgs; */
NS_IMETHODIMP dpoCKernel::GetNumberOfArgs(uint32_t *aNumberOfArgs)
{
	cl_uint result;
	cl_int err_code;

	err_code = clGetKernelInfo(kernel, CL_KERNEL_NUM_ARGS, sizeof(cl_uint), &result, NULL);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("GetNumberOfArgs", err_code);
		return NS_ERROR_NOT_AVAILABLE;
	}

	/* skip internal arguments when counting */
	*aNumberOfArgs = result - DPO_NUMBER_OF_ARTIFICIAL_ARGS;

    return NS_OK;
}

/* void setArgument (in uint32_t number, in dpoIData argument); */
NS_IMETHODIMP dpoCKernel::SetArgument(uint32_t number, dpoIData *argument)
{
	cl_int err_code;
	cl_mem buffer;

	/* skip internal arguments */
	number = number + DPO_NUMBER_OF_ARTIFICIAL_ARGS;

	buffer = ((dpoCData *) argument)->GetContainedBuffer();
	DEBUG_LOG_STATUS("SetArgument", "buffer is " << buffer);

	err_code = clSetKernelArg(kernel, number, sizeof(cl_mem), &buffer);

	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("SetArgument", err_code);
		return NS_ERROR_INVALID_ARG;
	}

    return NS_OK;
}

// High precision is true when arguments are passed as doubles and false when passed as floats.
/* void setScalarArgument (in uint32_t number, in jsval argument); */
NS_IMETHODIMP dpoCKernel::SetScalarArgument(uint32_t number, const jsval & argument,
	const jsval & isInteger, const jsval & highPrecision)
{
	cl_int err_code;
	bool isIntegerB;
	bool isHighPrecisionB;

	/* skip internal arguments */
	number = number + DPO_NUMBER_OF_ARTIFICIAL_ARGS;

	if (!JSVAL_IS_BOOLEAN(isInteger)) {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal isInteger argument.");

		return NS_ERROR_INVALID_ARG;
	}
	isIntegerB = JSVAL_TO_BOOLEAN(isInteger);

	if (!JSVAL_IS_BOOLEAN(highPrecision)) {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal highPrecision argument.");

		return NS_ERROR_INVALID_ARG;
	}
	isHighPrecisionB = JSVAL_TO_BOOLEAN(highPrecision);

	if (!JSVAL_IS_NUMBER(argument)) {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal number argument.");

		return NS_ERROR_INVALID_ARG;
	}

	if (JSVAL_IS_INT(argument)) {
		int value = JSVAL_TO_INT(argument);
		DEBUG_LOG_STATUS("SetScalarArgument", "(JSVAL_IS_INT(argument)) isIntegerB: " << isIntegerB  << " isHighPrecisionB " << isHighPrecisionB);

		if (isIntegerB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "(JSVAL_IS_INT(argument)) setting integer argument " << number << " to integer value " << value);
			cl_int intVal = (cl_int) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_int), &intVal);
		} else if (isHighPrecisionB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting double argument " << number << " to integer value " << value);
			cl_double doubleVal = (cl_double) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_double), &doubleVal);
		} else {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting float argument " << number << " to integer value " << value);
			cl_float floatVal = (cl_float) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_float), &floatVal);
		}

		if (err_code != CL_SUCCESS) {
			DEBUG_LOG_ERROR("SetScalarArgument", err_code);
			return NS_ERROR_NOT_AVAILABLE;
		}
	} else if (JSVAL_IS_DOUBLE(argument)) {
		double value = JSVAL_TO_DOUBLE(argument);
		DEBUG_LOG_STATUS("SetScalarArgument", "(JSVAL_IS_DOUBLE(argument)) isIntegerB: " << isIntegerB  << " isHighPrecisionB " << isHighPrecisionB);

		if (isIntegerB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting int formal argument " << number << " using double value " << value);
			cl_int intVal = (cl_int) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_int), &intVal);
		} else if (isHighPrecisionB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting double formal argument " << number << " using double value " << value);
			cl_double doubleVal = (cl_double) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_double), &doubleVal);
		} else {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting float formal argument " << number << " using double value " << value);
			cl_float floatVal = (cl_float) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_float), &floatVal);
		}

		if (err_code != CL_SUCCESS) {
			DEBUG_LOG_ERROR("SetScalarArgument", err_code);
			return NS_ERROR_NOT_AVAILABLE;
		}
	} else {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal number argument.");

		return NS_ERROR_INVALID_ARG;
	}

	return NS_OK;
}

/* uint32_t run (in uint32_t rank, [array, size_is (rank)] in uint32_t shape, [array, size_is (rank), optional] in uint32_t tile); */
NS_IMETHODIMP dpoCKernel::Run(uint32_t rank, uint32_t *shape, uint32_t *tile, uint32_t *_retval)
{
	cl_int err_code;
	cl_event runEvent, readEvent, writeEvent;
	size_t *global_work_size;
	size_t *local_work_size;
	const int zero = 0;

	DEBUG_LOG_STATUS("Run", "preparing execution of kernel");

    if (sizeof(size_t) == sizeof(uint32_t)) {
		global_work_size = (size_t *) shape;
	} else {
		global_work_size = (size_t *) nsMemory::Alloc(rank * sizeof(size_t));
		if (global_work_size == NULL) {
			DEBUG_LOG_STATUS("Run", "allocation of global_work_size failed");
			return NS_ERROR_OUT_OF_MEMORY;
		}
		for (int cnt = 0; cnt < rank; cnt++) {
			global_work_size[cnt] = shape[cnt];
		}
	}

#ifdef USE_LOCAL_WORKSIZE
	if (tile == NULL) {
		local_work_size = NULL;
	} else {
		if ((sizeof(size_t) == sizeof(uint32_t))) {
			local_work_size = (size_t *) tile;
		} else {
			local_work_size = (size_t *) nsMemory::Alloc(rank * sizeof(size_t));
			if (local_work_size == NULL) {
				DEBUG_LOG_STATUS("Run", "allocation of local_work_size failed");
				return NS_ERROR_OUT_OF_MEMORY;
			}
			for (int cnt = 0; cnt < rank; cnt++) {
				local_work_size[cnt] = (size_t) tile[cnt];
			}
		}
	}
#else /* USE_LOCAL_WORKSIZE */
	local_work_size = NULL;
#endif /* USE_LOCAL_WORKSIZE */

	DEBUG_LOG_STATUS("Run", "setting failure code to 0");

	err_code = clEnqueueWriteBuffer(cmdQueue, failureMem, CL_FALSE, 0, sizeof(int), &zero, 0, NULL, &writeEvent);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "enqueing execution of kernel");

#ifdef WINDOWS_ROUNDTRIP
	dpoCContext::RecordBeginOfRoundTrip(parent);
#endif /* WINDOWS_ROUNDTRIP */

	err_code = clEnqueueNDRangeKernel(cmdQueue, kernel, rank, NULL, global_work_size, NULL, 1, &writeEvent, &runEvent);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "reading failure code");

	err_code = clEnqueueReadBuffer(cmdQueue, failureMem, CL_FALSE, 0, sizeof(int), _retval, 1, &runEvent, &readEvent);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "waiting for execution to finish");

	// For now we always wait for the run to complete.
	// In the long run, we may want to interleave this with JS execution and only sync on result read.
	err_code = clWaitForEvents( 1, &readEvent);

	DEBUG_LOG_STATUS("Run", "first event fired");

	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}
#ifdef WINDOWS_ROUNDTRIP
	dpoCContext::RecordEndOfRoundTrip(parent);
#endif /* WINDOWS_ROUNDTRIP */

#ifdef CLPROFILE
#ifdef CLPROFILE_ASYNC
	err_code = clSetEventCallback( readEvent, CL_COMPLETE, &dpoCContext::CollectTimings, parent);

	DEBUG_LOG_STATUS("Run", "second event fired");
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}
#else /* CLPROFILE_ASYNC */
	dpoCContext::CollectTimings(readEvent,CL_COMPLETE,parent);
#endif /* CLPROFILE_ASYNC */
#endif /* CLPROFILE */

	DEBUG_LOG_STATUS("Run", "execution completed successfully, start cleanup");

	if (global_work_size != (size_t *) shape) {
		nsMemory::Free(global_work_size);
	}
#ifdef USE_LOCAL_WORKSIZE
	if (local_work_size != (size_t *) tile) {
		nsMemory::Free(local_work_size);
	}
#endif /* USE_LOCAL_WORKSIZE */

	err_code = clReleaseEvent(readEvent);
	err_code = clReleaseEvent(runEvent);
	err_code = clReleaseEvent(writeEvent);

	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "cleanup complete");

    return NS_OK;
}
<commit_msg>Update dpoCKernel.cpp<commit_after>/*
 * Copyright (c) 2011, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dpoCKernel.h"

#include "dpo_debug.h"
#include "dpoCData.h"
#include "dpoCContext.h"
#include "nsMemory.h"
#include "dpo_security_checks_stub.h"

#include "nsIClassInfoImpl.h"

#ifdef WINDOWS_ROUNDTRIP
#include "windows.h"
#endif /* WINDOWS_ROUNDTRIP */

/*
 * Implement ClassInfo support to make this class feel more like a JavaScript class, i.e.,
 * it is autmatically casted to the right interface and all methods are available
 * without using QueryInterface.
 *
 * see https://developer.mozilla.org/en/Using_nsIClassInfo
 */
NS_IMPL_CLASSINFO( dpoCKernel, 0, 0, DPO_KERNEL_CID)
NS_IMPL_CI_INTERFACE_GETTER2(dpoCKernel, dpoIKernel, nsISecurityCheckedComponent)

/*
 * Implement the hooks for the cycle collector
 */
NS_IMPL_CYCLE_COLLECTION_CLASS(dpoCKernel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(dpoCKernel)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(parent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(dpoCKernel)
NS_IMPL_CYCLE_COLLECTION_TRACE_END

NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(dpoCKernel)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(parent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(dpoCKernel)
  NS_INTERFACE_MAP_ENTRY(dpoIKernel)
  NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, dpoIKernel)
  NS_IMPL_QUERY_CLASSINFO(dpoCKernel)
NS_INTERFACE_MAP_END

NS_IMPL_CYCLE_COLLECTING_ADDREF(dpoCKernel)
NS_IMPL_CYCLE_COLLECTING_RELEASE(dpoCKernel)

DPO_SECURITY_CHECKS_ALL( dpoCKernel)

dpoCKernel::dpoCKernel(dpoIContext *aParent)
{
	DEBUG_LOG_CREATE("dpoCKernel", this);
	parent = aParent;
	kernel = NULL;
	cmdQueue = NULL;
}

dpoCKernel::~dpoCKernel()
{
	DEBUG_LOG_DESTROY("dpoCKernel", this);
	if (kernel != NULL) {
		clReleaseKernel(kernel);
	}
	parent = NULL;
}

nsresult dpoCKernel::InitKernel(cl_command_queue aCmdQueue, cl_kernel aKernel, cl_mem aFailureMem)
{
	cl_int err_code;

	kernel = aKernel;
	err_code = clRetainCommandQueue( aCmdQueue);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("initCData", err_code);
		return NS_ERROR_NOT_AVAILABLE;
	}
	cmdQueue = aCmdQueue;

	failureMem = aFailureMem;

	err_code = clSetKernelArg(kernel, 0, sizeof(cl_mem), &failureMem);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("initCData", err_code);
		return NS_ERROR_NOT_AVAILABLE;
	}

	return NS_OK;
}

/* readonly attribute uint32_t numberOfArgs; */
NS_IMETHODIMP dpoCKernel::GetNumberOfArgs(uint32_t *aNumberOfArgs)
{
	cl_uint result;
	cl_int err_code;

	err_code = clGetKernelInfo(kernel, CL_KERNEL_NUM_ARGS, sizeof(cl_uint), &result, NULL);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("GetNumberOfArgs", err_code);
		return NS_ERROR_NOT_AVAILABLE;
	}

	/* skip internal arguments when counting */
	*aNumberOfArgs = result - DPO_NUMBER_OF_ARTIFICIAL_ARGS;

    return NS_OK;
}

/* void setArgument (in uint32_t number, in dpoIData argument); */
NS_IMETHODIMP dpoCKernel::SetArgument(uint32_t number, dpoIData *argument)
{
	cl_int err_code;
	cl_mem buffer;

	/* skip internal arguments */
	number = number + DPO_NUMBER_OF_ARTIFICIAL_ARGS;

	buffer = ((dpoCData *) argument)->GetContainedBuffer();
	DEBUG_LOG_STATUS("SetArgument", "buffer is " << buffer);

	err_code = clSetKernelArg(kernel, number, sizeof(cl_mem), &buffer);

	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("SetArgument", err_code);
		return NS_ERROR_INVALID_ARG;
	}

    return NS_OK;
}

// High precision is true when arguments are passed as doubles and false when passed as floats.
/* void setScalarArgument (in uint32_t number, in jsval argument); */
NS_IMETHODIMP dpoCKernel::SetScalarArgument(uint32_t number, const jsval & argument,
	const jsval & isInteger, const jsval & highPrecision)
{
	cl_int err_code;
	bool isIntegerB;
	bool isHighPrecisionB;

	/* skip internal arguments */
	number = number + DPO_NUMBER_OF_ARTIFICIAL_ARGS;

	if (!JSVAL_IS_BOOLEAN(isInteger)) {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal isInteger argument.");

		return NS_ERROR_INVALID_ARG;
	}
	isIntegerB = JSVAL_TO_BOOLEAN(isInteger);

	if (!JSVAL_IS_BOOLEAN(highPrecision)) {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal highPrecision argument.");

		return NS_ERROR_INVALID_ARG;
	}
	isHighPrecisionB = JSVAL_TO_BOOLEAN(highPrecision);

	if (!JSVAL_IS_NUMBER(argument)) {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal number argument.");

		return NS_ERROR_INVALID_ARG;
	}

	if (JSVAL_IS_INT(argument)) {
		int value = JSVAL_TO_INT(argument);
		DEBUG_LOG_STATUS("SetScalarArgument", "(JSVAL_IS_INT(argument)) isIntegerB: " << isIntegerB  << " isHighPrecisionB " << isHighPrecisionB);

		if (isIntegerB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "(JSVAL_IS_INT(argument)) setting integer argument " << number << " to integer value " << value);
			cl_int intVal = (cl_int) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_int), &intVal);
		} else if (isHighPrecisionB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting double argument " << number << " to integer value " << value);
			cl_double doubleVal = (cl_double) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_double), &doubleVal);
		} else {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting float argument " << number << " to integer value " << value);
			cl_float floatVal = (cl_float) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_float), &floatVal);
		}

		if (err_code != CL_SUCCESS) {
			DEBUG_LOG_ERROR("SetScalarArgument", err_code);
			return NS_ERROR_NOT_AVAILABLE;
		}
	} else if (JSVAL_IS_DOUBLE(argument)) {
		double value = JSVAL_TO_DOUBLE(argument);
		DEBUG_LOG_STATUS("SetScalarArgument", "(JSVAL_IS_DOUBLE(argument)) isIntegerB: " << isIntegerB  << " isHighPrecisionB " << isHighPrecisionB);

		if (isIntegerB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting int formal argument " << number << " using double value " << value);
			cl_int intVal = (cl_int) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_int), &intVal);
		} else if (isHighPrecisionB) {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting double formal argument " << number << " using double value " << value);
			cl_double doubleVal = (cl_double) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_double), &doubleVal);
		} else {
			DEBUG_LOG_STATUS("SetScalarArgument", "setting float formal argument " << number << " using double value " << value);
			cl_float floatVal = (cl_float) value;
			err_code = clSetKernelArg(kernel, number, sizeof(cl_float), &floatVal);
		}

		if (err_code != CL_SUCCESS) {
			DEBUG_LOG_ERROR("SetScalarArgument", err_code);
			return NS_ERROR_NOT_AVAILABLE;
		}
	} else {
		DEBUG_LOG_STATUS("SetScalarArgument", "illegal number argument.");

		return NS_ERROR_INVALID_ARG;
	}

	return NS_OK;
}

/* uint32_t run (in uint32_t rank, [array, size_is (rank)] in uint32_t shape, [array, size_is (rank), optional] in uint32_t tile); */
NS_IMETHODIMP dpoCKernel::Run(uint32_t rank, uint32_t *shape, uint32_t *tile, uint32_t *_retval)
{
	cl_int err_code;
	cl_event runEvent, readEvent, writeEvent;
	size_t *global_work_size;
	size_t *local_work_size;
	const int zero = 0;

	DEBUG_LOG_STATUS("Run", "preparing execution of kernel");

    if (sizeof(size_t) == sizeof(uint32_t)) {
		global_work_size = (size_t *) shape;
	} else {
		global_work_size = (size_t *) nsMemory::Alloc(rank * sizeof(size_t));
		if (global_work_size == NULL) {
			DEBUG_LOG_STATUS("Run", "allocation of global_work_size failed");
			return NS_ERROR_OUT_OF_MEMORY;
		}
		for (int cnt = 0; cnt < rank; cnt++) {
			global_work_size[cnt] = shape[cnt];
		}
	}

#ifdef USE_LOCAL_WORKSIZE
	if (tile == NULL) {
		local_work_size = NULL;
	} else {
		if ((sizeof(size_t) == sizeof(uint32_t))) {
			local_work_size = (size_t *) tile;
		} else {
			local_work_size = (size_t *) nsMemory::Alloc(rank * sizeof(size_t));
			if (local_work_size == NULL) {
				DEBUG_LOG_STATUS("Run", "allocation of local_work_size failed");
				return NS_ERROR_OUT_OF_MEMORY;
			}
			for (int cnt = 0; cnt < rank; cnt++) {
				local_work_size[cnt] = (size_t) tile[cnt];
			}
		}
	}
#else /* USE_LOCAL_WORKSIZE */
	local_work_size = NULL;
#endif /* USE_LOCAL_WORKSIZE */

	DEBUG_LOG_STATUS("Run", "setting failure code to 0");

	err_code = clEnqueueWriteBuffer(cmdQueue, failureMem, CL_FALSE, 0, sizeof(int), &zero, 0, NULL, &writeEvent);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "enqueing execution of kernel");

#ifdef WINDOWS_ROUNDTRIP
	dpoCContext::RecordBeginOfRoundTrip(parent);
#endif /* WINDOWS_ROUNDTRIP */

	err_code = clEnqueueNDRangeKernel(cmdQueue, kernel, rank, NULL, global_work_size, NULL, 1, &writeEvent, &runEvent);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "reading failure code");

	err_code = clEnqueueReadBuffer(cmdQueue, failureMem, CL_FALSE, 0, sizeof(int), _retval, 1, &runEvent, &readEvent);
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "waiting for execution to finish");

	// For now we always wait for the run to complete.
	// In the long run, we may want to interleave this with JS execution and only sync on result read.
	err_code = clWaitForEvents( 1, &readEvent);

	DEBUG_LOG_STATUS("Run", "first event fired");

	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}
#ifdef WINDOWS_ROUNDTRIP
	dpoCContext::RecordEndOfRoundTrip(parent);
#endif /* WINDOWS_ROUNDTRIP */

#ifdef CLPROFILE
#ifdef CLPROFILE_ASYNC
	err_code = clSetEventCallback( readEvent, CL_COMPLETE, &dpoCContext::CollectTimings, parent);

	DEBUG_LOG_STATUS("Run", "second event fired");
	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}
#else /* CLPROFILE_ASYNC */
	dpoCContext::CollectTimings(runEvent,CL_COMPLETE,parent);
#endif /* CLPROFILE_ASYNC */
#endif /* CLPROFILE */

	DEBUG_LOG_STATUS("Run", "execution completed successfully, start cleanup");

	if (global_work_size != (size_t *) shape) {
		nsMemory::Free(global_work_size);
	}
#ifdef USE_LOCAL_WORKSIZE
	if (local_work_size != (size_t *) tile) {
		nsMemory::Free(local_work_size);
	}
#endif /* USE_LOCAL_WORKSIZE */

	err_code = clReleaseEvent(readEvent);
	err_code = clReleaseEvent(runEvent);
	err_code = clReleaseEvent(writeEvent);

	if (err_code != CL_SUCCESS) {
		DEBUG_LOG_ERROR("Run", err_code);
		return NS_ERROR_ABORT;
	}

	DEBUG_LOG_STATUS("Run", "cleanup complete");

    return NS_OK;
}
<|endoftext|>


<commit_before>/*
 *            kPPP: A front end for pppd for the KDE project
 *
 * $Id$
 *
 * Copyright (C) 1997 Bernd Johannes Wuebben
 *                    wuebben@math.cornell.edu
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/types.h>

#include "modem.h"
#include "pppdata.h"
#include "miniterm.h"

#define T_WIDTH 550
#define T_HEIGHT 400

#ifdef NO_USLEEP
extern int usleep( long usec );
#endif

extern PPPData gpppdata;

MiniTerm::MiniTerm(QWidget *parent=0, const char *name=0)
  : QDialog(parent, name,TRUE, WStyle_Customize|WStyle_NormalBorder)
{

  col = line = col_start = line_start = 0;
  modemfd = -1;

  setCaption(i18n("Kppp Mini-Terminal"));

  m_file = new QPopupMenu;
  m_file->insertItem( i18n("&Quit"),this, SLOT(cancelbutton()) );
  m_edit = new QPopupMenu;
  m_options = new QPopupMenu;
  m_options->insertItem(i18n("&Reset Modem"),this,SLOT(resetModem()));
  m_help = new QPopupMenu;
  m_help->insertItem( i18n("&Help"),this, SLOT(help()) );

  menubar = new KMenuBar( this );
  menubar->insertItem( i18n("&File"), m_file );
  menubar->insertItem( i18n("&Modem"), m_options );
  menubar->insertItem( i18n("&Help"), m_help);

  statusbar = new QLabel(this);
  statusbar->setFrameStyle(QFrame::Panel | QFrame::Sunken);

  statusbar2 = new QLabel(this);
  statusbar2->setFrameStyle(QFrame::Panel | QFrame::Sunken);

  terminal = new MyTerm(this,"term");
  connect(terminal,SIGNAL(got_a_line()),this,SLOT(process_line()));

  setupToolbar();

  statusbar->setGeometry(0, T_HEIGHT - 20, T_WIDTH - 70, 20);
  statusbar2->setGeometry(T_WIDTH - 70, T_HEIGHT - 20, 70, 20);

  menubar->setGeometry(0,0,T_WIDTH,30);

  terminal->setGeometry(0, menubar->height() + toolbar->height() ,
   T_WIDTH,  T_HEIGHT - menubar->height() - toolbar->height() - statusbar->height());

  readtimer = new QTimer(this);
  connect(readtimer,SIGNAL(timeout()),this,SLOT(readtty()));

  inittimer = new QTimer(this);
  connect(inittimer,SIGNAL(timeout()),this,SLOT(init()));
  inittimer->start(500);

}

void MiniTerm::setupToolbar(){

  toolbar = new KToolBar( this );

  KIconLoader *loader = kapp->getIconLoader();

  QPixmap pixmap;

  pixmap = loader->loadIcon("exit.xpm");
  toolbar->insertButton(pixmap, 0,
		      SIGNAL(clicked()), this,
		      SLOT(cancelbutton()), TRUE, i18n("Quit MiniTerm"));

  pixmap = loader->loadIcon("back.xpm");
  toolbar->insertButton(pixmap, 0,
		      SIGNAL(clicked()), this,
		      SLOT(resetModem()), TRUE, i18n("Reset Modem"));

  pixmap = loader->loadIcon("help.xpm");
  toolbar->insertButton(pixmap, 0,
		      SIGNAL(clicked()), this,
		      SLOT(help()), TRUE, i18n("Help"));

  toolbar->setBarPos( KToolBar::Top );

}

void MiniTerm::process_line(){

  QString newline;
  newline = terminal->textLine(line);
  newline = newline.remove(0,col_start);
  newline = newline.stripWhiteSpace();
  writeline(newline.data());

}

void MiniTerm::resizeEvent(QResizeEvent*){

  menubar->setGeometry(0,0,width(),30);

  toolbar->setGeometry(0,menubar->height(),width(),toolbar->height());

  terminal->setGeometry(0, menubar->height() + toolbar->height() ,
   width(),  height() - menubar->height() - toolbar->height() - statusbar->height());

  statusbar->setGeometry(0, height() - 20, width() - 70, 20);
  statusbar2->setGeometry(width() - 70, height() - 20, 70, 20);

}

void MiniTerm::init() {

  inittimer->stop();
  statusbar->setText(i18n("Initializing Modem"));
  kapp->processEvents();

  int lock = lockdevice();
  if (lock == 1){

    statusbar->setText(i18n("Sorry, modem device is locked."));
    return;
  }
  if (lock == -1){

    statusbar->setText(i18n("Sorry, can't create modem lock file."));
    return;
  }

  if(opentty()){

    if(modemfd >= 0) {
      writeline(gpppdata.modemHangupStr());
      usleep(100000);  // wait 0.1 secs
      hangup();
      writeline(gpppdata.modemInitStr());
      usleep(100000);
    }

    statusbar->setText(i18n("Modem Ready"));
    terminal->setFocus();

    kapp->processEvents();
    kapp->processEvents();
    readtimer->start(1);
  }
  else {// commmented out since this will now be set by the opentty() better.
        // statusbar->setText("Can't open modem device");
    unlockdevice();
  }
}

void MiniTerm::readtty() {

  char c;

  if(read(modemfd, &c, 1) == 1) {
    c = ((int)c & 0x7F);
    // printf("read:%x %c\n",c,c);

    // TODO sort this shit out

    if(((int)c != 13)&& ((int)c != 10)&&((int)c != 8))
      terminal->insertChar( c );

    if((int)c == 8)
      terminal->backspace();
    if((int)c == 127)
      terminal->backspace();

    if((int)c == 10)
      terminal->mynewline();

    if((int)c == 13)
      terminal->myreturn();
  }

}

void MiniTerm::cancelbutton() {

  readtimer->stop();
  statusbar->setText(i18n("Hanging up ..."));
  kapp->processEvents();
  kapp->flushX();

  if(modemfd >= 0) {
    writeline(gpppdata.modemHangupStr());
    usleep(100000); // 0.1 sec
    hangup();
  }

  closetty();
  unlockdevice();

  reject();
}

void MiniTerm::resetModem(){

  statusbar->setText(i18n("Resetting Modem"));
  terminal->newLine();
  kapp->processEvents();
  kapp->flushX();

  if(modemfd >= 0) {
    writeline(gpppdata.modemHangupStr());
    usleep(100000); // 0.1 sec
    hangup();
  }
  statusbar->setText(i18n("Modem Ready"));
}

bool MiniTerm::closetty(){

  if(modemfd > 0)

    /* discard data not read or transmitted */
    tcflush(modemfd, TCIOFLUSH);

    if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){
      statusbar->setText(i18n("Can't restore tty settings: tcsetattr()\n"));
    }

    ::close(modemfd);
    modemfd = -1;
  return TRUE;
}

bool MiniTerm::opentty() {

 memset(&initial_tty,'\0',sizeof(initial_tty));

 if((modemfd = open(gpppdata.modemDevice(), O_RDWR|O_NDELAY)) < 0){

    statusbar->setText(i18n("Can't open Modem"));
    return FALSE;
  }

  if(tcgetattr(modemfd, &tty) < 0){

    statusbar->setText(i18n("tcgetattr() failed\n"));
    return FALSE;
  }

  initial_tty = tty; // save a copy

  tty.c_cc[VMIN] = 0; // nonblocking
  tty.c_cc[VTIME] = 0;
  tty.c_oflag = 0;
  tty.c_lflag = 0;

  // clearing CLOCAL as below ensures we observe the modem status lines
  //  tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);

  tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
  tty.c_cflag |= CLOCAL ; //ignore modem satus lines
  tty.c_oflag &= ~OPOST; //no outline processing -- transparent output

  tty.c_cflag |= CS8 | CREAD;
  tty.c_iflag = IGNBRK | IGNPAR | ISTRIP;       // added ISTRIP
  tty.c_lflag &= ~ICANON;  			// non-canonical mode
  tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE);

  if(strcmp(gpppdata.flowcontrol(), "None") != 0) {
    if(strcmp(gpppdata.flowcontrol(), "CRTSCTS") == 0) {
      tty.c_cflag |= CRTSCTS;
      tty.c_iflag &= ~(IXON | IXOFF);
    }
    else {
      tty.c_cflag &= ~CRTSCTS;
      tty.c_iflag |= IXON | IXOFF;
      tty.c_cc[VSTOP]  = 0x13; // DC3 = XOFF = ^S
      tty.c_cc[VSTART] = 0x11; // DC1 = XON  = ^Q
    }
  }
  else {
    tty.c_cflag &= ~CRTSCTS;
    tty.c_iflag &= ~(IXON | IXOFF);
  }

  cfsetospeed(&tty, modemspeed());
  cfsetispeed(&tty, modemspeed());

  if(tcsetattr(modemfd, TCSANOW, &tty) < 0){

    statusbar->setText(i18n("tcsetattr() failed\n"));
    return FALSE;
  }

  return TRUE;
}

void MiniTerm::hangup() {

  struct termios temptty;

  if(modemfd >= 0) {

    // Properly bracketed escape code
    tcflush(modemfd,TCOFLUSH);
    // +3 because quiet time must be greater than guard time.
    usleep((gpppdata.modemEscapeGuardTime()+3)*20000);

    write(modemfd, gpppdata.modemEscapeStr(), strlen(gpppdata.modemEscapeStr()) );

    tcflush(modemfd,TCOFLUSH);
    usleep((gpppdata.modemEscapeGuardTime()+3)*20000);

    // Then hangup command
    writeline(gpppdata.modemHangupStr());

    usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec

    tcsendbreak(modemfd, 0);

    tcgetattr(modemfd, &temptty);
    cfsetospeed(&temptty, B0);
    cfsetispeed(&temptty, B0);
    tcsetattr(modemfd, TCSAFLUSH, &temptty);

    usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 secs

    cfsetospeed(&temptty, modemspeed());
    cfsetispeed(&temptty, modemspeed());
    tcsetattr(modemfd, TCSAFLUSH, &temptty);

  }

}

bool MiniTerm::writeChar(char c){

  write(modemfd,&c,1);
  return true;

}

bool MiniTerm::writeline(const char *buf) {

  write(modemfd, buf, strlen(buf));

  if(strcmp(gpppdata.enter(), "CR/LF") == 0)
    write(modemfd, "\r\n", 2);

  if(strcmp(gpppdata.enter(), "LF") == 0)
    write(modemfd, "\n", 1);

  if(strcmp(gpppdata.enter(), "CR") == 0)
    write(modemfd, "\r", 1);

  return true;
}

void MiniTerm::closeEvent( QCloseEvent *e ){

  e->ignore();     // don't let the user close the window

}

void MiniTerm::help(){

  kapp->invokeHTMLHelp("kppp/kppp.html","");

}

MyTerm::MyTerm(QWidget *parent=0 ,const char* name=0)
  : QMultiLineEdit(parent, name)
{
   p_parent =   (MiniTerm*)  parent;
   this->setFont(QFont("courier",12,QFont::Normal));

}

void MyTerm::keyPressEvent(QKeyEvent *k) {

  if(k->ascii() == 13){
    myreturn();
    p_parent->writeChar((char) k->ascii());
    return;
  }

  p_parent->writeChar((char) k->ascii());

}

void MyTerm::insertChar(char c) {

  QMultiLineEdit::insertChar(c);

}

void MyTerm::newLine() {

  QMultiLineEdit::newLine();

}

void MyTerm::del() {

  QMultiLineEdit::del();

}

void MyTerm::backspace() {

  //  QMultiLineEdit::cursorLeft();
  QMultiLineEdit::backspace();

}

void MyTerm::myreturn() {

    int column;
    int line;

    getCursorPosition(&line,&column);
    for (int i = 0; i < column;i++)
      QMultiLineEdit::cursorLeft();

}

void MyTerm::mynewline() {

    QMultiLineEdit::end(FALSE);
    QMultiLineEdit::newLine();

}

#include "miniterm.moc"
<commit_msg>And another thing:   Assigning defaults in the implementation is frowned on.  For instance<commit_after>/*
 *            kPPP: A front end for pppd for the KDE project
 *
 * $Id$
 *
 * Copyright (C) 1997 Bernd Johannes Wuebben
 *                    wuebben@math.cornell.edu
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/types.h>

#include "modem.h"
#include "pppdata.h"
#include "miniterm.h"

#define T_WIDTH 550
#define T_HEIGHT 400

#ifdef NO_USLEEP
extern int usleep( long usec );
#endif

extern PPPData gpppdata;

MiniTerm::MiniTerm(QWidget *parent, const char *name)
  : QDialog(parent, name,TRUE, WStyle_Customize|WStyle_NormalBorder)
{

  col = line = col_start = line_start = 0;
  modemfd = -1;

  setCaption(i18n("Kppp Mini-Terminal"));

  m_file = new QPopupMenu;
  m_file->insertItem( i18n("&Quit"),this, SLOT(cancelbutton()) );
  m_edit = new QPopupMenu;
  m_options = new QPopupMenu;
  m_options->insertItem(i18n("&Reset Modem"),this,SLOT(resetModem()));
  m_help = new QPopupMenu;
  m_help->insertItem( i18n("&Help"),this, SLOT(help()) );

  menubar = new KMenuBar( this );
  menubar->insertItem( i18n("&File"), m_file );
  menubar->insertItem( i18n("&Modem"), m_options );
  menubar->insertItem( i18n("&Help"), m_help);

  statusbar = new QLabel(this);
  statusbar->setFrameStyle(QFrame::Panel | QFrame::Sunken);

  statusbar2 = new QLabel(this);
  statusbar2->setFrameStyle(QFrame::Panel | QFrame::Sunken);

  terminal = new MyTerm(this,"term");
  connect(terminal,SIGNAL(got_a_line()),this,SLOT(process_line()));

  setupToolbar();

  statusbar->setGeometry(0, T_HEIGHT - 20, T_WIDTH - 70, 20);
  statusbar2->setGeometry(T_WIDTH - 70, T_HEIGHT - 20, 70, 20);

  menubar->setGeometry(0,0,T_WIDTH,30);

  terminal->setGeometry(0, menubar->height() + toolbar->height() ,
   T_WIDTH,  T_HEIGHT - menubar->height() - toolbar->height() - statusbar->height());

  readtimer = new QTimer(this);
  connect(readtimer,SIGNAL(timeout()),this,SLOT(readtty()));

  inittimer = new QTimer(this);
  connect(inittimer,SIGNAL(timeout()),this,SLOT(init()));
  inittimer->start(500);

}

void MiniTerm::setupToolbar(){

  toolbar = new KToolBar( this );

  KIconLoader *loader = kapp->getIconLoader();

  QPixmap pixmap;

  pixmap = loader->loadIcon("exit.xpm");
  toolbar->insertButton(pixmap, 0,
		      SIGNAL(clicked()), this,
		      SLOT(cancelbutton()), TRUE, i18n("Quit MiniTerm"));

  pixmap = loader->loadIcon("back.xpm");
  toolbar->insertButton(pixmap, 0,
		      SIGNAL(clicked()), this,
		      SLOT(resetModem()), TRUE, i18n("Reset Modem"));

  pixmap = loader->loadIcon("help.xpm");
  toolbar->insertButton(pixmap, 0,
		      SIGNAL(clicked()), this,
		      SLOT(help()), TRUE, i18n("Help"));

  toolbar->setBarPos( KToolBar::Top );

}

void MiniTerm::process_line(){

  QString newline;
  newline = terminal->textLine(line);
  newline = newline.remove(0,col_start);
  newline = newline.stripWhiteSpace();
  writeline(newline.data());

}

void MiniTerm::resizeEvent(QResizeEvent*){

  menubar->setGeometry(0,0,width(),30);

  toolbar->setGeometry(0,menubar->height(),width(),toolbar->height());

  terminal->setGeometry(0, menubar->height() + toolbar->height() ,
   width(),  height() - menubar->height() - toolbar->height() - statusbar->height());

  statusbar->setGeometry(0, height() - 20, width() - 70, 20);
  statusbar2->setGeometry(width() - 70, height() - 20, 70, 20);

}

void MiniTerm::init() {

  inittimer->stop();
  statusbar->setText(i18n("Initializing Modem"));
  kapp->processEvents();

  int lock = lockdevice();
  if (lock == 1){

    statusbar->setText(i18n("Sorry, modem device is locked."));
    return;
  }
  if (lock == -1){

    statusbar->setText(i18n("Sorry, can't create modem lock file."));
    return;
  }

  if(opentty()){

    if(modemfd >= 0) {
      writeline(gpppdata.modemHangupStr());
      usleep(100000);  // wait 0.1 secs
      hangup();
      writeline(gpppdata.modemInitStr());
      usleep(100000);
    }

    statusbar->setText(i18n("Modem Ready"));
    terminal->setFocus();

    kapp->processEvents();
    kapp->processEvents();
    readtimer->start(1);
  }
  else {// commmented out since this will now be set by the opentty() better.
        // statusbar->setText("Can't open modem device");
    unlockdevice();
  }
}

void MiniTerm::readtty() {

  char c;

  if(read(modemfd, &c, 1) == 1) {
    c = ((int)c & 0x7F);
    // printf("read:%x %c\n",c,c);

    // TODO sort this shit out

    if(((int)c != 13)&& ((int)c != 10)&&((int)c != 8))
      terminal->insertChar( c );

    if((int)c == 8)
      terminal->backspace();
    if((int)c == 127)
      terminal->backspace();

    if((int)c == 10)
      terminal->mynewline();

    if((int)c == 13)
      terminal->myreturn();
  }

}

void MiniTerm::cancelbutton() {

  readtimer->stop();
  statusbar->setText(i18n("Hanging up ..."));
  kapp->processEvents();
  kapp->flushX();

  if(modemfd >= 0) {
    writeline(gpppdata.modemHangupStr());
    usleep(100000); // 0.1 sec
    hangup();
  }

  closetty();
  unlockdevice();

  reject();
}

void MiniTerm::resetModem(){

  statusbar->setText(i18n("Resetting Modem"));
  terminal->newLine();
  kapp->processEvents();
  kapp->flushX();

  if(modemfd >= 0) {
    writeline(gpppdata.modemHangupStr());
    usleep(100000); // 0.1 sec
    hangup();
  }
  statusbar->setText(i18n("Modem Ready"));
}

bool MiniTerm::closetty(){

  if(modemfd > 0)

    /* discard data not read or transmitted */
    tcflush(modemfd, TCIOFLUSH);

    if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){
      statusbar->setText(i18n("Can't restore tty settings: tcsetattr()\n"));
    }

    ::close(modemfd);
    modemfd = -1;
  return TRUE;
}

bool MiniTerm::opentty() {

 memset(&initial_tty,'\0',sizeof(initial_tty));

 if((modemfd = open(gpppdata.modemDevice(), O_RDWR|O_NDELAY)) < 0){

    statusbar->setText(i18n("Can't open Modem"));
    return FALSE;
  }

  if(tcgetattr(modemfd, &tty) < 0){

    statusbar->setText(i18n("tcgetattr() failed\n"));
    return FALSE;
  }

  initial_tty = tty; // save a copy

  tty.c_cc[VMIN] = 0; // nonblocking
  tty.c_cc[VTIME] = 0;
  tty.c_oflag = 0;
  tty.c_lflag = 0;

  // clearing CLOCAL as below ensures we observe the modem status lines
  //  tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);

  tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
  tty.c_cflag |= CLOCAL ; //ignore modem satus lines
  tty.c_oflag &= ~OPOST; //no outline processing -- transparent output

  tty.c_cflag |= CS8 | CREAD;
  tty.c_iflag = IGNBRK | IGNPAR | ISTRIP;       // added ISTRIP
  tty.c_lflag &= ~ICANON;  			// non-canonical mode
  tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE);

  if(strcmp(gpppdata.flowcontrol(), "None") != 0) {
    if(strcmp(gpppdata.flowcontrol(), "CRTSCTS") == 0) {
      tty.c_cflag |= CRTSCTS;
      tty.c_iflag &= ~(IXON | IXOFF);
    }
    else {
      tty.c_cflag &= ~CRTSCTS;
      tty.c_iflag |= IXON | IXOFF;
      tty.c_cc[VSTOP]  = 0x13; // DC3 = XOFF = ^S
      tty.c_cc[VSTART] = 0x11; // DC1 = XON  = ^Q
    }
  }
  else {
    tty.c_cflag &= ~CRTSCTS;
    tty.c_iflag &= ~(IXON | IXOFF);
  }

  cfsetospeed(&tty, modemspeed());
  cfsetispeed(&tty, modemspeed());

  if(tcsetattr(modemfd, TCSANOW, &tty) < 0){

    statusbar->setText(i18n("tcsetattr() failed\n"));
    return FALSE;
  }

  return TRUE;
}

void MiniTerm::hangup() {

  struct termios temptty;

  if(modemfd >= 0) {

    // Properly bracketed escape code
    tcflush(modemfd,TCOFLUSH);
    // +3 because quiet time must be greater than guard time.
    usleep((gpppdata.modemEscapeGuardTime()+3)*20000);

    write(modemfd, gpppdata.modemEscapeStr(), strlen(gpppdata.modemEscapeStr()) );

    tcflush(modemfd,TCOFLUSH);
    usleep((gpppdata.modemEscapeGuardTime()+3)*20000);

    // Then hangup command
    writeline(gpppdata.modemHangupStr());

    usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec

    tcsendbreak(modemfd, 0);

    tcgetattr(modemfd, &temptty);
    cfsetospeed(&temptty, B0);
    cfsetispeed(&temptty, B0);
    tcsetattr(modemfd, TCSAFLUSH, &temptty);

    usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 secs

    cfsetospeed(&temptty, modemspeed());
    cfsetispeed(&temptty, modemspeed());
    tcsetattr(modemfd, TCSAFLUSH, &temptty);

  }

}

bool MiniTerm::writeChar(char c){

  write(modemfd,&c,1);
  return true;

}

bool MiniTerm::writeline(const char *buf) {

  write(modemfd, buf, strlen(buf));

  if(strcmp(gpppdata.enter(), "CR/LF") == 0)
    write(modemfd, "\r\n", 2);

  if(strcmp(gpppdata.enter(), "LF") == 0)
    write(modemfd, "\n", 1);

  if(strcmp(gpppdata.enter(), "CR") == 0)
    write(modemfd, "\r", 1);

  return true;
}

void MiniTerm::closeEvent( QCloseEvent *e ){

  e->ignore();     // don't let the user close the window

}

void MiniTerm::help(){

  kapp->invokeHTMLHelp("kppp/kppp.html","");

}

MyTerm::MyTerm(QWidget *parent, const char* name)
  : QMultiLineEdit(parent, name)
{
   p_parent = (MiniTerm*)parent;
   this->setFont(QFont("courier",12,QFont::Normal));

}

void MyTerm::keyPressEvent(QKeyEvent *k) {

  if(k->ascii() == 13){
    myreturn();
    p_parent->writeChar((char) k->ascii());
    return;
  }

  p_parent->writeChar((char) k->ascii());

}

void MyTerm::insertChar(char c) {

  QMultiLineEdit::insertChar(c);

}

void MyTerm::newLine() {

  QMultiLineEdit::newLine();

}

void MyTerm::del() {

  QMultiLineEdit::del();

}

void MyTerm::backspace() {

  //  QMultiLineEdit::cursorLeft();
  QMultiLineEdit::backspace();

}

void MyTerm::myreturn() {

    int column;
    int line;

    getCursorPosition(&line,&column);
    for (int i = 0; i < column;i++)
      QMultiLineEdit::cursorLeft();

}

void MyTerm::mynewline() {

    QMultiLineEdit::end(FALSE);
    QMultiLineEdit::newLine();

}

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