<commit_before>/*************************************************************************
 *
 *  $RCSfile: rscdbl.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2005-01-03 17:24:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>

#ifndef _RSCDB_HXX
#include <rscdb.hxx>
#endif
#ifndef _RSCALL_H
#include <rscall.h>
#endif
#ifndef _RSCHASH_HXX
#include <rschash.hxx>
#endif
#ifndef _RSCTREE_HXX
#include <rsctree.hxx>
#endif
#ifndef _RSCTOP_HXX
#include <rsctop.hxx>
#endif
#ifndef _RSCLST_HXX
#include "rsclst.hxx"
#endif

/*************************************************************************
|*
|*    RscTypCont::FillNameIdList()
|*
|*    Beschreibung
|*    Ersterstellung    MM 07.05.91
|*    Letzte Aenderung  MM 30.05.91
|*
*************************************************************************/
REResourceList * InsertList( Atom nClassName, const RscId& rId,
                             REResourceList * pList ){
    REResourceList  *   pSubList;
    const char *                pStrClass;
    ByteString          aStrClass;

    pStrClass = pHS->getString( nClassName ).getStr();
    if( pStrClass )
        aStrClass = pStrClass;
    else
        aStrClass = ByteString::CreateFromInt32( (long)nClassName );

    pSubList = new REResourceList( pList, aStrClass, rId );

    pList->Insert( pSubList, 0xFFFFFFFF );
    return( pSubList );
}

void FillSubList( RSCINST & rInst, REResourceList * pList )
{
    sal_uInt32      nCount, i;
    SUBINFO_STRUCT  aInfo;
    REResourceList* pSubList;
    RSCINST         aTmpI;

    nCount = rInst.pClass->GetCount( rInst );
    for( i = 0; i < nCount; i++ ){
        aInfo = rInst.pClass->GetInfoEle( rInst, i );
        aTmpI = rInst.pClass->GetPosEle( rInst, i );
        pSubList = InsertList( aInfo.pClass->GetId(),
                               aInfo.aId, pList );
        FillSubList( aTmpI, pSubList );
    };
}

void FillListObj( ObjNode * pObjNode, RscTop * pRscTop,
                  REResourceList * pList, ULONG lFileKey )
{
    if( pObjNode ){
        if( pObjNode->GetFileKey() == lFileKey ){
            RSCINST         aTmpI;
            REResourceList* pSubList;

            FillListObj( (ObjNode*)pObjNode->Left(), pRscTop,
                         pList, lFileKey );

            pSubList = InsertList( pRscTop->GetId(),
                                   pObjNode->GetRscId(), pList );

            aTmpI.pClass = pRscTop;
            aTmpI.pData = pObjNode->GetRscObj();
            FillSubList( aTmpI, pSubList );

            FillListObj( (ObjNode*)pObjNode->Right(), pRscTop,
                         pList, lFileKey );
        }
    };
}

void FillList( RscTop * pRscTop, REResourceList * pList, ULONG lFileKey ){
    if( pRscTop ){
        FillList( (RscTop*)pRscTop->Left(), pList, lFileKey );

        FillListObj( pRscTop->GetObjNode(), pRscTop, pList, lFileKey );

        FillList( (RscTop*)pRscTop->Right(), pList, lFileKey );
    };
}

void RscTypCont::FillNameIdList( REResourceList * pList, ULONG lFileKey ){
    FillList( pRoot, pList, lFileKey );
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.18); FILE MERGED 2005/09/05 18:46:54 rt 1.2.18.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rscdbl.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 13:35:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <stdio.h>

#ifndef _RSCDB_HXX
#include <rscdb.hxx>
#endif
#ifndef _RSCALL_H
#include <rscall.h>
#endif
#ifndef _RSCHASH_HXX
#include <rschash.hxx>
#endif
#ifndef _RSCTREE_HXX
#include <rsctree.hxx>
#endif
#ifndef _RSCTOP_HXX
#include <rsctop.hxx>
#endif
#ifndef _RSCLST_HXX
#include "rsclst.hxx"
#endif

/*************************************************************************
|*
|*    RscTypCont::FillNameIdList()
|*
|*    Beschreibung
|*    Ersterstellung    MM 07.05.91
|*    Letzte Aenderung  MM 30.05.91
|*
*************************************************************************/
REResourceList * InsertList( Atom nClassName, const RscId& rId,
                             REResourceList * pList ){
    REResourceList  *   pSubList;
    const char *                pStrClass;
    ByteString          aStrClass;

    pStrClass = pHS->getString( nClassName ).getStr();
    if( pStrClass )
        aStrClass = pStrClass;
    else
        aStrClass = ByteString::CreateFromInt32( (long)nClassName );

    pSubList = new REResourceList( pList, aStrClass, rId );

    pList->Insert( pSubList, 0xFFFFFFFF );
    return( pSubList );
}

void FillSubList( RSCINST & rInst, REResourceList * pList )
{
    sal_uInt32      nCount, i;
    SUBINFO_STRUCT  aInfo;
    REResourceList* pSubList;
    RSCINST         aTmpI;

    nCount = rInst.pClass->GetCount( rInst );
    for( i = 0; i < nCount; i++ ){
        aInfo = rInst.pClass->GetInfoEle( rInst, i );
        aTmpI = rInst.pClass->GetPosEle( rInst, i );
        pSubList = InsertList( aInfo.pClass->GetId(),
                               aInfo.aId, pList );
        FillSubList( aTmpI, pSubList );
    };
}

void FillListObj( ObjNode * pObjNode, RscTop * pRscTop,
                  REResourceList * pList, ULONG lFileKey )
{
    if( pObjNode ){
        if( pObjNode->GetFileKey() == lFileKey ){
            RSCINST         aTmpI;
            REResourceList* pSubList;

            FillListObj( (ObjNode*)pObjNode->Left(), pRscTop,
                         pList, lFileKey );

            pSubList = InsertList( pRscTop->GetId(),
                                   pObjNode->GetRscId(), pList );

            aTmpI.pClass = pRscTop;
            aTmpI.pData = pObjNode->GetRscObj();
            FillSubList( aTmpI, pSubList );

            FillListObj( (ObjNode*)pObjNode->Right(), pRscTop,
                         pList, lFileKey );
        }
    };
}

void FillList( RscTop * pRscTop, REResourceList * pList, ULONG lFileKey ){
    if( pRscTop ){
        FillList( (RscTop*)pRscTop->Left(), pList, lFileKey );

        FillListObj( pRscTop->GetObjNode(), pRscTop, pList, lFileKey );

        FillList( (RscTop*)pRscTop->Right(), pList, lFileKey );
    };
}

void RscTypCont::FillNameIdList( REResourceList * pList, ULONG lFileKey ){
    FillList( pRoot, pList, lFileKey );
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Tobias Gödderz
////////////////////////////////////////////////////////////////////////////////

#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>

#include "Replication2/ReplicatedLog/ILogParticipant.h"
#include "Replication2/ReplicatedLog/types.h"
#include "TestHelper.h"

#include <Basics/ScopeGuard.h>
#include <Basics/application-exit.h>

#include <functional>

using namespace arangodb;
using namespace arangodb::replication2;
using namespace arangodb::replication2::replicated_log;

struct ReplicatedLogConcurrentTest : ReplicatedLogTest {
  using ThreadIdx = uint16_t;
  using IterIdx = uint32_t;
  constexpr static auto maxIter = std::numeric_limits<IterIdx>::max();

  struct alignas(128) ThreadCoordinationData {
    // the testee
    std::shared_ptr<ILogParticipant> log;

    // only when set to true, all client threads start
    std::atomic<bool> go = false;
    // when set to true, client threads will stop after the current iteration,
    // whatever that means for them.
    std::atomic<bool> stopClientThreads = false;
    // when set to true, the replication thread stops. should be done only
    // after all client threads stopped to avoid them hanging while waiting on
    // replication.
    std::atomic<bool> stopReplicationThreads = false;
    // every thread increases this by one when it's ready to start
    std::atomic<std::size_t> threadsReady = 0;
    // every thread increases this by one when it's done a certain minimal
    // amount of work. This is to guarantee that all threads are running long
    // enough side by side.
    std::atomic<std::size_t> threadsSatisfied = 0;
  };

  // Used to generate payloads that are unique across threads.
  constexpr static auto genPayload = [](ThreadIdx thread, IterIdx i) {
    // This should fit into short string optimization
    auto str = std::string(16, ' ');

    auto p = str.begin() + 5;
    // up to 5 digits for thread
    static_assert(std::numeric_limits<ThreadIdx>::max() <= 99'999);
    // 1 digit for ':'
    *p = ':';
    // up to 10 digits for i
    static_assert(std::numeric_limits<IterIdx>::max() <= 99'999'999'999);

    do {
      --p;
      *p = static_cast<char>('0' + (thread % 10));
      thread /= 10;
    } while (thread > 0);
    p = str.end();
    do {
      --p;
      *p = static_cast<char>('0' + (i % 10));
      i /= 10;
    } while (i > 0);

    return str;
  };

  constexpr static auto alternatinglyInsertAndRead = [](ThreadIdx const threadIdx,
                                                        ThreadCoordinationData& data) {
    using namespace std::chrono_literals;
    auto log = std::dynamic_pointer_cast<LogLeader>(data.log);
    ASSERT_NE(log, nullptr);
    data.threadsReady.fetch_add(1);
    while (!data.go.load()) {
    }

    for (auto i = std::uint32_t{0}; i < maxIter && !data.stopClientThreads.load(); ++i) {
      auto const payload = LogPayload::createFromString(genPayload(threadIdx, i));
      auto const idx = log->insert(payload, false, LogLeader::doNotTriggerAsyncReplication);
      std::this_thread::sleep_for(1ns);
      auto fut = log->waitFor(idx);
      fut.get();
      auto snapshot = log->getReplicatedLogSnapshot();
      ASSERT_LT(0, idx.value);
      ASSERT_LE(idx.value, snapshot.size());
      auto const& entry = snapshot[idx.value - 1];
      EXPECT_EQ(idx, entry.entry().logIndex());
      EXPECT_EQ(payload, entry.entry().logPayload());
      if (i == 1000) {
        // we should have done at least a few iterations before finishing
        data.threadsSatisfied.fetch_add(1, std::memory_order_relaxed);
      }
    }
  };

  constexpr static auto insertManyThenRead = [](ThreadIdx const threadIdx,
                                                ThreadCoordinationData& data) {
    using namespace std::chrono_literals;
    auto log = std::dynamic_pointer_cast<LogLeader>(data.log);
    ASSERT_NE(log, nullptr);
    data.threadsReady.fetch_add(1);
    while (!data.go.load()) {
    }

    constexpr auto batch = 100;
    auto idxs = std::vector<LogIndex>{};
    idxs.resize(batch);

    for (auto i = std::uint32_t{0};
         i < maxIter && !data.stopClientThreads.load(); i += batch) {
      for (auto k = 0; k < batch && i + k < maxIter; ++k) {
        auto const payload = LogPayload::createFromString(genPayload(threadIdx, i + k));
        idxs[k] = log->insert(payload, false, LogLeader::doNotTriggerAsyncReplication);
      }
      std::this_thread::sleep_for(1ns);
      auto fut = log->waitFor(idxs.back());
      fut.get();
      auto snapshot = log->getReplicatedLogSnapshot();
      for (auto k = 0; k < batch && i + k < maxIter; ++k) {
        using namespace std::string_literals;
        auto const payload = std::optional(LogPayload::createFromString(genPayload(threadIdx, i + k)));
        auto const idx = idxs[k];
        ASSERT_LT(0, idx.value);
        ASSERT_LE(idx.value, snapshot.size());
        auto const& entry = snapshot[idx.value - 1];
        EXPECT_EQ(idx, entry.entry().logIndex());
        EXPECT_EQ(payload, entry.entry().logPayload())
            << VPackSlice(payload->dummy.data()).toJson() << " "
            << (entry.entry().logPayload()
                    ? VPackSlice(entry.entry().logPayload()->dummy.data()).toJson()
                    : "std::nullopt"s);
      }
      if (i == 10 * batch) {
        // we should have done at least a few iterations before finishing
        data.threadsSatisfied.fetch_add(1, std::memory_order_relaxed);
      }
    }
  };

  constexpr static auto runReplicationWithIntermittentPauses =
      [](ThreadCoordinationData& data) {
        using namespace std::chrono_literals;
        auto log = std::dynamic_pointer_cast<LogLeader>(data.log);
        ASSERT_NE(log, nullptr);
        for (auto i = 0;; ++i) {
          log->triggerAsyncReplication();
          if (i % 16) {
            std::this_thread::sleep_for(100ns);
            if (data.stopReplicationThreads.load()) {
              return;
            }
          }
        }
      };

  constexpr static auto runFollowerReplicationWithIntermittentPauses =
      // NOLINTNEXTLINE(performance-unnecessary-value-param)
      [](std::vector<DelayedFollowerLog*> followers, ThreadCoordinationData& data) {
        using namespace std::chrono_literals;
        for (auto i = 0;;) {
          for (auto* follower : followers) {
            follower->runAsyncAppendEntries();
            if (i % 17) {
              std::this_thread::sleep_for(100ns);
              if (data.stopReplicationThreads.load()) {
                return;
              }
            }
            ++i;
          }
        }
      };
};

TEST_F(ReplicatedLogConcurrentTest, genPayloadTest) {
  EXPECT_EQ("    0:         0", genPayload(0, 0));
  EXPECT_EQ("   11:        42", genPayload(11, 42));
  EXPECT_EQ("65535:4294967295", genPayload(65535, 4294967295));
}

TEST_F(ReplicatedLogConcurrentTest, lonelyLeader) {
  using namespace std::chrono_literals;

  auto replicatedLog = makeReplicatedLogWithAsyncMockLog(LogId{1});
  // TODO this test hangs because there is not local follower currently
  auto leaderLog = replicatedLog->becomeLeader("leader", LogTerm{1}, {}, 1);

  auto data = ThreadCoordinationData{leaderLog};

  // start replication
  auto replicationThread =
      std::thread{runReplicationWithIntermittentPauses, std::ref(data)};

  std::vector<std::thread> clientThreads;
  auto threadCounter = uint16_t{0};
  clientThreads.emplace_back(alternatinglyInsertAndRead, threadCounter++, std::ref(data));
  clientThreads.emplace_back(insertManyThenRead, threadCounter++, std::ref(data));

  ASSERT_EQ(clientThreads.size(), threadCounter);
  while (data.threadsReady.load() < clientThreads.size()) {
  }
  data.go.store(true);
  while (data.threadsSatisfied.load() < clientThreads.size()) {
    std::this_thread::sleep_for(100us);
  }
  data.stopClientThreads.store(true);

  for (auto& thread : clientThreads) {
    thread.join();
  }

  // stop replication only after all client threads joined, so we don't block
  // them in some intermediate state
  data.stopReplicationThreads.store(true);
  replicationThread.join();

  auto stats = std::get<LeaderStatus>(data.log->getStatus().getVariant()).local;
  EXPECT_LE(LogIndex{8000}, stats.commitIndex);
  EXPECT_LE(stats.commitIndex, stats.spearHead.index);
  stopAsyncMockLogs();
}

TEST_F(ReplicatedLogConcurrentTest, leaderWithFollowers) {
  using namespace std::chrono_literals;

  auto guard = scopeGuard([] {
    LOG_TOPIC("27bc7", FATAL, Logger::REPLICATION2)
        << "Test terminating early, aborting for debugging";
    FATAL_ERROR_ABORT();
  });

  auto leaderLog = makeReplicatedLog(LogId{1});
  auto follower1Log = makeReplicatedLog(LogId{2});
  auto follower2Log = makeReplicatedLog(LogId{3});

  auto follower1 = follower1Log->becomeFollower("follower1", LogTerm{1}, "leader");
  auto follower2 = follower2Log->becomeFollower("follower2", LogTerm{1}, "leader");
  auto leader =
      leaderLog->becomeLeader("leader", LogTerm{1},
                              {std::static_pointer_cast<AbstractFollower>(follower1),
                               std::static_pointer_cast<AbstractFollower>(follower2)},
                              2);

  auto data = ThreadCoordinationData{leader};

  // start replication
  auto replicationThread =
      std::thread{runReplicationWithIntermittentPauses, std::ref(data)};
  auto followerReplicationThread =
      std::thread{runFollowerReplicationWithIntermittentPauses,
                  std::vector{follower1.get(), follower2.get()}, std::ref(data)};

  std::vector<std::thread> clientThreads;
  auto threadCounter = uint16_t{0};
  clientThreads.emplace_back(alternatinglyInsertAndRead, threadCounter++, std::ref(data));
  clientThreads.emplace_back(insertManyThenRead, threadCounter++, std::ref(data));

  ASSERT_EQ(clientThreads.size(), threadCounter);
  while (data.threadsReady.load() < clientThreads.size()) {
  }
  data.go.store(true);
  while (data.threadsSatisfied.load() < clientThreads.size()) {
    std::this_thread::sleep_for(100us);
  }
  data.stopClientThreads.store(true);

  for (auto& thread : clientThreads) {
    thread.join();
  }

  // stop replication only after all client threads joined, so we don't block
  // them in some intermediate state
  data.stopReplicationThreads.store(true);
  replicationThread.join();
  followerReplicationThread.join();

  guard.cancel();

  auto stats = std::get<LeaderStatus>(data.log->getStatus().getVariant()).local;
  EXPECT_LE(LogIndex{8000}, stats.commitIndex);
  EXPECT_LE(stats.commitIndex, stats.spearHead.index);
}
<commit_msg>Suppress a useless warning (#14624)<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Tobias Gödderz
////////////////////////////////////////////////////////////////////////////////

#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>

#include "Replication2/ReplicatedLog/ILogParticipant.h"
#include "Replication2/ReplicatedLog/types.h"
#include "TestHelper.h"

#include <Basics/ScopeGuard.h>
#include <Basics/application-exit.h>

#include <functional>

using namespace arangodb;
using namespace arangodb::replication2;
using namespace arangodb::replication2::replicated_log;

struct ReplicatedLogConcurrentTest : ReplicatedLogTest {
  using ThreadIdx = uint16_t;
  using IterIdx = uint32_t;
  constexpr static auto maxIter = std::numeric_limits<IterIdx>::max();

  struct alignas(128) ThreadCoordinationData {
    // the testee
    std::shared_ptr<ILogParticipant> log;

    // only when set to true, all client threads start
    std::atomic<bool> go = false;
    // when set to true, client threads will stop after the current iteration,
    // whatever that means for them.
    std::atomic<bool> stopClientThreads = false;
    // when set to true, the replication thread stops. should be done only
    // after all client threads stopped to avoid them hanging while waiting on
    // replication.
    std::atomic<bool> stopReplicationThreads = false;
    // every thread increases this by one when it's ready to start
    std::atomic<std::size_t> threadsReady = 0;
    // every thread increases this by one when it's done a certain minimal
    // amount of work. This is to guarantee that all threads are running long
    // enough side by side.
    std::atomic<std::size_t> threadsSatisfied = 0;
  };

  // Used to generate payloads that are unique across threads.
  constexpr static auto genPayload = [](ThreadIdx thread, IterIdx i) {
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#endif
    // up to 5 digits for thread
    static_assert(std::numeric_limits<ThreadIdx>::max() <= 99'999);
    // up to 10 digits for i
    static_assert(std::numeric_limits<IterIdx>::max() <= 99'999'999'999);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

    // This should fit into short string optimization
    auto str = std::string(16, ' ');

    auto p = str.begin() + 5;
    // 1 digit for ':'
    *p = ':';

    do {
      --p;
      *p = static_cast<char>('0' + (thread % 10));
      thread /= 10;
    } while (thread > 0);
    p = str.end();
    do {
      --p;
      *p = static_cast<char>('0' + (i % 10));
      i /= 10;
    } while (i > 0);

    return str;
  };

  constexpr static auto alternatinglyInsertAndRead = [](ThreadIdx const threadIdx,
                                                        ThreadCoordinationData& data) {
    using namespace std::chrono_literals;
    auto log = std::dynamic_pointer_cast<LogLeader>(data.log);
    ASSERT_NE(log, nullptr);
    data.threadsReady.fetch_add(1);
    while (!data.go.load()) {
    }

    for (auto i = std::uint32_t{0}; i < maxIter && !data.stopClientThreads.load(); ++i) {
      auto const payload = LogPayload::createFromString(genPayload(threadIdx, i));
      auto const idx = log->insert(payload, false, LogLeader::doNotTriggerAsyncReplication);
      std::this_thread::sleep_for(1ns);
      auto fut = log->waitFor(idx);
      fut.get();
      auto snapshot = log->getReplicatedLogSnapshot();
      ASSERT_LT(0, idx.value);
      ASSERT_LE(idx.value, snapshot.size());
      auto const& entry = snapshot[idx.value - 1];
      EXPECT_EQ(idx, entry.entry().logIndex());
      EXPECT_EQ(payload, entry.entry().logPayload());
      if (i == 1000) {
        // we should have done at least a few iterations before finishing
        data.threadsSatisfied.fetch_add(1, std::memory_order_relaxed);
      }
    }
  };

  constexpr static auto insertManyThenRead = [](ThreadIdx const threadIdx,
                                                ThreadCoordinationData& data) {
    using namespace std::chrono_literals;
    auto log = std::dynamic_pointer_cast<LogLeader>(data.log);
    ASSERT_NE(log, nullptr);
    data.threadsReady.fetch_add(1);
    while (!data.go.load()) {
    }

    constexpr auto batch = 100;
    auto idxs = std::vector<LogIndex>{};
    idxs.resize(batch);

    for (auto i = std::uint32_t{0};
         i < maxIter && !data.stopClientThreads.load(); i += batch) {
      for (auto k = 0; k < batch && i + k < maxIter; ++k) {
        auto const payload = LogPayload::createFromString(genPayload(threadIdx, i + k));
        idxs[k] = log->insert(payload, false, LogLeader::doNotTriggerAsyncReplication);
      }
      std::this_thread::sleep_for(1ns);
      auto fut = log->waitFor(idxs.back());
      fut.get();
      auto snapshot = log->getReplicatedLogSnapshot();
      for (auto k = 0; k < batch && i + k < maxIter; ++k) {
        using namespace std::string_literals;
        auto const payload = std::optional(LogPayload::createFromString(genPayload(threadIdx, i + k)));
        auto const idx = idxs[k];
        ASSERT_LT(0, idx.value);
        ASSERT_LE(idx.value, snapshot.size());
        auto const& entry = snapshot[idx.value - 1];
        EXPECT_EQ(idx, entry.entry().logIndex());
        EXPECT_EQ(payload, entry.entry().logPayload())
            << VPackSlice(payload->dummy.data()).toJson() << " "
            << (entry.entry().logPayload()
                    ? VPackSlice(entry.entry().logPayload()->dummy.data()).toJson()
                    : "std::nullopt"s);
      }
      if (i == 10 * batch) {
        // we should have done at least a few iterations before finishing
        data.threadsSatisfied.fetch_add(1, std::memory_order_relaxed);
      }
    }
  };

  constexpr static auto runReplicationWithIntermittentPauses =
      [](ThreadCoordinationData& data) {
        using namespace std::chrono_literals;
        auto log = std::dynamic_pointer_cast<LogLeader>(data.log);
        ASSERT_NE(log, nullptr);
        for (auto i = 0;; ++i) {
          log->triggerAsyncReplication();
          if (i % 16) {
            std::this_thread::sleep_for(100ns);
            if (data.stopReplicationThreads.load()) {
              return;
            }
          }
        }
      };

  constexpr static auto runFollowerReplicationWithIntermittentPauses =
      // NOLINTNEXTLINE(performance-unnecessary-value-param)
      [](std::vector<DelayedFollowerLog*> followers, ThreadCoordinationData& data) {
        using namespace std::chrono_literals;
        for (auto i = 0;;) {
          for (auto* follower : followers) {
            follower->runAsyncAppendEntries();
            if (i % 17) {
              std::this_thread::sleep_for(100ns);
              if (data.stopReplicationThreads.load()) {
                return;
              }
            }
            ++i;
          }
        }
      };
};

TEST_F(ReplicatedLogConcurrentTest, genPayloadTest) {
  EXPECT_EQ("    0:         0", genPayload(0, 0));
  EXPECT_EQ("   11:        42", genPayload(11, 42));
  EXPECT_EQ("65535:4294967295", genPayload(65535, 4294967295));
}

TEST_F(ReplicatedLogConcurrentTest, lonelyLeader) {
  using namespace std::chrono_literals;

  auto replicatedLog = makeReplicatedLogWithAsyncMockLog(LogId{1});
  // TODO this test hangs because there is not local follower currently
  auto leaderLog = replicatedLog->becomeLeader("leader", LogTerm{1}, {}, 1);

  auto data = ThreadCoordinationData{leaderLog};

  // start replication
  auto replicationThread =
      std::thread{runReplicationWithIntermittentPauses, std::ref(data)};

  std::vector<std::thread> clientThreads;
  auto threadCounter = uint16_t{0};
  clientThreads.emplace_back(alternatinglyInsertAndRead, threadCounter++, std::ref(data));
  clientThreads.emplace_back(insertManyThenRead, threadCounter++, std::ref(data));

  ASSERT_EQ(clientThreads.size(), threadCounter);
  while (data.threadsReady.load() < clientThreads.size()) {
  }
  data.go.store(true);
  while (data.threadsSatisfied.load() < clientThreads.size()) {
    std::this_thread::sleep_for(100us);
  }
  data.stopClientThreads.store(true);

  for (auto& thread : clientThreads) {
    thread.join();
  }

  // stop replication only after all client threads joined, so we don't block
  // them in some intermediate state
  data.stopReplicationThreads.store(true);
  replicationThread.join();

  auto stats = std::get<LeaderStatus>(data.log->getStatus().getVariant()).local;
  EXPECT_LE(LogIndex{8000}, stats.commitIndex);
  EXPECT_LE(stats.commitIndex, stats.spearHead.index);
  stopAsyncMockLogs();
}

TEST_F(ReplicatedLogConcurrentTest, leaderWithFollowers) {
  using namespace std::chrono_literals;

  auto guard = scopeGuard([] {
    LOG_TOPIC("27bc7", FATAL, Logger::REPLICATION2)
        << "Test terminating early, aborting for debugging";
    FATAL_ERROR_ABORT();
  });

  auto leaderLog = makeReplicatedLog(LogId{1});
  auto follower1Log = makeReplicatedLog(LogId{2});
  auto follower2Log = makeReplicatedLog(LogId{3});

  auto follower1 = follower1Log->becomeFollower("follower1", LogTerm{1}, "leader");
  auto follower2 = follower2Log->becomeFollower("follower2", LogTerm{1}, "leader");
  auto leader =
      leaderLog->becomeLeader("leader", LogTerm{1},
                              {std::static_pointer_cast<AbstractFollower>(follower1),
                               std::static_pointer_cast<AbstractFollower>(follower2)},
                              2);

  auto data = ThreadCoordinationData{leader};

  // start replication
  auto replicationThread =
      std::thread{runReplicationWithIntermittentPauses, std::ref(data)};
  auto followerReplicationThread =
      std::thread{runFollowerReplicationWithIntermittentPauses,
                  std::vector{follower1.get(), follower2.get()}, std::ref(data)};

  std::vector<std::thread> clientThreads;
  auto threadCounter = uint16_t{0};
  clientThreads.emplace_back(alternatinglyInsertAndRead, threadCounter++, std::ref(data));
  clientThreads.emplace_back(insertManyThenRead, threadCounter++, std::ref(data));

  ASSERT_EQ(clientThreads.size(), threadCounter);
  while (data.threadsReady.load() < clientThreads.size()) {
  }
  data.go.store(true);
  while (data.threadsSatisfied.load() < clientThreads.size()) {
    std::this_thread::sleep_for(100us);
  }
  data.stopClientThreads.store(true);

  for (auto& thread : clientThreads) {
    thread.join();
  }

  // stop replication only after all client threads joined, so we don't block
  // them in some intermediate state
  data.stopReplicationThreads.store(true);
  replicationThread.join();
  followerReplicationThread.join();

  guard.cancel();

  auto stats = std::get<LeaderStatus>(data.log->getStatus().getVariant()).local;
  EXPECT_LE(LogIndex{8000}, stats.commitIndex);
  EXPECT_LE(stats.commitIndex, stats.spearHead.index);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: salframe.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ganaya $ $Date: 2000-11-13 21:12:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <string.h>

#define _SV_SALFRAME_CXX

#ifndef _SV_SALDATA_HXX
#include <saldata.hxx>
#endif
#ifndef _SV_SALGDI_HXX
#include <salgdi.hxx>
#endif
#ifndef _SV_SALFRAME_HXX
#include <salframe.hxx>
#endif
#ifndef _SV_VCLWINDOW_H
#include <VCLWindow.h>
#endif
#ifndef _SV_VCLGRAPHICS_H
#include <VCLGraphics.h>
#endif

// =======================================================================

SalFrame::SalFrame()
{
    SalData* pSalData = GetSalData();

    maFrameData.mhWnd               = 0;
    maFrameData.mpGraphics          = NULL;
    maFrameData.mpInst              = NULL;
    maFrameData.mpProc              = NULL;
    maFrameData.mnInputLang         = 0;
    maFrameData.mnInputCodePage     = 0;
    maFrameData.mbGraphics          = FALSE;
    maFrameData.mbCaption           = FALSE;
    maFrameData.mbBorder            = FALSE;
    maFrameData.mbSizeBorder        = FALSE;
    maFrameData.mbFullScreen        = FALSE;
    maFrameData.mbPresentation      = FALSE;
    maFrameData.mbInShow            = FALSE;
    maFrameData.mbRestoreMaximize   = FALSE;
    maFrameData.mbInMoveMsg         = FALSE;
    maFrameData.mbInSizeMsg         = FALSE;
    maFrameData.mbFullScreenToolWin = FALSE;
    maFrameData.mbDefPos            = TRUE;
    maFrameData.mbOverwriteState    = TRUE;
    maFrameData.mbIME               = FALSE;
    maFrameData.mbHandleIME         = FALSE;
    maFrameData.mbSpezIME           = FALSE;
    maFrameData.mbAtCursorIME       = FALSE;
    maFrameData.mbCompositionMode   = FALSE;
    maFrameData.mbCandidateMode     = FALSE;
    memset( &maFrameData.maState, 0, sizeof( SalFrameState ) );
    maFrameData.maSysData.nSize     = sizeof( SystemEnvData );
}

// -----------------------------------------------------------------------

SalFrame::~SalFrame()
{
}

// -----------------------------------------------------------------------

SalGraphics* SalFrame::GetGraphics()
{
    if ( maFrameData.mbGraphics )
        return NULL;

    if ( !maFrameData.mpGraphics )
    {
        VCLVIEW hView = VCLWindow_contentView( maFrameData.mhWnd );
        if ( hView )
        {
            SalData* pSalData = GetSalData();
            maFrameData.mpGraphics = new SalGraphics;
            maFrameData.mpGraphics->maGraphicsData.mhDC      = hView;
            maFrameData.mpGraphics->maGraphicsData.mhWnd     = maFrameData.mhWnd;
            maFrameData.mpGraphics->maGraphicsData.mbPrinter = FALSE;
            maFrameData.mpGraphics->maGraphicsData.mbVirDev  = FALSE;
            maFrameData.mpGraphics->maGraphicsData.mbWindow  = TRUE;
            maFrameData.mpGraphics->maGraphicsData.mbScreen  = TRUE;
            maFrameData.mbGraphics = TRUE;
        }
    }
    else
        maFrameData.mbGraphics = TRUE;

    return maFrameData.mpGraphics;
}

// -----------------------------------------------------------------------

void SalFrame::ReleaseGraphics( SalGraphics* )
{
}

// -----------------------------------------------------------------------

BOOL SalFrame::PostEvent( void* pData )
{
    return FALSE;
}

// -----------------------------------------------------------------------

void SalFrame::SetTitle( const XubString& rTitle )
{
  ByteString aByteTitle( rTitle, gsl_getSystemTextEncoding() );
  char *pTitle = (char*)aByteTitle.GetBuffer();
  VCLWindow_SetTitle(maFrameData.mhWnd, pTitle);
}

// -----------------------------------------------------------------------

void SalFrame::SetIcon( USHORT nIcon )
{
}

// -----------------------------------------------------------------------

void SalFrame::Show( BOOL bVisible )
{
    if ( bVisible )
        VCLWindow_makeKeyAndOrderFront( maFrameData.mhWnd );
    else
        VCLWindow_close( maFrameData.mhWnd );

    // This is temporary code for testing only and should be removed when
    // development of the SalObject class is complete. This code allows
    // us to test our SalGraphics drawing methods.

    // Get this window's cached handle to its native content view
    VCLVIEW hView = VCLWindow_contentView( maFrameData.mhWnd );

    // Draw a line on the native content view
    VCLGraphics_drawLine( hView, 0L, 0L, 1000L, 1000L );
}

// -----------------------------------------------------------------------

void SalFrame::Enable( BOOL bEnable )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetMinClientSize( long nWidth, long nHeight )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetClientSize( long nWidth, long nHeight )
{
}

// -----------------------------------------------------------------------

void SalFrame::GetClientSize( long& rWidth, long& rHeight )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetWindowState( const SalFrameState* pState )
{
}

// -----------------------------------------------------------------------

BOOL SalFrame::GetWindowState( SalFrameState* pState )
{
    return FALSE;
}

// -----------------------------------------------------------------------

void SalFrame::ShowFullScreen( BOOL bFullScreen )
{
}

// -----------------------------------------------------------------------

void SalFrame::StartPresentation( BOOL bStart )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
{
}

// -----------------------------------------------------------------------

void SalFrame::ToTop( USHORT nFlags )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetPointer( PointerStyle ePointerStyle )
{
}

// -----------------------------------------------------------------------

void SalFrame::CaptureMouse( BOOL bCapture )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetPointerPos( long nX, long nY )
{
}

// -----------------------------------------------------------------------

void SalFrame::Flush()
{
}

// -----------------------------------------------------------------------

void SalFrame::Sync()
{
}

// -----------------------------------------------------------------------

void SalFrame::SetInputContext( SalInputContext* pContext )
{
}

// -----------------------------------------------------------------------

void SalFrame::UpdateExtTextInputArea()
{
}

// -----------------------------------------------------------------------

void SalFrame::EndExtTextInput( USHORT nFlags )
{
}

// -----------------------------------------------------------------------

XubString SalFrame::GetKeyName( USHORT nKeyCode )
{
    return XubString();
}

// -----------------------------------------------------------------------

XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
{
    return GetKeyName( nKeyCode );
}

// -----------------------------------------------------------------------

void SalFrame::UpdateSettings( AllSettings& rSettings )
{
}

// -----------------------------------------------------------------------

const SystemEnvData* SalFrame::GetSystemData() const
{
    return NULL;
}

// -----------------------------------------------------------------------

void SalFrame::Beep( SoundType eSoundType )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
{
}
<commit_msg>Changed VCLWindow_SetTitle function to VCLWindow_setTitle to be consistent with other C function naming format.<commit_after>/*************************************************************************
 *
 *  $RCSfile: salframe.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: pluby $ $Date: 2000-11-14 00:18:56 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <string.h>

#define _SV_SALFRAME_CXX

#ifndef _SV_SALDATA_HXX
#include <saldata.hxx>
#endif
#ifndef _SV_SALGDI_HXX
#include <salgdi.hxx>
#endif
#ifndef _SV_SALFRAME_HXX
#include <salframe.hxx>
#endif
#ifndef _SV_VCLWINDOW_H
#include <VCLWindow.h>
#endif
#ifndef _SV_VCLGRAPHICS_H
#include <VCLGraphics.h>
#endif

// =======================================================================

SalFrame::SalFrame()
{
    SalData* pSalData = GetSalData();

    maFrameData.mhWnd               = 0;
    maFrameData.mpGraphics          = NULL;
    maFrameData.mpInst              = NULL;
    maFrameData.mpProc              = NULL;
    maFrameData.mnInputLang         = 0;
    maFrameData.mnInputCodePage     = 0;
    maFrameData.mbGraphics          = FALSE;
    maFrameData.mbCaption           = FALSE;
    maFrameData.mbBorder            = FALSE;
    maFrameData.mbSizeBorder        = FALSE;
    maFrameData.mbFullScreen        = FALSE;
    maFrameData.mbPresentation      = FALSE;
    maFrameData.mbInShow            = FALSE;
    maFrameData.mbRestoreMaximize   = FALSE;
    maFrameData.mbInMoveMsg         = FALSE;
    maFrameData.mbInSizeMsg         = FALSE;
    maFrameData.mbFullScreenToolWin = FALSE;
    maFrameData.mbDefPos            = TRUE;
    maFrameData.mbOverwriteState    = TRUE;
    maFrameData.mbIME               = FALSE;
    maFrameData.mbHandleIME         = FALSE;
    maFrameData.mbSpezIME           = FALSE;
    maFrameData.mbAtCursorIME       = FALSE;
    maFrameData.mbCompositionMode   = FALSE;
    maFrameData.mbCandidateMode     = FALSE;
    memset( &maFrameData.maState, 0, sizeof( SalFrameState ) );
    maFrameData.maSysData.nSize     = sizeof( SystemEnvData );
}

// -----------------------------------------------------------------------

SalFrame::~SalFrame()
{
}

// -----------------------------------------------------------------------

SalGraphics* SalFrame::GetGraphics()
{
    if ( maFrameData.mbGraphics )
        return NULL;

    if ( !maFrameData.mpGraphics )
    {
        VCLVIEW hView = VCLWindow_contentView( maFrameData.mhWnd );
        if ( hView )
        {
            SalData* pSalData = GetSalData();
            maFrameData.mpGraphics = new SalGraphics;
            maFrameData.mpGraphics->maGraphicsData.mhDC      = hView;
            maFrameData.mpGraphics->maGraphicsData.mhWnd     = maFrameData.mhWnd;
            maFrameData.mpGraphics->maGraphicsData.mbPrinter = FALSE;
            maFrameData.mpGraphics->maGraphicsData.mbVirDev  = FALSE;
            maFrameData.mpGraphics->maGraphicsData.mbWindow  = TRUE;
            maFrameData.mpGraphics->maGraphicsData.mbScreen  = TRUE;
            maFrameData.mbGraphics = TRUE;
        }
    }
    else
        maFrameData.mbGraphics = TRUE;

    return maFrameData.mpGraphics;
}

// -----------------------------------------------------------------------

void SalFrame::ReleaseGraphics( SalGraphics* )
{
}

// -----------------------------------------------------------------------

BOOL SalFrame::PostEvent( void* pData )
{
    return FALSE;
}

// -----------------------------------------------------------------------

void SalFrame::SetTitle( const XubString& rTitle )
{

    ByteString aByteTitle( rTitle, gsl_getSystemTextEncoding() );
    char *pTitle = (char *)aByteTitle.GetBuffer();
    VCLWindow_setTitle(maFrameData.mhWnd, pTitle);

}

// -----------------------------------------------------------------------

void SalFrame::SetIcon( USHORT nIcon )
{
}

// -----------------------------------------------------------------------

void SalFrame::Show( BOOL bVisible )
{
    if ( bVisible )
        VCLWindow_makeKeyAndOrderFront( maFrameData.mhWnd );
    else
        VCLWindow_close( maFrameData.mhWnd );

    // This is temporary code for testing only and should be removed when
    // development of the SalObject class is complete. This code allows
    // us to test our SalGraphics drawing methods.

    // Get this window's cached handle to its native content view
    VCLVIEW hView = VCLWindow_contentView( maFrameData.mhWnd );

    // Draw a line on the native content view
    VCLGraphics_drawLine( hView, 0L, 0L, 1000L, 1000L );
}

// -----------------------------------------------------------------------

void SalFrame::Enable( BOOL bEnable )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetMinClientSize( long nWidth, long nHeight )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetClientSize( long nWidth, long nHeight )
{
}

// -----------------------------------------------------------------------

void SalFrame::GetClientSize( long& rWidth, long& rHeight )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetWindowState( const SalFrameState* pState )
{
}

// -----------------------------------------------------------------------

BOOL SalFrame::GetWindowState( SalFrameState* pState )
{
    return FALSE;
}

// -----------------------------------------------------------------------

void SalFrame::ShowFullScreen( BOOL bFullScreen )
{
}

// -----------------------------------------------------------------------

void SalFrame::StartPresentation( BOOL bStart )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
{
}

// -----------------------------------------------------------------------

void SalFrame::ToTop( USHORT nFlags )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetPointer( PointerStyle ePointerStyle )
{
}

// -----------------------------------------------------------------------

void SalFrame::CaptureMouse( BOOL bCapture )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetPointerPos( long nX, long nY )
{
}

// -----------------------------------------------------------------------

void SalFrame::Flush()
{
}

// -----------------------------------------------------------------------

void SalFrame::Sync()
{
}

// -----------------------------------------------------------------------

void SalFrame::SetInputContext( SalInputContext* pContext )
{
}

// -----------------------------------------------------------------------

void SalFrame::UpdateExtTextInputArea()
{
}

// -----------------------------------------------------------------------

void SalFrame::EndExtTextInput( USHORT nFlags )
{
}

// -----------------------------------------------------------------------

XubString SalFrame::GetKeyName( USHORT nKeyCode )
{
    return XubString();
}

// -----------------------------------------------------------------------

XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
{
    return GetKeyName( nKeyCode );
}

// -----------------------------------------------------------------------

void SalFrame::UpdateSettings( AllSettings& rSettings )
{
}

// -----------------------------------------------------------------------

const SystemEnvData* SalFrame::GetSystemData() const
{
    return NULL;
}

// -----------------------------------------------------------------------

void SalFrame::Beep( SoundType eSoundType )
{
}

// -----------------------------------------------------------------------

void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
{
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2009-2016, MAV'RIC Development Team
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * 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.
 ******************************************************************************/

/*******************************************************************************
 * \file imu.c
 *
 * \author MAV'RIC Team
 * \author Felix Schill
 * \author Gregoire Heitz
 * \author Julien Lecoeur
 *
 * \brief Inertial measurement unit (IMU)
 *
 ******************************************************************************/

#include "sensing/imu.hpp"

extern "C"
{
#include "hal/common/time_keeper.hpp"
#include "util/print_util.h"
#include "util/constants.h"
}

Imu::Imu(Accelerometer& accelerometer, Gyroscope& gyroscope, Magnetometer& magnetometer, imu_conf_t config):
    accelerometer_(accelerometer),
    gyroscope_(gyroscope),
    magnetometer_(magnetometer),
    config_(config),
    oriented_acc_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    oriented_gyro_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    oriented_mag_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    scaled_acc_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    scaled_gyro_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    scaled_mag_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    do_accelerometer_bias_calibration_(false),
    do_gyroscope_bias_calibration_(false),
    do_magnetometer_bias_calibration_(false),
    is_ready_(false),
    dt_s_(0.004f),
    last_update_us_(time_keeper_get_us()),
    timestamp_gyro_stable(time_keeper_get_s())
{}

bool Imu::update(void)
{
    bool success = false;

    // Update timing
    uint32_t t      = time_keeper_get_us();
    dt_s_           = (float)(t - last_update_us_) / 1000000.0f;
    last_update_us_ = t;

    // Read new values from sensors
    success &= accelerometer_.update();
    success &= gyroscope_.update();
    success &= magnetometer_.update();

    // Retrieve data
    std::array<float, 3> raw_acc  = accelerometer_.acc();
    std::array<float, 3> raw_gyro = gyroscope_.gyro();
    std::array<float, 3> raw_mag  = magnetometer_.mag();

    // Rotate sensor values
    for (uint8_t i = 0; i < 3; i++)
    {
        oriented_acc_[i]  = raw_acc[  config_.accelerometer.axis[i] ] * config_.accelerometer.sign[i];
        oriented_gyro_[i] = raw_gyro[ config_.gyroscope.axis[i]     ] * config_.gyroscope.sign[i];
        oriented_mag_[i]  = raw_mag[  config_.magnetometer.axis[i]  ] * config_.magnetometer.sign[i];
    }

    // Scale sensor values
    float new_scaled_acc[3];
    float new_scaled_gyro[3];
    float new_scaled_mag[3];
    for (int8_t i = 0; i < 3; i++)
    {
        // Scale, then remove bias
        new_scaled_acc[i]  = oriented_acc_[i]  / config_.accelerometer.scale_factor[i] - config_.accelerometer.bias[i];
        new_scaled_gyro[i] = oriented_gyro_[i] / config_.gyroscope.scale_factor[i]     - config_.gyroscope.bias[i];
        new_scaled_mag[i]  = oriented_mag_[i]  / config_.magnetometer.scale_factor[i]  - config_.magnetometer.bias[i];

        // Low pass filter
        scaled_acc_[i]  = config_.lpf_acc   * new_scaled_acc[i]  + (1.0f - config_.lpf_acc) * scaled_acc_[i];
        scaled_gyro_[i] = config_.lpf_gyro  * new_scaled_gyro[i] + (1.0f - config_.lpf_gyro) * scaled_gyro_[i];
        scaled_mag_[i]  = config_.lpf_mag   * new_scaled_mag[i]  + (1.0f - config_.lpf_mag) * scaled_mag_[i];
    }

    // Do automatic gyroscope calibration at startup
    do_startup_calibration();

    // Perform calibration of sensors
    do_calibration();

    return success;
}

const float& Imu::last_update_us(void) const
{
    return last_update_us_;
}

const float& Imu::dt_s(void) const
{
    return dt_s_;
}

const std::array<float, 3>& Imu::acc(void) const
{
    return scaled_acc_;
}

const std::array<float, 3>& Imu::gyro(void) const
{
    return scaled_gyro_;
}

const std::array<float, 3>& Imu::mag(void) const
{
    return scaled_mag_;
}

imu_conf_t* Imu::get_config(void)
{
    return &config_;
}

bool Imu::start_accelerometer_bias_calibration(void)
{
    // Success if not already doing magnetometer calibration
    bool success = !do_magnetometer_bias_calibration_;

    if (success)
    {
        do_accelerometer_bias_calibration_      = true;
        config_.accelerometer.mean_values[X]    = scaled_acc_[X];
        config_.accelerometer.mean_values[Y]    = scaled_acc_[Y];
        config_.accelerometer.mean_values[Z]    = scaled_acc_[Z];
    }

    return success;
}

bool Imu::start_gyroscope_bias_calibration(void)
{
    // Success if not already doing magnetometer calibration
    bool success = !do_magnetometer_bias_calibration_;

    if (success)
    {
        do_gyroscope_bias_calibration_      = true;
        config_.gyroscope.mean_values[X]    = scaled_gyro_[X];
        config_.gyroscope.mean_values[Y]    = scaled_gyro_[Y];
        config_.gyroscope.mean_values[Z]    = scaled_gyro_[Z];
    }

    return success;
}

bool Imu::start_magnetometer_bias_calibration(void)
{
    // Success if not already doing accelerometer or gyroscope calibration
    bool success  = true;
    success &= !do_accelerometer_bias_calibration_;
    success &= !do_gyroscope_bias_calibration_;

    if (success)
    {
        do_magnetometer_bias_calibration_   = true;
        config_.magnetometer.max_values[X]  = -10000.0f;
        config_.magnetometer.max_values[Y]  = -10000.0f;
        config_.magnetometer.max_values[Z]  = -10000.0f;
        config_.magnetometer.min_values[X]  =  10000.0f;
        config_.magnetometer.min_values[Y]  =  10000.0f;
        config_.magnetometer.min_values[Z]  =  10000.0f;
    }

    return success;
}

bool Imu::stop_accelerometer_bias_calibration(void)
{
    // Success if calibration is ongoing
    bool success = do_accelerometer_bias_calibration_;

    // Stop calibrating
    do_accelerometer_bias_calibration_ = false;

    // Update biases
    if (success)
    {
        config_.accelerometer.bias[X] += config_.accelerometer.mean_values[X];
        config_.accelerometer.bias[Y] += config_.accelerometer.mean_values[Y];
        config_.accelerometer.bias[Z] += config_.accelerometer.mean_values[Z] - (-1.0f);
    }

    return success;
}

bool Imu::stop_gyroscope_bias_calibration(void)
{
    // Success if calibration is ongoing
    bool success = do_gyroscope_bias_calibration_;

    // Stop calibrating
    do_gyroscope_bias_calibration_ = false;

    // Update biases
    if (success)
    {
        config_.gyroscope.bias[X] += config_.gyroscope.mean_values[X];
        config_.gyroscope.bias[Y] += config_.gyroscope.mean_values[Y];
        config_.gyroscope.bias[Z] += config_.gyroscope.mean_values[Z];
    }

    return success;
}

bool Imu::stop_magnetometer_bias_calibration(void)
{
    // Success if calibration is ongoing
    bool success = do_magnetometer_bias_calibration_;

    // Stop calibrating
    do_magnetometer_bias_calibration_ = false;

    // Update biases
    config_.magnetometer.bias[X] += 0.5f * (config_.magnetometer.max_values[X] + config_.magnetometer.min_values[X]);
    config_.magnetometer.bias[Y] += 0.5f * (config_.magnetometer.max_values[Y] + config_.magnetometer.min_values[Y]);
    config_.magnetometer.bias[Z] += 0.5f * (config_.magnetometer.max_values[Z] + config_.magnetometer.min_values[Z]);

    return success;
}

const bool Imu::is_ready(void) const
{
    return is_ready_;
}

void Imu::do_startup_calibration(void)
{
    if (is_ready_ == false)
    {
        // Make sure calibration is ongoing
        if (do_gyroscope_bias_calibration_ == false)
        {
            start_gyroscope_bias_calibration();
            timestamp_gyro_stable = time_keeper_get_s();
        }

        // Check if the gyroscope values are stable
        bool gyro_is_stable = (maths_f_abs(config_.gyroscope.mean_values[X] - scaled_gyro_[X]) < config_.startup_calib_gyro_threshold)
                              && (maths_f_abs(config_.gyroscope.mean_values[Y] - scaled_gyro_[Y]) < config_.startup_calib_gyro_threshold)
                              && (maths_f_abs(config_.gyroscope.mean_values[Z] - scaled_gyro_[Z]) < config_.startup_calib_gyro_threshold);

        if (gyro_is_stable == false)
        {
            is_ready_ = false;
            // Reset timestamp
            timestamp_gyro_stable = time_keeper_get_s();
        }

        // If gyros have been stable for long enough
        if ((gyro_is_stable == true) && ((time_keeper_get_s() - timestamp_gyro_stable) > config_.startup_calib_duration_s))
        {
            // Sartup calibration is done
            is_ready_ = true;
            stop_gyroscope_bias_calibration();
        }
    }
}

void Imu::do_calibration(void)
{
    // Do accelero bias calibration
    if (do_accelerometer_bias_calibration_)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            config_.accelerometer.mean_values[i] = (1.0f - config_.lpf_mean) * config_.accelerometer.mean_values[i] + config_.lpf_mean * scaled_acc_[i];
        }
    }

    // Do gyroscope bias calibration
    if (do_gyroscope_bias_calibration_)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            config_.gyroscope.mean_values[i] = (1.0f - config_.lpf_mean) * config_.gyroscope.mean_values[i] + config_.lpf_mean * scaled_gyro_[i];
        }
    }

    // Do magnetometer bias calibration
    if (do_magnetometer_bias_calibration_)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            config_.magnetometer.max_values[i]  = maths_f_max(config_.magnetometer.max_values[i], scaled_mag_[i]);
            config_.magnetometer.min_values[i]  = maths_f_min(config_.magnetometer.min_values[i], scaled_mag_[i]);
        }
    }
}<commit_msg>reset imu_ready_ flag in case of calibration (#210)<commit_after>/*******************************************************************************
 * Copyright (c) 2009-2016, MAV'RIC Development Team
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * 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.
 ******************************************************************************/

/*******************************************************************************
 * \file imu.c
 *
 * \author MAV'RIC Team
 * \author Felix Schill
 * \author Gregoire Heitz
 * \author Julien Lecoeur
 *
 * \brief Inertial measurement unit (IMU)
 *
 ******************************************************************************/

#include "sensing/imu.hpp"

extern "C"
{
#include "hal/common/time_keeper.hpp"
#include "util/print_util.h"
#include "util/constants.h"
}

Imu::Imu(Accelerometer& accelerometer, Gyroscope& gyroscope, Magnetometer& magnetometer, imu_conf_t config):
    accelerometer_(accelerometer),
    gyroscope_(gyroscope),
    magnetometer_(magnetometer),
    config_(config),
    oriented_acc_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    oriented_gyro_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    oriented_mag_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    scaled_acc_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    scaled_gyro_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    scaled_mag_(std::array<float,3>{{0.0f, 0.0f, 0.0f}}),
    do_accelerometer_bias_calibration_(false),
    do_gyroscope_bias_calibration_(false),
    do_magnetometer_bias_calibration_(false),
    is_ready_(false),
    dt_s_(0.004f),
    last_update_us_(time_keeper_get_us()),
    timestamp_gyro_stable(time_keeper_get_s())
{}

bool Imu::update(void)
{
    bool success = false;

    // Update timing
    uint32_t t      = time_keeper_get_us();
    dt_s_           = (float)(t - last_update_us_) / 1000000.0f;
    last_update_us_ = t;

    // Read new values from sensors
    success &= accelerometer_.update();
    success &= gyroscope_.update();
    success &= magnetometer_.update();

    // Retrieve data
    std::array<float, 3> raw_acc  = accelerometer_.acc();
    std::array<float, 3> raw_gyro = gyroscope_.gyro();
    std::array<float, 3> raw_mag  = magnetometer_.mag();

    // Rotate sensor values
    for (uint8_t i = 0; i < 3; i++)
    {
        oriented_acc_[i]  = raw_acc[  config_.accelerometer.axis[i] ] * config_.accelerometer.sign[i];
        oriented_gyro_[i] = raw_gyro[ config_.gyroscope.axis[i]     ] * config_.gyroscope.sign[i];
        oriented_mag_[i]  = raw_mag[  config_.magnetometer.axis[i]  ] * config_.magnetometer.sign[i];
    }

    // Scale sensor values
    float new_scaled_acc[3];
    float new_scaled_gyro[3];
    float new_scaled_mag[3];
    for (int8_t i = 0; i < 3; i++)
    {
        // Scale, then remove bias
        new_scaled_acc[i]  = oriented_acc_[i]  / config_.accelerometer.scale_factor[i] - config_.accelerometer.bias[i];
        new_scaled_gyro[i] = oriented_gyro_[i] / config_.gyroscope.scale_factor[i]     - config_.gyroscope.bias[i];
        new_scaled_mag[i]  = oriented_mag_[i]  / config_.magnetometer.scale_factor[i]  - config_.magnetometer.bias[i];

        // Low pass filter
        scaled_acc_[i]  = config_.lpf_acc   * new_scaled_acc[i]  + (1.0f - config_.lpf_acc) * scaled_acc_[i];
        scaled_gyro_[i] = config_.lpf_gyro  * new_scaled_gyro[i] + (1.0f - config_.lpf_gyro) * scaled_gyro_[i];
        scaled_mag_[i]  = config_.lpf_mag   * new_scaled_mag[i]  + (1.0f - config_.lpf_mag) * scaled_mag_[i];
    }

    // Do automatic gyroscope calibration at startup
    do_startup_calibration();

    // Perform calibration of sensors
    do_calibration();

    return success;
}

const float& Imu::last_update_us(void) const
{
    return last_update_us_;
}

const float& Imu::dt_s(void) const
{
    return dt_s_;
}

const std::array<float, 3>& Imu::acc(void) const
{
    return scaled_acc_;
}

const std::array<float, 3>& Imu::gyro(void) const
{
    return scaled_gyro_;
}

const std::array<float, 3>& Imu::mag(void) const
{
    return scaled_mag_;
}

imu_conf_t* Imu::get_config(void)
{
    return &config_;
}

bool Imu::start_accelerometer_bias_calibration(void)
{
    // Success if not already doing magnetometer calibration
    // Since this calib needs the robot to remain still,
    //      whereas for the magneto calib we need to move the robot
    bool success = !do_magnetometer_bias_calibration_;

    if (success)
    {
        // Start calibration
        is_ready_ = false;
        do_accelerometer_bias_calibration_      = true;
        config_.accelerometer.mean_values[X]    = scaled_acc_[X];
        config_.accelerometer.mean_values[Y]    = scaled_acc_[Y];
        config_.accelerometer.mean_values[Z]    = scaled_acc_[Z];
    }

    return success;
}

bool Imu::start_gyroscope_bias_calibration(void)
{
    // Success if not already doing magnetometer calibration
    // Since this calib needs the robot to remain still,
    //      whereas for the magneto calib we need to move the robot
    bool success = !do_magnetometer_bias_calibration_;

    if (success)
    {
        // Start calibration
        is_ready_ = false;
        do_gyroscope_bias_calibration_      = true;
        config_.gyroscope.mean_values[X]    = scaled_gyro_[X];
        config_.gyroscope.mean_values[Y]    = scaled_gyro_[Y];
        config_.gyroscope.mean_values[Z]    = scaled_gyro_[Z];
    }

    return success;
}

bool Imu::start_magnetometer_bias_calibration(void)
{
    // Success if not already doing accelerometer or gyroscope calibration
    // Since this calib needs the robot to be moved,
    //      whereas for the 2 other calibs we need to have the robot still
    bool success  = true;
    success &= !do_accelerometer_bias_calibration_;
    success &= !do_gyroscope_bias_calibration_;

    if (success)
    {
        // Start calibration
        is_ready_ = false;
        do_magnetometer_bias_calibration_   = true;
        config_.magnetometer.max_values[X]  = -10000.0f;
        config_.magnetometer.max_values[Y]  = -10000.0f;
        config_.magnetometer.max_values[Z]  = -10000.0f;
        config_.magnetometer.min_values[X]  =  10000.0f;
        config_.magnetometer.min_values[Y]  =  10000.0f;
        config_.magnetometer.min_values[Z]  =  10000.0f;
    }

    return success;
}

bool Imu::stop_accelerometer_bias_calibration(void)
{
    // Success if calibration is ongoing
    bool success = do_accelerometer_bias_calibration_;

    // Stop calibrating
    do_accelerometer_bias_calibration_ = false;

    // Update biases
    if (success)
    {
        // Stop calibration
        is_ready_ = true;
        config_.accelerometer.bias[X] += config_.accelerometer.mean_values[X];
        config_.accelerometer.bias[Y] += config_.accelerometer.mean_values[Y];
        config_.accelerometer.bias[Z] += config_.accelerometer.mean_values[Z] - (-1.0f);
    }

    return success;
}

bool Imu::stop_gyroscope_bias_calibration(void)
{
    // Success if calibration is ongoing
    bool success = do_gyroscope_bias_calibration_;

    // Stop calibrating
    do_gyroscope_bias_calibration_ = false;

    // Update biases
    if (success)
    {
        // Stop calibration
        is_ready_ = true;
        config_.gyroscope.bias[X] += config_.gyroscope.mean_values[X];
        config_.gyroscope.bias[Y] += config_.gyroscope.mean_values[Y];
        config_.gyroscope.bias[Z] += config_.gyroscope.mean_values[Z];
    }

    return success;
}

bool Imu::stop_magnetometer_bias_calibration(void)
{
    // Success if calibration is ongoing
    bool success = do_magnetometer_bias_calibration_;

    // Stop calibrating
    do_magnetometer_bias_calibration_ = false;

    // Update biases
    if (success)
    {
        // Stop calibration
        is_ready_ = true;
        config_.magnetometer.bias[X] += 0.5f * (config_.magnetometer.max_values[X] + config_.magnetometer.min_values[X]);
        config_.magnetometer.bias[Y] += 0.5f * (config_.magnetometer.max_values[Y] + config_.magnetometer.min_values[Y]);
        config_.magnetometer.bias[Z] += 0.5f * (config_.magnetometer.max_values[Z] + config_.magnetometer.min_values[Z]);
    }

    return success;
}

const bool Imu::is_ready(void) const
{
    return is_ready_;
}

void Imu::do_startup_calibration(void)
{
    if (is_ready_ == false)
    {
        // Make sure calibration is ongoing
        if (do_gyroscope_bias_calibration_ == false)
        {
            start_gyroscope_bias_calibration();
            timestamp_gyro_stable = time_keeper_get_s();
        }

        // Check if the gyroscope values are stable
        bool gyro_is_stable = (maths_f_abs(config_.gyroscope.mean_values[X] - scaled_gyro_[X]) < config_.startup_calib_gyro_threshold)
                              && (maths_f_abs(config_.gyroscope.mean_values[Y] - scaled_gyro_[Y]) < config_.startup_calib_gyro_threshold)
                              && (maths_f_abs(config_.gyroscope.mean_values[Z] - scaled_gyro_[Z]) < config_.startup_calib_gyro_threshold);

        if (gyro_is_stable == false)
        {
            is_ready_ = false;
            // Reset timestamp
            timestamp_gyro_stable = time_keeper_get_s();
        }

        // If gyros have been stable for long enough
        if ((gyro_is_stable == true) && ((time_keeper_get_s() - timestamp_gyro_stable) > config_.startup_calib_duration_s))
        {
            // Sartup calibration is done
            is_ready_ = true;
            stop_gyroscope_bias_calibration();
        }
    }
}

void Imu::do_calibration(void)
{
    // Do accelero bias calibration
    if (do_accelerometer_bias_calibration_)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            config_.accelerometer.mean_values[i] = (1.0f - config_.lpf_mean) * config_.accelerometer.mean_values[i] + config_.lpf_mean * scaled_acc_[i];
        }
    }

    // Do gyroscope bias calibration
    if (do_gyroscope_bias_calibration_)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            config_.gyroscope.mean_values[i] = (1.0f - config_.lpf_mean) * config_.gyroscope.mean_values[i] + config_.lpf_mean * scaled_gyro_[i];
        }
    }

    // Do magnetometer bias calibration
    if (do_magnetometer_bias_calibration_)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            config_.magnetometer.max_values[i]  = maths_f_max(config_.magnetometer.max_values[i], scaled_mag_[i]);
            config_.magnetometer.min_values[i]  = maths_f_min(config_.magnetometer.min_values[i], scaled_mag_[i]);
        }
    }
}<|endoftext|>


<commit_before>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2008 Appcelerator, Inc. All Rights Reserved.
 */
#include <signal.h>
#include "php_module.h"
#include <Poco/Path.h>

#ifdef ZTS
void ***tsrm_ls;
#endif

namespace kroll
{
    KROLL_MODULE(PhpModule, STRING(MODULE_NAME), STRING(MODULE_VERSION));

    PhpModule* PhpModule::instance_ = NULL;

    void PhpModule::Initialize()
    {
        PhpModule::instance_ = this;

        int argc = 1;
        char *argv[] = { NULL };
        php_embed_init(argc, argv PTSRMLS_CC);
    }

    void PhpModule::Stop()
    {
        PhpModule::instance_ = NULL;

        php_embed_shutdown(TSRMLS_C);
    }

    void PhpModule::InitializeBinding()
    {
    }

    const static std::string php_suffix = "module.php";

    bool PhpModule::IsModule(std::string& path)
    {
        return (path.substr(path.length()-php_suffix.length()) == php_suffix);
    }

    Module* PhpModule::CreateModule(std::string& path)
    {
        // TODO: Open and load the file path with PHP

        Poco::Path p(path);
        std::string basename = p.getBaseName();
        std::string name = basename.substr(0,basename.length()-php_suffix.length()+4);
        std::string moduledir = path.substr(0,path.length()-basename.length()-4);

        Logger *logger = Logger::Get("PHP");
        logger->Info("Loading PHP path=%s", path.c_str());

        return new PhpModuleInstance(host, path, moduledir, name);
    }
}
<commit_msg>Loading and executing path.c_str() in the PHP module.<commit_after>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2008 Appcelerator, Inc. All Rights Reserved.
 */
#include <signal.h>
#include "php_module.h"
#include <Poco/Path.h>

#ifdef ZTS
void ***tsrm_ls;
#endif

namespace kroll
{
    KROLL_MODULE(PhpModule, STRING(MODULE_NAME), STRING(MODULE_VERSION));

    PhpModule* PhpModule::instance_ = NULL;

    void PhpModule::Initialize()
    {
        PhpModule::instance_ = this;

        int argc = 1;
        char *argv[2] = { "php_kroll", NULL };
        php_embed_init(argc, argv PTSRMLS_CC);
    }

    void PhpModule::Stop()
    {
        PhpModule::instance_ = NULL;

        php_embed_shutdown(TSRMLS_C);
    }

    void PhpModule::InitializeBinding()
    {
    }

    const static std::string php_suffix = "module.php";

    bool PhpModule::IsModule(std::string& path)
    {
        return (path.substr(path.length()-php_suffix.length()) == php_suffix);
    }

    Module* PhpModule::CreateModule(std::string& path)
    {
        zend_first_try {
            char *include_script;
            spprintf(&include_script, 0, "include '%s';", path.c_str());
            zend_eval_string(include_script, NULL, (char *) path.c_str() TSRMLS_CC);
            efree(include_script);
        } zend_end_try();

        Poco::Path p(path);
        std::string basename = p.getBaseName();
        std::string name = basename.substr(0,basename.length()-php_suffix.length()+4);
        std::string moduledir = path.substr(0,path.length()-basename.length()-4);

        Logger *logger = Logger::Get("PHP");
        logger->Info("Loading PHP path=%s", path.c_str());

        return new PhpModuleInstance(host, path, moduledir, name);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/common/application_info.h"

#include <windows.h>  // windows.h must be included first

#include <VersionHelpers.h>
#include <appmodel.h>
#include <shlobj.h>

#include <memory>

#include "base/file_version_info.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "shell/browser/win/scoped_hstring.h"

namespace electron {

namespace {

base::string16 g_app_user_model_id;
}

const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1";

std::string GetApplicationName() {
  auto* module = GetModuleHandle(nullptr);
  std::unique_ptr<FileVersionInfo> info(
      FileVersionInfo::CreateFileVersionInfoForModule(module));
  return base::UTF16ToUTF8(info->product_name());
}

std::string GetApplicationVersion() {
  auto* module = GetModuleHandle(nullptr);
  std::unique_ptr<FileVersionInfo> info(
      FileVersionInfo::CreateFileVersionInfoForModule(module));
  return base::UTF16ToUTF8(info->product_version());
}

void SetAppUserModelID(const base::string16& name) {
  g_app_user_model_id = name;
  SetCurrentProcessExplicitAppUserModelID(g_app_user_model_id.c_str());
}

PCWSTR GetRawAppUserModelID() {
  if (g_app_user_model_id.empty()) {
    PWSTR current_app_id;
    if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&current_app_id))) {
      g_app_user_model_id = current_app_id;
    } else {
      std::string name = GetApplicationName();
      base::string16 generated_app_id = base::ReplaceStringPlaceholders(
          kAppUserModelIDFormat, base::UTF8ToUTF16(name), nullptr);
      SetAppUserModelID(generated_app_id);
    }
    CoTaskMemFree(current_app_id);
  }

  return g_app_user_model_id.c_str();
}

bool GetAppUserModelID(ScopedHString* app_id) {
  app_id->Reset(GetRawAppUserModelID());
  return app_id->success();
}

bool IsRunningInDesktopBridgeImpl() {
  if (IsWindows8OrGreater()) {
    // GetPackageFamilyName is not available on Windows 7
    using GetPackageFamilyNameFuncPtr = decltype(&GetPackageFamilyName);

    static bool initialize_get_package_family_name = true;
    static GetPackageFamilyNameFuncPtr get_package_family_namePtr = NULL;

    if (initialize_get_package_family_name) {
      initialize_get_package_family_name = false;
      HMODULE kernel32_base = GetModuleHandle(L"Kernel32.dll");
      if (!kernel32_base) {
        NOTREACHED() << " " << __FUNCTION__ << "(): Can't open Kernel32.dll";
        return false;
      }

      get_package_family_namePtr =
          reinterpret_cast<GetPackageFamilyNameFuncPtr>(
              GetProcAddress(kernel32_base, "GetPackageFamilyName"));

      if (!get_package_family_namePtr) {
        return false;
      }
    }

    UINT32 length;
    wchar_t packageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH + 1];
    HANDLE proc = GetCurrentProcess();
    LONG result =
        (*get_package_family_namePtr)(proc, &length, packageFamilyName);

    return result == ERROR_SUCCESS;
  } else {
    return false;
  }
}

bool IsRunningInDesktopBridge() {
  static bool result = IsRunningInDesktopBridgeImpl();
  return result;
}

}  // namespace electron
<commit_msg>fix: pass correct buffer length (#23785)<commit_after>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/common/application_info.h"

#include <windows.h>  // windows.h must be included first

#include <VersionHelpers.h>
#include <appmodel.h>
#include <shlobj.h>

#include <memory>

#include "base/file_version_info.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "shell/browser/win/scoped_hstring.h"

namespace electron {

namespace {

base::string16 g_app_user_model_id;
}

const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1";

std::string GetApplicationName() {
  auto* module = GetModuleHandle(nullptr);
  std::unique_ptr<FileVersionInfo> info(
      FileVersionInfo::CreateFileVersionInfoForModule(module));
  return base::UTF16ToUTF8(info->product_name());
}

std::string GetApplicationVersion() {
  auto* module = GetModuleHandle(nullptr);
  std::unique_ptr<FileVersionInfo> info(
      FileVersionInfo::CreateFileVersionInfoForModule(module));
  return base::UTF16ToUTF8(info->product_version());
}

void SetAppUserModelID(const base::string16& name) {
  g_app_user_model_id = name;
  SetCurrentProcessExplicitAppUserModelID(g_app_user_model_id.c_str());
}

PCWSTR GetRawAppUserModelID() {
  if (g_app_user_model_id.empty()) {
    PWSTR current_app_id;
    if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&current_app_id))) {
      g_app_user_model_id = current_app_id;
    } else {
      std::string name = GetApplicationName();
      base::string16 generated_app_id = base::ReplaceStringPlaceholders(
          kAppUserModelIDFormat, base::UTF8ToUTF16(name), nullptr);
      SetAppUserModelID(generated_app_id);
    }
    CoTaskMemFree(current_app_id);
  }

  return g_app_user_model_id.c_str();
}

bool GetAppUserModelID(ScopedHString* app_id) {
  app_id->Reset(GetRawAppUserModelID());
  return app_id->success();
}

bool IsRunningInDesktopBridgeImpl() {
  if (IsWindows8OrGreater()) {
    // GetPackageFamilyName is not available on Windows 7
    using GetPackageFamilyNameFuncPtr = decltype(&GetPackageFamilyName);

    static bool initialize_get_package_family_name = true;
    static GetPackageFamilyNameFuncPtr get_package_family_namePtr = NULL;

    if (initialize_get_package_family_name) {
      initialize_get_package_family_name = false;
      HMODULE kernel32_base = GetModuleHandle(L"Kernel32.dll");
      if (!kernel32_base) {
        NOTREACHED() << " " << __FUNCTION__ << "(): Can't open Kernel32.dll";
        return false;
      }

      get_package_family_namePtr =
          reinterpret_cast<GetPackageFamilyNameFuncPtr>(
              GetProcAddress(kernel32_base, "GetPackageFamilyName"));

      if (!get_package_family_namePtr) {
        return false;
      }
    }

    UINT32 length = PACKAGE_FAMILY_NAME_MAX_LENGTH;
    wchar_t packageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH];
    HANDLE proc = GetCurrentProcess();
    LONG result =
        (*get_package_family_namePtr)(proc, &length, packageFamilyName);

    return result == ERROR_SUCCESS;
  } else {
    return false;
  }
}

bool IsRunningInDesktopBridge() {
  static bool result = IsRunningInDesktopBridgeImpl();
  return result;
}

}  // namespace electron
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: shellexec.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-06-17 11:35:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SHELLEXEC_HXX_
#define _SHELLEXEC_HXX_

#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#ifndef _COM_SUN_STAR_SYS_SHELL_XSYSTEMSHELLEXECUTE_HPP_
#include <com/sun/star/system/XSystemShellExecute.hpp>
#endif

//----------------------------------------------------------
// class declaration
//----------------------------------------------------------

class ShellExec : public ::cppu::WeakImplHelper2< com::sun::star::system::XSystemShellExecute, com::sun::star::lang::XServiceInfo >
{
    ::rtl::OString m_aDesktopEnvironment;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
    m_xContext;

public:
    ShellExec(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext);

    //------------------------------------------------
    // XSystemShellExecute
    //------------------------------------------------

    virtual void SAL_CALL execute( const ::rtl::OUString& aCommand, const ::rtl::OUString& aParameter, sal_Int32 nFlags )
        throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::system::SystemShellExecuteException, ::com::sun::star::uno::RuntimeException);

    //------------------------------------------------
    // XServiceInfo
    //------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName(  )
        throw(::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
        throw(::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  )
        throw(::com::sun::star::uno::RuntimeException);
};

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.104); FILE MERGED 2005/09/05 14:05:06 rt 1.3.104.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: shellexec.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:54:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SHELLEXEC_HXX_
#define _SHELLEXEC_HXX_

#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#ifndef _COM_SUN_STAR_SYS_SHELL_XSYSTEMSHELLEXECUTE_HPP_
#include <com/sun/star/system/XSystemShellExecute.hpp>
#endif

//----------------------------------------------------------
// class declaration
//----------------------------------------------------------

class ShellExec : public ::cppu::WeakImplHelper2< com::sun::star::system::XSystemShellExecute, com::sun::star::lang::XServiceInfo >
{
    ::rtl::OString m_aDesktopEnvironment;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
    m_xContext;

public:
    ShellExec(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext);

    //------------------------------------------------
    // XSystemShellExecute
    //------------------------------------------------

    virtual void SAL_CALL execute( const ::rtl::OUString& aCommand, const ::rtl::OUString& aParameter, sal_Int32 nFlags )
        throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::system::SystemShellExecuteException, ::com::sun::star::uno::RuntimeException);

    //------------------------------------------------
    // XServiceInfo
    //------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName(  )
        throw(::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
        throw(::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  )
        throw(::com::sun::star::uno::RuntimeException);
};

#endif
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2076
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1251574 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/03/28 03:00:10<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2077
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1724
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1117259 by johtaylo@johtaylo-JTBUILDER03-increment on 2015/01/31 03:00:13<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1725
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>