<commit_before>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */

#include "string.h"

#include "array.h"
#include "class-inl.h"
#include "gc/accounting/card_table-inl.h"
#include "intern_table.h"
#include "object-inl.h"
#include "runtime.h"
#include "sirt_ref.h"
#include "thread.h"
#include "utf-inl.h"

namespace art {
namespace mirror {

const CharArray* String::GetCharArray() const {
  return GetFieldObject<const CharArray*>(ValueOffset(), false);
}

CharArray* String::GetCharArray() {
  return GetFieldObject<CharArray*>(ValueOffset(), false);
}

void String::ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
}

int32_t String::GetUtfLength() const {
  return CountUtf8Bytes(GetCharArray()->GetData() + GetOffset(), GetLength());
}

int32_t String::FastIndexOf(int32_t ch, int32_t start) const {
  int32_t count = GetLength();
  if (start < 0) {
    start = 0;
  } else if (start > count) {
    start = count;
  }
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  const uint16_t* p = chars + start;
  const uint16_t* end = chars + count;
  while (p < end) {
    if (*p++ == ch) {
      return (p - 1) - chars;
    }
  }
  return -1;
}

void String::SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  DCHECK(new_array != NULL);
  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array, false);
}

// TODO: get global references for these
Class* String::java_lang_String_ = NULL;

void String::SetClass(Class* java_lang_String) {
  CHECK(java_lang_String_ == NULL);
  CHECK(java_lang_String != NULL);
  java_lang_String_ = java_lang_String;
}

void String::ResetClass() {
  CHECK(java_lang_String_ != NULL);
  java_lang_String_ = NULL;
}

String* String::Intern() {
  return Runtime::Current()->GetInternTable()->InternWeak(this);
}

int32_t String::GetHashCode() {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  if (result == 0) {
    ComputeHashCode();
  }
  result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
          << ToModifiedUtf8() << " " << result;
  return result;
}

int32_t String::GetLength() const {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
  DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
  return result;
}

uint16_t String::CharAt(int32_t index) const {
  // TODO: do we need this? Equals is the only caller, and could
  // bounds check itself.
  DCHECK_GE(count_, 0);  // ensures the unsigned comparison is safe.
  if (UNLIKELY(static_cast<uint32_t>(index) >= static_cast<uint32_t>(count_))) {
    Thread* self = Thread::Current();
    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    self->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
                             "length=%i; index=%i", count_, index);
    return 0;
  }
  return GetCharArray()->Get(index + GetOffset());
}

String* String::AllocFromUtf16(Thread* self,
                               int32_t utf16_length,
                               const uint16_t* utf16_data_in,
                               int32_t hash_code) {
  CHECK(utf16_data_in != NULL || utf16_length == 0);
  String* string = Alloc(self, utf16_length);
  if (UNLIKELY(string == nullptr)) {
    return nullptr;
  }
  // TODO: use 16-bit wide memset variant
  CharArray* array = const_cast<CharArray*>(string->GetCharArray());
  if (array == NULL) {
    return NULL;
  }
  for (int i = 0; i < utf16_length; i++) {
    array->Set(i, utf16_data_in[i]);
  }
  if (hash_code != 0) {
    string->SetHashCode(hash_code);
  } else {
    string->ComputeHashCode();
  }
  return string;
}

String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
  if (UNLIKELY(utf == nullptr)) {
    return nullptr;
  }
  size_t char_count = CountModifiedUtf8Chars(utf);
  return AllocFromModifiedUtf8(self, char_count, utf);
}

String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
                                      const char* utf8_data_in) {
  String* string = Alloc(self, utf16_length);
  if (UNLIKELY(string == nullptr)) {
    return nullptr;
  }
  uint16_t* utf16_data_out =
      const_cast<uint16_t*>(string->GetCharArray()->GetData());
  ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
  string->ComputeHashCode();
  return string;
}

String* String::Alloc(Thread* self, int32_t utf16_length) {
  SirtRef<CharArray> array(self, CharArray::Alloc(self, utf16_length));
  if (UNLIKELY(array.get() == nullptr)) {
    return nullptr;
  }
  return Alloc(self, array);
}

String* String::Alloc(Thread* self, const SirtRef<CharArray>& array) {
  // Hold reference in case AllocObject causes GC.
  String* string = down_cast<String*>(GetJavaLangString()->AllocObject(self));
  if (LIKELY(string != nullptr)) {
    string->SetArray(array.get());
    string->SetCount(array->GetLength());
  }
  return string;
}

bool String::Equals(const String* that) const {
  if (this == that) {
    // Quick reference equality test
    return true;
  } else if (that == NULL) {
    // Null isn't an instanceof anything
    return false;
  } else if (this->GetLength() != that->GetLength()) {
    // Quick length inequality test
    return false;
  } else {
    // Note: don't short circuit on hash code as we're presumably here as the
    // hash code was already equal
    for (int32_t i = 0; i < that->GetLength(); ++i) {
      if (this->CharAt(i) != that->CharAt(i)) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const uint16_t* that_chars, int32_t that_offset, int32_t that_length) const {
  if (this->GetLength() != that_length) {
    return false;
  } else {
    for (int32_t i = 0; i < that_length; ++i) {
      if (this->CharAt(i) != that_chars[that_offset + i]) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const char* modified_utf8) const {
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
    if (ch == '\0' || ch != CharAt(i)) {
      return false;
    }
  }
  return *modified_utf8 == '\0';
}

bool String::Equals(const StringPiece& modified_utf8) const {
  const char* p = modified_utf8.data();
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&p);
    if (ch != CharAt(i)) {
      return false;
    }
  }
  return true;
}

// Create a modified UTF-8 encoded std::string from a java/lang/String object.
std::string String::ToModifiedUtf8() const {
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  size_t byte_count = GetUtfLength();
  std::string result(byte_count, static_cast<char>(0));
  ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
  return result;
}

#ifdef HAVE__MEMCMP16
// "count" is in 16-bit units.
extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
#define MemCmp16 __memcmp16
#else
static uint32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
  for (size_t i = 0; i < count; i++) {
    if (s0[i] != s1[i]) {
      return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
    }
  }
  return 0;
}
#endif

int32_t String::CompareTo(String* rhs) const {
  // Quick test for comparison of a string with itself.
  const String* lhs = this;
  if (lhs == rhs) {
    return 0;
  }
  // TODO: is this still true?
  // The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
  // because the interpreter converts the characters to 32-bit integers
  // *without* sign extension before it subtracts them (which makes some
  // sense since "char" is unsigned).  So what we get is the result of
  // 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
  int lhsCount = lhs->GetLength();
  int rhsCount = rhs->GetLength();
  int countDiff = lhsCount - rhsCount;
  int minCount = (countDiff < 0) ? lhsCount : rhsCount;
  const uint16_t* lhsChars = lhs->GetCharArray()->GetData() + lhs->GetOffset();
  const uint16_t* rhsChars = rhs->GetCharArray()->GetData() + rhs->GetOffset();
  int otherRes = MemCmp16(lhsChars, rhsChars, minCount);
  if (otherRes != 0) {
    return otherRes;
  }
  return countDiff;
}

void String::VisitRoots(RootVisitor* visitor, void* arg) {
  if (java_lang_String_ != nullptr) {
    java_lang_String_ = down_cast<Class*>(visitor(java_lang_String_, arg));
  }
}

}  // namespace mirror
}  // namespace art
<commit_msg>am d7b5f474: am 5a2ced51: Merge "Use memcpy instead of Array::Set in mirror::String::AllocFromUtf16."<commit_after>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */

#include "string.h"

#include "array.h"
#include "class-inl.h"
#include "gc/accounting/card_table-inl.h"
#include "intern_table.h"
#include "object-inl.h"
#include "runtime.h"
#include "sirt_ref.h"
#include "thread.h"
#include "utf-inl.h"

namespace art {
namespace mirror {

const CharArray* String::GetCharArray() const {
  return GetFieldObject<const CharArray*>(ValueOffset(), false);
}

CharArray* String::GetCharArray() {
  return GetFieldObject<CharArray*>(ValueOffset(), false);
}

void String::ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
}

int32_t String::GetUtfLength() const {
  return CountUtf8Bytes(GetCharArray()->GetData() + GetOffset(), GetLength());
}

int32_t String::FastIndexOf(int32_t ch, int32_t start) const {
  int32_t count = GetLength();
  if (start < 0) {
    start = 0;
  } else if (start > count) {
    start = count;
  }
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  const uint16_t* p = chars + start;
  const uint16_t* end = chars + count;
  while (p < end) {
    if (*p++ == ch) {
      return (p - 1) - chars;
    }
  }
  return -1;
}

void String::SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  DCHECK(new_array != NULL);
  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array, false);
}

// TODO: get global references for these
Class* String::java_lang_String_ = NULL;

void String::SetClass(Class* java_lang_String) {
  CHECK(java_lang_String_ == NULL);
  CHECK(java_lang_String != NULL);
  java_lang_String_ = java_lang_String;
}

void String::ResetClass() {
  CHECK(java_lang_String_ != NULL);
  java_lang_String_ = NULL;
}

String* String::Intern() {
  return Runtime::Current()->GetInternTable()->InternWeak(this);
}

int32_t String::GetHashCode() {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  if (result == 0) {
    ComputeHashCode();
  }
  result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
  DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
          << ToModifiedUtf8() << " " << result;
  return result;
}

int32_t String::GetLength() const {
  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
  DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
  return result;
}

uint16_t String::CharAt(int32_t index) const {
  // TODO: do we need this? Equals is the only caller, and could
  // bounds check itself.
  DCHECK_GE(count_, 0);  // ensures the unsigned comparison is safe.
  if (UNLIKELY(static_cast<uint32_t>(index) >= static_cast<uint32_t>(count_))) {
    Thread* self = Thread::Current();
    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    self->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
                             "length=%i; index=%i", count_, index);
    return 0;
  }
  return GetCharArray()->Get(index + GetOffset());
}

String* String::AllocFromUtf16(Thread* self,
                               int32_t utf16_length,
                               const uint16_t* utf16_data_in,
                               int32_t hash_code) {
  CHECK(utf16_data_in != nullptr || utf16_length == 0);
  String* string = Alloc(self, utf16_length);
  if (UNLIKELY(string == nullptr)) {
    return nullptr;
  }
  CharArray* array = const_cast<CharArray*>(string->GetCharArray());
  if (UNLIKELY(array == nullptr)) {
    return nullptr;
  }
  memcpy(array->GetData(), utf16_data_in, utf16_length * sizeof(uint16_t));
  if (hash_code != 0) {
    DCHECK_EQ(hash_code, ComputeUtf16Hash(utf16_data_in, utf16_length));
    string->SetHashCode(hash_code);
  } else {
    string->ComputeHashCode();
  }
  return string;
}

String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
  if (UNLIKELY(utf == nullptr)) {
    return nullptr;
  }
  size_t char_count = CountModifiedUtf8Chars(utf);
  return AllocFromModifiedUtf8(self, char_count, utf);
}

String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
                                      const char* utf8_data_in) {
  String* string = Alloc(self, utf16_length);
  if (UNLIKELY(string == nullptr)) {
    return nullptr;
  }
  uint16_t* utf16_data_out =
      const_cast<uint16_t*>(string->GetCharArray()->GetData());
  ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
  string->ComputeHashCode();
  return string;
}

String* String::Alloc(Thread* self, int32_t utf16_length) {
  SirtRef<CharArray> array(self, CharArray::Alloc(self, utf16_length));
  if (UNLIKELY(array.get() == nullptr)) {
    return nullptr;
  }
  return Alloc(self, array);
}

String* String::Alloc(Thread* self, const SirtRef<CharArray>& array) {
  // Hold reference in case AllocObject causes GC.
  String* string = down_cast<String*>(GetJavaLangString()->AllocObject(self));
  if (LIKELY(string != nullptr)) {
    string->SetArray(array.get());
    string->SetCount(array->GetLength());
  }
  return string;
}

bool String::Equals(const String* that) const {
  if (this == that) {
    // Quick reference equality test
    return true;
  } else if (that == NULL) {
    // Null isn't an instanceof anything
    return false;
  } else if (this->GetLength() != that->GetLength()) {
    // Quick length inequality test
    return false;
  } else {
    // Note: don't short circuit on hash code as we're presumably here as the
    // hash code was already equal
    for (int32_t i = 0; i < that->GetLength(); ++i) {
      if (this->CharAt(i) != that->CharAt(i)) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const uint16_t* that_chars, int32_t that_offset, int32_t that_length) const {
  if (this->GetLength() != that_length) {
    return false;
  } else {
    for (int32_t i = 0; i < that_length; ++i) {
      if (this->CharAt(i) != that_chars[that_offset + i]) {
        return false;
      }
    }
    return true;
  }
}

bool String::Equals(const char* modified_utf8) const {
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
    if (ch == '\0' || ch != CharAt(i)) {
      return false;
    }
  }
  return *modified_utf8 == '\0';
}

bool String::Equals(const StringPiece& modified_utf8) const {
  const char* p = modified_utf8.data();
  for (int32_t i = 0; i < GetLength(); ++i) {
    uint16_t ch = GetUtf16FromUtf8(&p);
    if (ch != CharAt(i)) {
      return false;
    }
  }
  return true;
}

// Create a modified UTF-8 encoded std::string from a java/lang/String object.
std::string String::ToModifiedUtf8() const {
  const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
  size_t byte_count = GetUtfLength();
  std::string result(byte_count, static_cast<char>(0));
  ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
  return result;
}

#ifdef HAVE__MEMCMP16
// "count" is in 16-bit units.
extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
#define MemCmp16 __memcmp16
#else
static uint32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
  for (size_t i = 0; i < count; i++) {
    if (s0[i] != s1[i]) {
      return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
    }
  }
  return 0;
}
#endif

int32_t String::CompareTo(String* rhs) const {
  // Quick test for comparison of a string with itself.
  const String* lhs = this;
  if (lhs == rhs) {
    return 0;
  }
  // TODO: is this still true?
  // The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
  // because the interpreter converts the characters to 32-bit integers
  // *without* sign extension before it subtracts them (which makes some
  // sense since "char" is unsigned).  So what we get is the result of
  // 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
  int lhsCount = lhs->GetLength();
  int rhsCount = rhs->GetLength();
  int countDiff = lhsCount - rhsCount;
  int minCount = (countDiff < 0) ? lhsCount : rhsCount;
  const uint16_t* lhsChars = lhs->GetCharArray()->GetData() + lhs->GetOffset();
  const uint16_t* rhsChars = rhs->GetCharArray()->GetData() + rhs->GetOffset();
  int otherRes = MemCmp16(lhsChars, rhsChars, minCount);
  if (otherRes != 0) {
    return otherRes;
  }
  return countDiff;
}

void String::VisitRoots(RootVisitor* visitor, void* arg) {
  if (java_lang_String_ != nullptr) {
    java_lang_String_ = down_cast<Class*>(visitor(java_lang_String_, arg));
  }
}

}  // namespace mirror
}  // namespace art
<|endoftext|>


<commit_before>/// This source file contains tests, that are planned to be used with thread sanitizer or Valgrind.
<commit_msg>[Functional Testing] Multithreaded usage.<commit_after>///
/// This source file contains tests, that are planned to be used with thread sanitizer or Valgrind.
///

#include <blackhole/logger.hpp>
#include <blackhole/macro.hpp>
#include <blackhole/formatter/string.hpp>
#include <blackhole/sink/stream.hpp>

#include "../../global.hpp"

using namespace blackhole;

namespace {

static inline void run(logger_base_t& log, int) {
    for (int i = 0; i < 10000; ++i) {
        if (auto record = log.open_record()) {
            aux::logger::make_pusher(log, record, "le message");
        }
    }
}

} // namespace

TEST(SanitizeThread, Logger) {
    using aux::util::make_unique;

    typedef formatter::string_t                   formatter_type;
    typedef sink::stream_t                        sink_type;
    typedef frontend_t<formatter_type, sink_type> frontend_type;
    typedef logger_base_t                         logger_type;

    std::ostringstream stream;

    auto formatter = make_unique<formatter_type>("%(message)s %(...:[:])s");
    auto sink      = make_unique<sink_type>(stream);
    auto frontend  = make_unique<frontend_type>(std::move(formatter), std::move(sink));
    logger_type log;
    log.add_frontend(std::move(frontend));

    std::vector<std::thread> threads;

    for (int i = 0; i < 8; ++i) {
        threads.emplace_back(std::bind(&run, std::ref(log), i));
    }

    for (auto it = threads.begin(); it != threads.end(); ++it) {
        if (it->joinable()) {
            it->join();
        }
    }
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//  Copyright (c) 2011, John Haddon. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software 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 OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/ParameterisedInterface.h"

#include "Gaffer/ParameterisedHolder.h"
#include "Gaffer/CompoundParameterHandler.h"
#include "Gaffer/TypedPlug.h"
#include "Gaffer/NumericPlug.h"

using namespace Gaffer;

template<typename BaseType>
const IECore::RunTimeTyped::TypeDescription<ParameterisedHolder<BaseType> > ParameterisedHolder<BaseType>::g_typeDescription;

template<typename BaseType>
ParameterisedHolder<BaseType>::ParameterisedHolder( const std::string &name )
	:	BaseType( name ), m_parameterised( 0 ), m_parameterHandler( 0 )
{
	BaseType::addChild( new StringPlug( "__className" ) );
	BaseType::addChild( new IntPlug( "__classVersion", Plug::In, -1 ) );
	BaseType::addChild( new StringPlug( "__searchPathEnvVar" ) );
}

template<typename BaseType>
void ParameterisedHolder<BaseType>::setParameterised( IECore::RunTimeTypedPtr parameterised )
{
	IECore::ParameterisedInterface *interface = dynamic_cast<IECore::ParameterisedInterface *>( parameterised.get() );
	if( !interface )
	{
		throw IECore::Exception( "Not a ParameterisedInterface derived type." );
	}

	m_parameterised = parameterised;
	m_parameterHandler = new CompoundParameterHandler( interface->parameters(), this );
	m_parameterHandler->setPlugValue();
}

template<typename BaseType>
void ParameterisedHolder<BaseType>::setParameterised( const std::string &className, int classVersion, const std::string &searchPathEnvVar )
{
	/// \todo How do we load a class without introducing a python dependency into the main library?
	/// Make this function virtual and only implement it in the wrapper class?
	/// Give IECore::ClassLoader a C++ base class and implement it in python somehow?
	assert( 0 );
}

template<typename BaseType>
IECore::RunTimeTypedPtr ParameterisedHolder<BaseType>::getParameterised( std::string *className, int *classVersion, std::string *searchPathEnvVar ) const
{
	Node *node = const_cast<Node *>( static_cast<const Node *>( this ) );
	if( className )
	{
		*className = node->getChild<StringPlug>( "__className" )->getValue();
	}
	if( classVersion )
	{
		*classVersion = node->getChild<IntPlug>( "__classVersion" )->getValue();
	}
	if( searchPathEnvVar )
	{
		*searchPathEnvVar = node->getChild<StringPlug>( "__searchPathEnvVar" )->getValue();
	}
	return m_parameterised;
}

template<typename BaseType>
IECore::ParameterisedInterface *ParameterisedHolder<BaseType>::parameterisedInterface( std::string *className, int *classVersion, std::string *searchPathEnvVar )
{
	return dynamic_cast<IECore::ParameterisedInterface *>( getParameterised( className, classVersion, searchPathEnvVar ).get() );
}

template<typename BaseType>
CompoundParameterHandlerPtr ParameterisedHolder<BaseType>::parameterHandler()
{
	return m_parameterHandler;
}

template<typename BaseType>
ConstCompoundParameterHandlerPtr ParameterisedHolder<BaseType>::parameterHandler() const
{
	return m_parameterHandler;
}

template<typename BaseType>
void ParameterisedHolder<BaseType>::setParameterisedValues()
{
	if( m_parameterHandler )
	{
		m_parameterHandler->setParameterValue();
	}
}

//////////////////////////////////////////////////////////////////////////
// ParameterModificationContext
//////////////////////////////////////////////////////////////////////////

template<typename BaseType>
ParameterisedHolder<BaseType>::ParameterModificationContext::ParameterModificationContext( Ptr parameterisedHolder )
	:	m_parameterisedHolder( parameterisedHolder )
{
}

template<typename BaseType>
ParameterisedHolder<BaseType>::ParameterModificationContext::~ParameterModificationContext()
{
	if( IECore::ParameterisedInterface *interface = m_parameterisedHolder->parameterisedInterface() )
	{
		m_parameterisedHolder->m_parameterHandler = new CompoundParameterHandler( interface->parameters(), m_parameterisedHolder );
		m_parameterisedHolder->m_parameterHandler->setPlugValue();
	}
}

// specialisation

namespace Gaffer
{

IECORE_RUNTIMETYPED_DEFINETEMPLATESPECIALISATION( ParameterisedHolderNode, ParameterisedHolderNodeTypeId )

}

// explicit instantiation
template class ParameterisedHolder<Node>;
<commit_msg>Adding changing which should have been with earlier commit.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//  Copyright (c) 2011, John Haddon. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software 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 OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/ParameterisedInterface.h"

#include "Gaffer/ParameterisedHolder.h"
#include "Gaffer/CompoundParameterHandler.h"
#include "Gaffer/TypedPlug.h"
#include "Gaffer/NumericPlug.h"

using namespace Gaffer;

template<typename BaseType>
const IECore::RunTimeTyped::TypeDescription<ParameterisedHolder<BaseType> > ParameterisedHolder<BaseType>::g_typeDescription;

template<typename BaseType>
ParameterisedHolder<BaseType>::ParameterisedHolder( const std::string &name )
	:	BaseType( name ), m_parameterised( 0 ), m_parameterHandler( 0 )
{
	BaseType::addChild( new StringPlug( "__className" ) );
	BaseType::addChild( new IntPlug( "__classVersion", Plug::In, -1 ) );
	BaseType::addChild( new StringPlug( "__searchPathEnvVar" ) );
}

template<typename BaseType>
void ParameterisedHolder<BaseType>::setParameterised( IECore::RunTimeTypedPtr parameterised )
{
	IECore::ParameterisedInterface *interface = dynamic_cast<IECore::ParameterisedInterface *>( parameterised.get() );
	if( !interface )
	{
		throw IECore::Exception( "Not a ParameterisedInterface derived type." );
	}

	m_parameterised = parameterised;
	m_parameterHandler = new CompoundParameterHandler( interface->parameters() );
	m_parameterHandler->setupPlug( this );
	m_parameterHandler->setPlugValue();
}

template<typename BaseType>
void ParameterisedHolder<BaseType>::setParameterised( const std::string &className, int classVersion, const std::string &searchPathEnvVar )
{
	/// \todo How do we load a class without introducing a python dependency into the main library?
	/// Make this function virtual and only implement it in the wrapper class?
	/// Give IECore::ClassLoader a C++ base class and implement it in python somehow?
	assert( 0 );
}

template<typename BaseType>
IECore::RunTimeTypedPtr ParameterisedHolder<BaseType>::getParameterised( std::string *className, int *classVersion, std::string *searchPathEnvVar ) const
{
	Node *node = const_cast<Node *>( static_cast<const Node *>( this ) );
	if( className )
	{
		*className = node->getChild<StringPlug>( "__className" )->getValue();
	}
	if( classVersion )
	{
		*classVersion = node->getChild<IntPlug>( "__classVersion" )->getValue();
	}
	if( searchPathEnvVar )
	{
		*searchPathEnvVar = node->getChild<StringPlug>( "__searchPathEnvVar" )->getValue();
	}
	return m_parameterised;
}

template<typename BaseType>
IECore::ParameterisedInterface *ParameterisedHolder<BaseType>::parameterisedInterface( std::string *className, int *classVersion, std::string *searchPathEnvVar )
{
	return dynamic_cast<IECore::ParameterisedInterface *>( getParameterised( className, classVersion, searchPathEnvVar ).get() );
}

template<typename BaseType>
CompoundParameterHandlerPtr ParameterisedHolder<BaseType>::parameterHandler()
{
	return m_parameterHandler;
}

template<typename BaseType>
ConstCompoundParameterHandlerPtr ParameterisedHolder<BaseType>::parameterHandler() const
{
	return m_parameterHandler;
}

template<typename BaseType>
void ParameterisedHolder<BaseType>::setParameterisedValues()
{
	if( m_parameterHandler )
	{
		m_parameterHandler->setParameterValue();
	}
}

//////////////////////////////////////////////////////////////////////////
// ParameterModificationContext
//////////////////////////////////////////////////////////////////////////

template<typename BaseType>
ParameterisedHolder<BaseType>::ParameterModificationContext::ParameterModificationContext( Ptr parameterisedHolder )
	:	m_parameterisedHolder( parameterisedHolder )
{
}

template<typename BaseType>
ParameterisedHolder<BaseType>::ParameterModificationContext::~ParameterModificationContext()
{
	if( m_parameterisedHolder->m_parameterHandler )
	{
		m_parameterisedHolder->m_parameterHandler->setupPlug( m_parameterisedHolder );
		m_parameterisedHolder->m_parameterHandler->setPlugValue();
	}
}

// specialisation

namespace Gaffer
{

IECORE_RUNTIMETYPED_DEFINETEMPLATESPECIALISATION( ParameterisedHolderNode, ParameterisedHolderNodeTypeId )

}

// explicit instantiation
template class ParameterisedHolder<Node>;
<|endoftext|>


<commit_before>#include <chrono>
#include <iostream>
#include <sstream>

using namespace std;

asm(".LC3:");
asm("  .long 1065353216");
asm(".LC4:");
asm("  .long 3212836864");

float evaluateClang(float a, float b) {
  asm("subss xmm0, xmm1");
  asm("movss xmm1, dword ptr [rip + .LC3]");
  asm("addss xmm1, xmm0");
  asm("mulss xmm1, xmm0");
  asm("addss xmm0, dword ptr [rip + .LC4]");
  asm("mulss xmm0, xmm1");
}

float evaluateGCC(float a, float b) {
  asm("subss xmm0, xmm1");
  asm("movss xmm2, dword ptr [rip + .LC3]");
  asm("movaps xmm1, xmm0");
  asm("addss xmm1, xmm2");
  asm("mulss xmm1, xmm0");
  asm("subss xmm0, xmm2");
  asm("mulss xmm0, xmm1");
}

int main() {
  auto start = std::chrono::steady_clock::now();
  for (int j = 0; j < 1000; j++) {
    for (int i = 0; i < 65536; i++) {
      evaluateClang(4.0f, 9.0f);
    }
  }
  auto now = std::chrono::steady_clock::now();
  std::chrono::duration<double, std::nano> ns = now - start;
  cout << ns.count() << " ns" << '\n';

  start = std::chrono::steady_clock::now();
  for (int j = 0; j < 1000; j++) {
    for (int i = 0; i < 65536; i++) {
      evaluateGCC(4.0f, 9.0f);
    }
  }
  now = std::chrono::steady_clock::now();
  ns = now - start;
  cout << ns.count() << " ns" << '\n';
}
<commit_msg>Should use a single asm statement per function<commit_after>#include <chrono>
#include <iostream>
#include <sstream>

using namespace std;

asm(".LC3:\n"
    "  .long 1065353216");
asm(".LC4:\n"
    "  .long 3212836864");

float evaluateClang(float a, float b) {
  asm("subss xmm0, xmm1\n"
      "movss xmm1, dword ptr [rip + .LC3]\n"
      "addss xmm1, xmm0\n"
      "mulss xmm1, xmm0\n"
      "addss xmm0, dword ptr [rip + .LC4]\n"
      "mulss xmm0, xmm1");
}

float evaluateGCC(float a, float b) {
  asm("subss xmm0, xmm1\n"
      "movss xmm2, dword ptr [rip + .LC3]\n"
      "movaps xmm1, xmm0\n"
      "addss xmm1, xmm2\n"
      "mulss xmm1, xmm0\n"
      "subss xmm0, xmm2\n"
      "mulss xmm0, xmm1");
}

int main() {
  auto start = std::chrono::steady_clock::now();
  for (int j = 0; j < 1000; j++) {
    for (int i = 0; i < 65536; i++) {
      evaluateClang(4.0f, 9.0f);
    }
  }
  auto now = std::chrono::steady_clock::now();
  std::chrono::duration<double, std::nano> ns = now - start;
  cout << ns.count() << " ns" << '\n';

  start = std::chrono::steady_clock::now();
  for (int j = 0; j < 1000; j++) {
    for (int i = 0; i < 65536; i++) {
      evaluateGCC(4.0f, 9.0f);
    }
  }
  now = std::chrono::steady_clock::now();
  ns = now - start;
  cout << ns.count() << " ns" << '\n';
}
<|endoftext|>


<commit_before>/* Copyright 2016 Stanford University, NVIDIA Corporation
 *
 * 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.
 */

// Realm logging infrastructure

#include "logging.h"

#ifdef SHARED_LOWLEVEL
#define gasnet_mynode() 0
#define gasnet_nodes() 1
#else
#include "activemsg.h"
#endif

#include "cmdline.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>

#include <set>
#include <map>

namespace Realm {

  // abstract class for an output stream
  class LoggerOutputStream {
  public:
    LoggerOutputStream(void) {}
    virtual ~LoggerOutputStream(void) {}

    virtual void write(const char *buffer, size_t len) = 0;
    virtual void flush(void) = 0;
  };

  class LoggerFileStream : public LoggerOutputStream {
  public:
    LoggerFileStream(FILE *_f, bool _close_file)
      : f(_f), close_file(_close_file)
    {}

    virtual ~LoggerFileStream(void)
    {
      if(close_file)
	fclose(f);
    }

    virtual void write(const char *buffer, size_t len)
    {
#ifndef NDEBUG
      size_t amt =
#endif
	fwrite(buffer, 1, len, f);
      assert(amt == len);
    }

    virtual void flush(void)
    {
      fflush(f);
    }

  protected:
    FILE *f;
    bool close_file;
  };

  // use a pthread mutex to prevent simultaneous writes to a stream
  template <typename T>
  class LoggerStreamSerialized : public LoggerOutputStream {
  public:
    LoggerStreamSerialized(T *_stream, bool _delete_inner)
      : stream(_stream), delete_inner(_delete_inner)
    {
#ifndef NDEBUG
      int ret =
#endif
	pthread_mutex_init(&mutex, 0);
      assert(ret == 0);
    }

    virtual ~LoggerStreamSerialized(void)
    {
#ifndef NDEBUG
      int ret =
#endif
	pthread_mutex_destroy(&mutex);
      assert(ret == 0);
      if(delete_inner)
	delete stream;
    }

    virtual void write(const char *buffer, size_t len)
    {
#ifndef NDEBUG
      int ret;
      ret =
#endif
	pthread_mutex_lock(&mutex);
      assert(ret == 0);
      stream->write(buffer, len);
#ifndef NDEBUG
      ret =
#endif
	pthread_mutex_unlock(&mutex);
      assert(ret == 0);
    }

    virtual void flush(void)
    {
#ifndef NDEBUG
      int ret;
      ret =
#endif
	pthread_mutex_lock(&mutex);
      assert(ret == 0);
      stream->flush();
#ifndef NDEBUG
      ret =
#endif
	pthread_mutex_unlock(&mutex);
      assert(ret == 0);
    }

  protected:
    LoggerOutputStream *stream;
    bool delete_inner;
    pthread_mutex_t mutex;
  };

  class LoggerConfig {
  protected:
    LoggerConfig(void);
    ~LoggerConfig(void);

  public:
    static LoggerConfig *get_config(void);

    static void flush_all_streams(void);

    void read_command_line(std::vector<std::string>& cmdline);

    // either configures a logger right away or remembers it to config once
    //   we know the desired settings
    void configure(Logger *logger);

  protected:
    bool parse_level_argument(const std::string& s);

    bool cmdline_read;
    Logger::LoggingLevel default_level;
    std::map<std::string, Logger::LoggingLevel> category_levels;
    std::string cats_enabled;
    std::set<Logger *> pending_configs;
    LoggerOutputStream *stream;
  };

  LoggerConfig::LoggerConfig(void)
    : cmdline_read(false), default_level(Logger::LEVEL_PRINT), stream(0)
  {}

  LoggerConfig::~LoggerConfig(void)
  {
    delete stream;
  }

  /*static*/ LoggerConfig *LoggerConfig::get_config(void)
  {
    static LoggerConfig cfg;
    return &cfg;
  }

  /*static*/ void LoggerConfig::flush_all_streams(void)
  {
    LoggerConfig *cfg = get_config();
    if(cfg->stream)
      cfg->stream->flush();
  }

  bool LoggerConfig::parse_level_argument(const std::string& s)
  {
    const char *p1 = s.c_str();

    while(true) {
      // skip commas
      while(*p1 == ',') p1++;
      if(!*p1) break;

      // numbers may be preceeded by name= to specify a per-category level
      std::string catname;
      if(!isdigit(*p1)) {
	const char *p2 = p1;
	while(*p2 != '=') {
	  if(!*p2) {
	    fprintf(stderr, "ERROR: category name in -level must be followed by =\n");
	    return false;
	  }
	  p2++;
	}
	catname.assign(p1, p2 - p1);
	p1 = p2 + 1;
      }

      // levels are small integers
      if(isdigit(*p1)) {
	char *p2;
	errno = 0; // no leftover errors from elsewhere
	long v = strtol(p1, &p2, 10);

	if((errno == 0) && ((*p2 == 0) || (*p2) == ',') &&
	   (v >= 0) && (v <= Logger::LEVEL_NONE)) {
	  if(catname.empty())
	    default_level = (Logger::LoggingLevel)v;
	  else
	    category_levels[catname] = (Logger::LoggingLevel)v;

	  p1 = p2;
	  continue;
	}
      }

      fprintf(stderr, "ERROR: logger level malformed or out of range: '%s'\n", p1);
      return false;
    }

    return true;
  }

  void LoggerConfig::read_command_line(std::vector<std::string>& cmdline)
  {
    std::string logname;

    bool ok = CommandLineParser()
      .add_option_string("-cat", cats_enabled)
      .add_option_string("-logfile", logname)
      .add_option_method("-level", this, &LoggerConfig::parse_level_argument)
      .parse_command_line(cmdline);

    if(!ok) {
      fprintf(stderr, "couldn't parse logger config options\n");
      exit(1);
    }

    // lots of choices for log output
    if(logname.empty() || (logname == "stdout")) {
      stream = new LoggerStreamSerialized<LoggerFileStream>(new LoggerFileStream(stdout, false),
							    true);
    } else if(logname == "stderr") {
      stream = new LoggerStreamSerialized<LoggerFileStream>(new LoggerFileStream(stderr, false),
							    true);
    } else {
      // we're going to open a file, but key off a + for appending and
      //  look for a % for node number insertion
      bool append = false;
      size_t start = 0;

      if(logname[0] == '+') {
	append = true;
	start++;
      }

      FILE *f = 0;
      size_t pct = logname.find_first_of('%', start);
      if(pct == std::string::npos) {
	// no node number - everybody uses the same file
	if(gasnet_nodes() > 1) {
	  if(!append) {
	    if(gasnet_mynode() == 1)
	      fprintf(stderr, "WARNING: all ranks are logging to the same output file - appending is forced and output may be jumbled\n");
	    append = true;
	  }
	}
	const char *fn = logname.c_str() + start;
	f = fopen(fn, append ? "a" : "w");
	if(!f) {
	  fprintf(stderr, "could not open log file '%s': %s\n", fn, strerror(errno));
	  exit(1);
	}
      } else {
	// replace % with node number
	char filename[256];
	sprintf(filename, "%.*s%d%s",
		(int)(pct - start), logname.c_str() + start, gasnet_mynode(), logname.c_str() + pct + 1);

	f = fopen(filename, append ? "a" : "w");
	if(!f) {
	  fprintf(stderr, "could not open log file '%s': %s\n", filename, strerror(errno));
	  exit(1);
	}
      }
      // TODO: consider buffering in some cases?
      setbuf(f, 0); // disable output buffering
      stream = new LoggerStreamSerialized<LoggerFileStream>(new LoggerFileStream(f, true),
							    true);
    }

    atexit(LoggerConfig::flush_all_streams);

    cmdline_read = true;
    if(!pending_configs.empty()) {
      for(std::set<Logger *>::iterator it = pending_configs.begin();
	  it != pending_configs.end();
	  it++)
	configure(*it);
      pending_configs.clear();
    }
  }

  void LoggerConfig::configure(Logger *logger)
  {
    // if we haven't read the command line yet, remember this for later
    if(!cmdline_read) {
      pending_configs.insert(logger);
      return;
    }

    // see if this logger is one of the categories we want
    if(!cats_enabled.empty()) {
      bool found = false;
      const char *p = cats_enabled.c_str();
      int l = logger->get_name().length();
      const char *n = logger->get_name().c_str();
      while(*p) {
	if(((p[l] == '\0') || (p[l] == ',')) && !strncmp(p, n, l)) {
	  found = true;
	  break;
	}
	// skip to after next comma
	while(*p && (*p != ',')) p++;
	while(*p && (*p == ',')) p++;
      }
      if(!found) {
	//printf("'%s' not in '%s'\n", n, cats_enabled);
	return;
      }
    }

    // see if the level for this category has been customized
    Logger::LoggingLevel level = default_level;
    std::map<std::string, Logger::LoggingLevel>::const_iterator it = category_levels.find(logger->get_name());
    if(it != category_levels.end())
      level = it->second;

    // give this logger a copy of the global stream
    logger->add_stream(stream, level,
		       false,  /* don't delete */
		       false); /* don't flush each write */
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class Logger

  Logger::Logger(const std::string& _name)
    : name(_name), log_level(LEVEL_NONE)
  {
    LoggerConfig::get_config()->configure(this);
  }

  Logger::~Logger(void)
  {
    // go through our streams and delete any we're supposed to
    for(std::vector<LogStream>::iterator it = streams.begin();
	it != streams.end();
	it++)
      if(it->delete_when_done)
	delete it->s;

    streams.clear();
  }

  /*static*/ void Logger::configure_from_cmdline(std::vector<std::string>& cmdline)
  {
    LoggerConfig::get_config()->read_command_line(cmdline);
  }

  void Logger::log_msg(LoggingLevel level, const std::string& msg)
  {
    // no logging of empty messages
    if(msg.length() == 0)
      return;

    // build message string, including prefix
    static const int MAXLEN = 4096;
    char buffer[MAXLEN];
    int len = snprintf(buffer, MAXLEN - 2, "[%d - %lx] {%d}{%s}: ",
		       gasnet_mynode(), (unsigned long)pthread_self(),
		       level, name.c_str());
    int amt = msg.length();
    // Unusual case, but handle it
    if((len + amt) >= MAXLEN)
    {
      // If this is an error or a warning, print out the
      // whole message no matter what
      if ((level == LEVEL_FATAL) ||
          (level == LEVEL_ERROR) || (level == LEVEL_WARNING))
      {
        const size_t full_len = len + amt + 2;
        char *full_buffer = (char*)malloc(full_len);
        memcpy(full_buffer, buffer, len);
        memcpy(full_buffer + len, msg.data(), amt);
        full_buffer[len+amt] = '\n';
        full_buffer[len+amt+1] = 0;
        // go through all the streams
        for(std::vector<LogStream>::iterator it = streams.begin();
            it != streams.end();
            it++) {
          if(level < it->min_level)
            continue;

          it->s->write(full_buffer, full_len);

          if(it->flush_each_write)
            it->s->flush();
        }
        free(full_buffer);
        return;
      }
      amt = MAXLEN - 2 - len;
    }
    memcpy(buffer + len, msg.data(), amt);
    len += amt;
    buffer[len++] = '\n';
    buffer[len] = 0;

    // go through all the streams
    for(std::vector<LogStream>::iterator it = streams.begin();
	it != streams.end();
	it++) {
      if(level < it->min_level)
	continue;

      it->s->write(buffer, len);

      if(it->flush_each_write)
	it->s->flush();
    }
  }

  void Logger::add_stream(LoggerOutputStream *s, LoggingLevel min_level,
			  bool delete_when_done, bool flush_each_write)
  {
    LogStream ls;
    ls.s = s;
    ls.min_level = min_level;
    ls.delete_when_done = delete_when_done;
    ls.flush_each_write = flush_each_write;
    streams.push_back(ls);

    // update our logging level if needed
    if(log_level > min_level)
      log_level = min_level;
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class LoggerMessage

  LoggerMessage& LoggerMessage::vprintf(const char *fmt, va_list args)
  {
    if(active) {
      char msg[256];
      vsnprintf(msg, 256, fmt, args);
      (*oss) << msg;
    }
    return *this;
  }

}; // namespace Realm
<commit_msg>realm: Fix maximum logging message size.<commit_after>/* Copyright 2016 Stanford University, NVIDIA Corporation
 *
 * 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.
 */

// Realm logging infrastructure

#include "logging.h"

#ifdef SHARED_LOWLEVEL
#define gasnet_mynode() 0
#define gasnet_nodes() 1
#else
#include "activemsg.h"
#endif

#include "cmdline.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>

#include <set>
#include <map>

namespace Realm {

  // abstract class for an output stream
  class LoggerOutputStream {
  public:
    LoggerOutputStream(void) {}
    virtual ~LoggerOutputStream(void) {}

    virtual void write(const char *buffer, size_t len) = 0;
    virtual void flush(void) = 0;
  };

  class LoggerFileStream : public LoggerOutputStream {
  public:
    LoggerFileStream(FILE *_f, bool _close_file)
      : f(_f), close_file(_close_file)
    {}

    virtual ~LoggerFileStream(void)
    {
      if(close_file)
	fclose(f);
    }

    virtual void write(const char *buffer, size_t len)
    {
#ifndef NDEBUG
      size_t amt =
#endif
	fwrite(buffer, 1, len, f);
      assert(amt == len);
    }

    virtual void flush(void)
    {
      fflush(f);
    }

  protected:
    FILE *f;
    bool close_file;
  };

  // use a pthread mutex to prevent simultaneous writes to a stream
  template <typename T>
  class LoggerStreamSerialized : public LoggerOutputStream {
  public:
    LoggerStreamSerialized(T *_stream, bool _delete_inner)
      : stream(_stream), delete_inner(_delete_inner)
    {
#ifndef NDEBUG
      int ret =
#endif
	pthread_mutex_init(&mutex, 0);
      assert(ret == 0);
    }

    virtual ~LoggerStreamSerialized(void)
    {
#ifndef NDEBUG
      int ret =
#endif
	pthread_mutex_destroy(&mutex);
      assert(ret == 0);
      if(delete_inner)
	delete stream;
    }

    virtual void write(const char *buffer, size_t len)
    {
#ifndef NDEBUG
      int ret;
      ret =
#endif
	pthread_mutex_lock(&mutex);
      assert(ret == 0);
      stream->write(buffer, len);
#ifndef NDEBUG
      ret =
#endif
	pthread_mutex_unlock(&mutex);
      assert(ret == 0);
    }

    virtual void flush(void)
    {
#ifndef NDEBUG
      int ret;
      ret =
#endif
	pthread_mutex_lock(&mutex);
      assert(ret == 0);
      stream->flush();
#ifndef NDEBUG
      ret =
#endif
	pthread_mutex_unlock(&mutex);
      assert(ret == 0);
    }

  protected:
    LoggerOutputStream *stream;
    bool delete_inner;
    pthread_mutex_t mutex;
  };

  class LoggerConfig {
  protected:
    LoggerConfig(void);
    ~LoggerConfig(void);

  public:
    static LoggerConfig *get_config(void);

    static void flush_all_streams(void);

    void read_command_line(std::vector<std::string>& cmdline);

    // either configures a logger right away or remembers it to config once
    //   we know the desired settings
    void configure(Logger *logger);

  protected:
    bool parse_level_argument(const std::string& s);

    bool cmdline_read;
    Logger::LoggingLevel default_level;
    std::map<std::string, Logger::LoggingLevel> category_levels;
    std::string cats_enabled;
    std::set<Logger *> pending_configs;
    LoggerOutputStream *stream;
  };

  LoggerConfig::LoggerConfig(void)
    : cmdline_read(false), default_level(Logger::LEVEL_PRINT), stream(0)
  {}

  LoggerConfig::~LoggerConfig(void)
  {
    delete stream;
  }

  /*static*/ LoggerConfig *LoggerConfig::get_config(void)
  {
    static LoggerConfig cfg;
    return &cfg;
  }

  /*static*/ void LoggerConfig::flush_all_streams(void)
  {
    LoggerConfig *cfg = get_config();
    if(cfg->stream)
      cfg->stream->flush();
  }

  bool LoggerConfig::parse_level_argument(const std::string& s)
  {
    const char *p1 = s.c_str();

    while(true) {
      // skip commas
      while(*p1 == ',') p1++;
      if(!*p1) break;

      // numbers may be preceeded by name= to specify a per-category level
      std::string catname;
      if(!isdigit(*p1)) {
	const char *p2 = p1;
	while(*p2 != '=') {
	  if(!*p2) {
	    fprintf(stderr, "ERROR: category name in -level must be followed by =\n");
	    return false;
	  }
	  p2++;
	}
	catname.assign(p1, p2 - p1);
	p1 = p2 + 1;
      }

      // levels are small integers
      if(isdigit(*p1)) {
	char *p2;
	errno = 0; // no leftover errors from elsewhere
	long v = strtol(p1, &p2, 10);

	if((errno == 0) && ((*p2 == 0) || (*p2) == ',') &&
	   (v >= 0) && (v <= Logger::LEVEL_NONE)) {
	  if(catname.empty())
	    default_level = (Logger::LoggingLevel)v;
	  else
	    category_levels[catname] = (Logger::LoggingLevel)v;

	  p1 = p2;
	  continue;
	}
      }

      fprintf(stderr, "ERROR: logger level malformed or out of range: '%s'\n", p1);
      return false;
    }

    return true;
  }

  void LoggerConfig::read_command_line(std::vector<std::string>& cmdline)
  {
    std::string logname;

    bool ok = CommandLineParser()
      .add_option_string("-cat", cats_enabled)
      .add_option_string("-logfile", logname)
      .add_option_method("-level", this, &LoggerConfig::parse_level_argument)
      .parse_command_line(cmdline);

    if(!ok) {
      fprintf(stderr, "couldn't parse logger config options\n");
      exit(1);
    }

    // lots of choices for log output
    if(logname.empty() || (logname == "stdout")) {
      stream = new LoggerStreamSerialized<LoggerFileStream>(new LoggerFileStream(stdout, false),
							    true);
    } else if(logname == "stderr") {
      stream = new LoggerStreamSerialized<LoggerFileStream>(new LoggerFileStream(stderr, false),
							    true);
    } else {
      // we're going to open a file, but key off a + for appending and
      //  look for a % for node number insertion
      bool append = false;
      size_t start = 0;

      if(logname[0] == '+') {
	append = true;
	start++;
      }

      FILE *f = 0;
      size_t pct = logname.find_first_of('%', start);
      if(pct == std::string::npos) {
	// no node number - everybody uses the same file
	if(gasnet_nodes() > 1) {
	  if(!append) {
	    if(gasnet_mynode() == 1)
	      fprintf(stderr, "WARNING: all ranks are logging to the same output file - appending is forced and output may be jumbled\n");
	    append = true;
	  }
	}
	const char *fn = logname.c_str() + start;
	f = fopen(fn, append ? "a" : "w");
	if(!f) {
	  fprintf(stderr, "could not open log file '%s': %s\n", fn, strerror(errno));
	  exit(1);
	}
      } else {
	// replace % with node number
	char filename[256];
	sprintf(filename, "%.*s%d%s",
		(int)(pct - start), logname.c_str() + start, gasnet_mynode(), logname.c_str() + pct + 1);

	f = fopen(filename, append ? "a" : "w");
	if(!f) {
	  fprintf(stderr, "could not open log file '%s': %s\n", filename, strerror(errno));
	  exit(1);
	}
      }
      // TODO: consider buffering in some cases?
      setbuf(f, 0); // disable output buffering
      stream = new LoggerStreamSerialized<LoggerFileStream>(new LoggerFileStream(f, true),
							    true);
    }

    atexit(LoggerConfig::flush_all_streams);

    cmdline_read = true;
    if(!pending_configs.empty()) {
      for(std::set<Logger *>::iterator it = pending_configs.begin();
	  it != pending_configs.end();
	  it++)
	configure(*it);
      pending_configs.clear();
    }
  }

  void LoggerConfig::configure(Logger *logger)
  {
    // if we haven't read the command line yet, remember this for later
    if(!cmdline_read) {
      pending_configs.insert(logger);
      return;
    }

    // see if this logger is one of the categories we want
    if(!cats_enabled.empty()) {
      bool found = false;
      const char *p = cats_enabled.c_str();
      int l = logger->get_name().length();
      const char *n = logger->get_name().c_str();
      while(*p) {
	if(((p[l] == '\0') || (p[l] == ',')) && !strncmp(p, n, l)) {
	  found = true;
	  break;
	}
	// skip to after next comma
	while(*p && (*p != ',')) p++;
	while(*p && (*p == ',')) p++;
      }
      if(!found) {
	//printf("'%s' not in '%s'\n", n, cats_enabled);
	return;
      }
    }

    // see if the level for this category has been customized
    Logger::LoggingLevel level = default_level;
    std::map<std::string, Logger::LoggingLevel>::const_iterator it = category_levels.find(logger->get_name());
    if(it != category_levels.end())
      level = it->second;

    // give this logger a copy of the global stream
    logger->add_stream(stream, level,
		       false,  /* don't delete */
		       false); /* don't flush each write */
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class Logger

  Logger::Logger(const std::string& _name)
    : name(_name), log_level(LEVEL_NONE)
  {
    LoggerConfig::get_config()->configure(this);
  }

  Logger::~Logger(void)
  {
    // go through our streams and delete any we're supposed to
    for(std::vector<LogStream>::iterator it = streams.begin();
	it != streams.end();
	it++)
      if(it->delete_when_done)
	delete it->s;

    streams.clear();
  }

  /*static*/ void Logger::configure_from_cmdline(std::vector<std::string>& cmdline)
  {
    LoggerConfig::get_config()->read_command_line(cmdline);
  }

  void Logger::log_msg(LoggingLevel level, const std::string& msg)
  {
    // no logging of empty messages
    if(msg.length() == 0)
      return;

    // build message string, including prefix
    static const int MAXLEN = 4096;
    char buffer[MAXLEN];
    int len = snprintf(buffer, MAXLEN - 2, "[%d - %lx] {%d}{%s}: ",
		       gasnet_mynode(), (unsigned long)pthread_self(),
		       level, name.c_str());
    int amt = msg.length();
    // Unusual case, but handle it
    if((len + amt) >= MAXLEN)
    {
      // If this is an error or a warning, print out the
      // whole message no matter what
      if ((level == LEVEL_FATAL) ||
          (level == LEVEL_ERROR) || (level == LEVEL_WARNING))
      {
        const size_t full_len = len + amt + 2;
        char *full_buffer = (char*)malloc(full_len);
        memcpy(full_buffer, buffer, len);
        memcpy(full_buffer + len, msg.data(), amt);
        full_buffer[len+amt] = '\n';
        full_buffer[len+amt+1] = 0;
        // go through all the streams
        for(std::vector<LogStream>::iterator it = streams.begin();
            it != streams.end();
            it++) {
          if(level < it->min_level)
            continue;

          it->s->write(full_buffer, full_len);

          if(it->flush_each_write)
            it->s->flush();
        }
        free(full_buffer);
        return;
      }
      amt = MAXLEN - 2 - len;
    }
    memcpy(buffer + len, msg.data(), amt);
    len += amt;
    buffer[len++] = '\n';
    buffer[len] = 0;

    // go through all the streams
    for(std::vector<LogStream>::iterator it = streams.begin();
	it != streams.end();
	it++) {
      if(level < it->min_level)
	continue;

      it->s->write(buffer, len);

      if(it->flush_each_write)
	it->s->flush();
    }
  }

  void Logger::add_stream(LoggerOutputStream *s, LoggingLevel min_level,
			  bool delete_when_done, bool flush_each_write)
  {
    LogStream ls;
    ls.s = s;
    ls.min_level = min_level;
    ls.delete_when_done = delete_when_done;
    ls.flush_each_write = flush_each_write;
    streams.push_back(ls);

    // update our logging level if needed
    if(log_level > min_level)
      log_level = min_level;
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class LoggerMessage

  LoggerMessage& LoggerMessage::vprintf(const char *fmt, va_list args)
  {
    if(active) {
      static const int MAXLEN = 4096;
      char msg[MAXLEN];
      vsnprintf(msg, MAXLEN, fmt, args);
      (*oss) << msg;
    }
    return *this;
  }

}; // namespace Realm
<|endoftext|>


<commit_before>/*//////////////////////////////////////////////////////////////////
////       SKIRT -- an advanced radiative transfer code         ////
////       © Astronomical Observatory, Ghent University         ////
///////////////////////////////////////////////////////////////// */

#include <cmath>
#include "ElectronDustMix.hpp"
#include "Units.hpp"

using namespace std;

//////////////////////////////////////////////////////////////////////

ElectronDustMix::ElectronDustMix()
{
}

//////////////////////////////////////////////////////////////////////

void ElectronDustMix::setupSelfBefore()
{
    DustMix::setupSelfBefore();

    // get the simulation's wavelength grid
    const Array& lambdav = simlambdav();
    int Nlambda = lambdav.size();

    // arbitrarily set the resolution of the theta grid
    int Ntheta = 181;

    // create temporary vectors and tables with the appropriate size
    Array sigmaabsv(Nlambda), sigmascav(Nlambda), asymmparv(Nlambda);
    Table<2> S11vv(Nlambda,Ntheta), S12vv(Nlambda,Ntheta), S33vv(Nlambda,Ntheta), S34vv(Nlambda,Ntheta);

    // set the constant scattering cross section, and leave absorption at zero
    // (leave asymmpar at zero as well - it is not used since we support polarization)
    sigmascav = Units::sigmaThomson();

    // calculate the wavelength-independent Sxx values in the Mueller matrix according to
    // equation (C.7) of Wolf 2003 (Computer Physics Communications, 150, 99–115)
    double dt = M_PI/(Ntheta-1);
    for (int t=0; t<Ntheta; t++)
    {
        double theta = t * dt;
        double costheta = cos(theta);
        double S11 = 0.5*(costheta*costheta+1.);
        double S12 = 0.5*(costheta*costheta-1.);
        double S33 = costheta;
        for (int ell=0; ell<Nlambda; ell++)
        {
            S11vv(ell,t) = S11;
            S12vv(ell,t) = S12;
            S33vv(ell,t) = S33;
        }
    }

    // calculate the weight of an electron per hydrogen atom
    double mu = Units::masselectron()/(Units::masselectron()+Units::massproton());

    // add a single dust population with these properties
    addpopulation(mu, sigmaabsv, sigmascav, asymmparv);
    addpolarization(S11vv, S12vv, S33vv, S34vv);
}

//////////////////////////////////////////////////////////////////////
<commit_msg>fix mu for electron dust mix<commit_after>/*//////////////////////////////////////////////////////////////////
////       SKIRT -- an advanced radiative transfer code         ////
////       © Astronomical Observatory, Ghent University         ////
///////////////////////////////////////////////////////////////// */

#include <cmath>
#include "ElectronDustMix.hpp"
#include "Units.hpp"

using namespace std;

//////////////////////////////////////////////////////////////////////

ElectronDustMix::ElectronDustMix()
{
}

//////////////////////////////////////////////////////////////////////

void ElectronDustMix::setupSelfBefore()
{
    DustMix::setupSelfBefore();

    // get the simulation's wavelength grid
    const Array& lambdav = simlambdav();
    int Nlambda = lambdav.size();

    // arbitrarily set the resolution of the theta grid
    int Ntheta = 181;

    // create temporary vectors and tables with the appropriate size
    Array sigmaabsv(Nlambda), sigmascav(Nlambda), asymmparv(Nlambda);
    Table<2> S11vv(Nlambda,Ntheta), S12vv(Nlambda,Ntheta), S33vv(Nlambda,Ntheta), S34vv(Nlambda,Ntheta);

    // set the constant scattering cross section, and leave absorption at zero
    // (leave asymmpar at zero as well - it is not used since we support polarization)
    sigmascav = Units::sigmaThomson();

    // calculate the wavelength-independent Sxx values in the Mueller matrix according to
    // equation (C.7) of Wolf 2003 (Computer Physics Communications, 150, 99–115)
    double dt = M_PI/(Ntheta-1);
    for (int t=0; t<Ntheta; t++)
    {
        double theta = t * dt;
        double costheta = cos(theta);
        double S11 = 0.5*(costheta*costheta+1.);
        double S12 = 0.5*(costheta*costheta-1.);
        double S33 = costheta;
        for (int ell=0; ell<Nlambda; ell++)
        {
            S11vv(ell,t) = S11;
            S12vv(ell,t) = S12;
            S33vv(ell,t) = S33;
        }
    }

    // add a single dust population with these properties
    addpopulation(Units::masselectron(), sigmaabsv, sigmascav, asymmparv);
    addpolarization(S11vv, S12vv, S33vv, S34vv);
}

//////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include "AliAODExtension.h"

//-------------------------------------------------------------------------
//     Support class for AOD extensions. This is created by the user analysis
//     that requires a separate file for some AOD branches. The name of the
//     AliAODExtension object is the file name where the AOD branches will be
//     stored.
//-------------------------------------------------------------------------

#include "AliAODBranchReplicator.h"
#include "AliAODEvent.h"
#include "AliCodeTimer.h"
#include "AliLog.h"
#include "Riostream.h"
#include "TDirectory.h"
#include "TFile.h"
#include "TList.h"
#include "TMap.h"
#include "TMap.h"
#include "TObjString.h"
#include "TROOT.h"
#include "TString.h"
#include "TTree.h"

using std::endl;
using std::cout;
ClassImp(AliAODExtension)

//______________________________________________________________________________
AliAODExtension::AliAODExtension() : TNamed(),
fAODEvent(0), fTreeE(0), fFileE(0), fNtotal(0), fNpassed(0),
fSelected(kFALSE), fRepFiMap(0x0), fRepFiList(0x0), fEnableReferences(kTRUE), fObjectList(0x0)
{
  // default ctor
}

//______________________________________________________________________________
AliAODExtension::AliAODExtension(const char* name, const char* title, Bool_t isfilter)
:TNamed(name,title),
fAODEvent(0),
fTreeE(0),
fFileE(0),
fNtotal(0),
fNpassed(0),
fSelected(kFALSE),
fRepFiMap(0x0),
fRepFiList(0x0),
fEnableReferences(kTRUE),
fObjectList(0x0)
{
  // Constructor.
  if (isfilter) {
    TObject::SetBit(kFilteredAOD);
    printf("####### Added AOD filter %s\n", name);
  } else printf("####### Added AOD extension %s\n", name);
  KeepUnspecifiedBranches();
}

//______________________________________________________________________________
AliAODExtension::~AliAODExtension()
{
  // Destructor.
  if(fFileE){
    // is already handled in TerminateIO
    fFileE->Close();
    delete fFileE;
    fTreeE = 0;
    fAODEvent = 0;
  }
  if (fTreeE) delete fTreeE;
  if (fRepFiMap) fRepFiMap->DeleteAll();
  delete fRepFiMap; // the map is owner
  delete fRepFiList; // the list is not
  delete fObjectList; // not owner
}

//______________________________________________________________________________
void AliAODExtension::AddBranch(const char* cname, void* addobj)
{
  // Add a new branch to the aod

  if (!fAODEvent) {
    char type[20];
    gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)%p, \"%%s\", s_tmp.Data());", type));
    Init(type);
  }
  TDirectory *owd = gDirectory;
  if (fFileE) {
    fFileE->cd();
  }
  char** apointer = (char**) addobj;
  TObject* obj = (TObject*) *apointer;

  fAODEvent->AddObject(obj);

  TString bname(obj->GetName());

  if (!fTreeE->FindBranch(bname.Data()))
  {
    Bool_t acceptAdd(kTRUE);

    if ( TestBit(kDropUnspecifiedBranches) )
    {
      // check that this branch is in our list of specified ones...
      // otherwise do not add it !
      TIter next(fRepFiMap);
      TObjString* p;

      acceptAdd=kFALSE;

      while ( ( p = static_cast<TObjString*>(next()) ) && !acceptAdd )
      {
        if ( p->String() == bname ) acceptAdd=kTRUE;
      }
    }

    if ( acceptAdd )
    {
      // Do the same as if we book via
      // TTree::Branch(TCollection*)

      fObjectList->Add(obj);

      const Int_t kSplitlevel = 99; // default value in TTree::Branch()
      const Int_t kBufsize = 32000; // default value in TTree::Branch()

      fTreeE->Bronch(bname.Data(), cname,
                     fAODEvent->GetList()->GetObjectRef(obj),
                     kBufsize, kSplitlevel - 1);
    }
  }
  owd->cd();
}

//______________________________________________________________________________
Bool_t AliAODExtension::FinishEvent()
{
  // Fill current event.
  fNtotal++;
  if (!IsFilteredAOD()) {
    fAODEvent->MakeEntriesReferencable();
    fTreeE->Fill();
    return kTRUE;
  }
  // Filtered AOD. Fill only if event is selected.
  if (!fSelected) return kTRUE;

  TIter next(fRepFiList);

  AliAODBranchReplicator* repfi;

  while ( ( repfi = static_cast<AliAODBranchReplicator*>(next()) ) )
  {
    repfi->ReplicateAndFilter(*fAODEvent);
  }
  fNpassed++;
  fTreeE->Fill();
  fSelected = kFALSE; // so that next event will not be selected unless demanded
  return kTRUE;
}

//______________________________________________________________________________
Bool_t AliAODExtension::Init(Option_t *option)
{
  // Initialize IO.

  AliCodeTimerAuto(GetName(),0);

  if(!fAODEvent)
  {
    fAODEvent = new AliAODEvent();
  }

  TDirectory *owd = gDirectory;
  TString opt(option);
  opt.ToLower();

  if (opt.Contains("proof"))
  {
    // proof
    // Merging via files. Need to access analysis manager via interpreter.
    gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
    gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\", \"%s\");", fName.Data()));
    fFileE = gFile;
  }
  else
  {
    fFileE = new TFile(GetName(), "RECREATE");
  }
  fTreeE = new TTree("aodTree", "AliAOD tree");

  delete fObjectList;
  fObjectList = new TList;
  fObjectList->SetOwner(kFALSE); // be explicit we're not the owner...
  TList* inputList = fAODEvent->GetList();
  TIter next(inputList);
  TObject* o;

  while ( ( o = next() ) )
  {
    // Loop on the objects that are within the main AOD, and see what to do with them :
    // - transmit them to our AOD as they are
    // - filter them (by means of an AliAODBranchReplicator)
    // - drop them completely

    Bool_t mustKeep(kFALSE);

    TString test(o->ClassName());
    test.ToUpper();
    if (test.BeginsWith("ALIAODHEADER"))
    {
      // do not allow to drop header branch
      mustKeep=kTRUE;
    }

    if ( fRepFiMap && !mustKeep )
    {
      // we have some replicators, so let's see what the relevant one decides about this object
      TObject* specified = fRepFiMap->FindObject(o->GetName()); // FindObject finds key=o->GetName() in the map
      if (specified)
      {
        AliAODBranchReplicator* repfi = dynamic_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(o->GetName())); // GetValue gets the replicator corresponding to key=o->GetName()
        if ( repfi )
        {
          TList* replicatedList = repfi->GetList();
          if (replicatedList)
          {
            AliAODEvent::AssignIDtoCollection(replicatedList);
            TIter nextRep(replicatedList);
            TObject* objRep;
            while ( ( objRep = nextRep() ) )
            {
              if ( !fObjectList->FindObject(objRep) ) // insure we're not adding several times the same object
              {
                fObjectList->Add(objRep);
              }
            }
          }
          else
          {
            AliError(Form("replicatedList from %s is null !",repfi->GetName()));
          }
        }
      }
      else
      {
        if ( !TestBit(kDropUnspecifiedBranches) )
        {
          // object o will be transmitted to the output AOD, unchanged
          fObjectList->Add(o);
        }
      }
    }
    else
    {
      // no replicator, so decide based on the policy about dropping unspecified branches
      if ( mustKeep || !TestBit(kDropUnspecifiedBranches) )
      {
        // object o will be transmitted to the output AOD, unchanged
        fObjectList->Add(o);
      }
    }
  }

  if (fEnableReferences)
  {
    fTreeE->BranchRef();
  }

  fTreeE->Branch(fObjectList);

  owd->cd();

  return kTRUE;
}

//______________________________________________________________________________
void AliAODExtension::Print(Option_t* opt) const
{
  // Print info about this extension

  cout << opt << Form("%s - %s - %s - aod %p",IsFilteredAOD() ? "FilteredAOD" : "Extension",
                      GetName(),GetTitle(),GetAOD()) << endl;
  if ( !fEnableReferences )
  {
    cout << opt << opt << "References are disabled ! Hope you know what you are doing !" << endl;
  }
  if ( TestBit(kDropUnspecifiedBranches) )
  {
    cout << opt << opt << "All branches not explicitely specified will be dropped" << endl;
  }

  TIter next(fRepFiMap);
  TObjString* s;

  while ( ( s = static_cast<TObjString*>(next()) ) )
  {
    AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));

    cout << opt << opt << "Branch " << s->String();
    if (br)
    {
      cout << " will be filtered by class " << br->ClassName();
    }
    else
    {
      cout << " will be transmitted as is";
    }
    cout << endl;
  }
}

//______________________________________________________________________________
void AliAODExtension::SetEvent(AliAODEvent* event)
{
  // Connects to an external event
  if (!IsFilteredAOD()) {
    Error("SetEvent", "Not allowed to set external event for non filtered AOD's");
    return;
  }
  fAODEvent = event;
}

//______________________________________________________________________________
void AliAODExtension::AddAODtoTreeUserInfo()
{
  // Add aod event to tree user info

  if (!fTreeE) return;

  AliAODEvent* aodEvent(fAODEvent);

  if ( IsFilteredAOD() )
  {
    // cannot attach fAODEvent (which is shared with our AliAODHandler mother)
    // so we create a custom (empty) AliAODEvent
    // Has also the advantage we can specify only the list of objects
    // that are actually there in this filtered aod
    //
    aodEvent = new AliAODEvent;
    TIter nextObj(fObjectList);
    TObject* o;
    while ( ( o = nextObj() ) )
    {
      aodEvent->AddObject(o);
    }
  }

  fTreeE->GetUserInfo()->Add(aodEvent);
}

//______________________________________________________________________________
Bool_t AliAODExtension::TerminateIO()
{
  // Terminate IO
  if (TObject::TestBit(kFilteredAOD))
    printf("AOD Filter %s: events processed: %d   passed: %d\n", GetName(), fNtotal, fNpassed);
  else
    printf("AOD extension %s: events processed: %d\n", GetName(), fNtotal);
  if (fFileE)
  {
    fFileE->Write();
    fFileE->Close();
    delete fFileE;
    fFileE = 0;
    fTreeE = 0;
    fAODEvent = 0;
  }
  return kTRUE;
}

//______________________________________________________________________________
void AliAODExtension::FilterBranch(const char* branchName, AliAODBranchReplicator* repfi)
{
  // Specify a filter/replicator for a given branch
  //
  // If repfi=0x0, this will disable the branch (in the output) completely.
  //
  // repfi is adopted by this class, i.e. user should not delete it.
  //
  // WARNING : branch name must be exact.
  //
  // See also the documentation for AliAODBranchReplicator class.
  //

  if (!fRepFiMap)
  {
    fRepFiMap = new TMap;
    fRepFiMap->SetOwnerKeyValue(kTRUE,kTRUE);
    fRepFiList = new TList;
    fRepFiList->SetOwner(kFALSE);
  }

  fRepFiMap->Add(new TObjString(branchName),repfi);

  if (repfi && !fRepFiList->FindObject(repfi))
  {
    // insure we get unique and non-null replicators in this list
    fRepFiList->Add(repfi);
  }
}

<commit_msg>From Jens: Allow for custom header replicator in AOD<commit_after>#include "AliAODExtension.h"

//-------------------------------------------------------------------------
//     Support class for AOD extensions. This is created by the user analysis
//     that requires a separate file for some AOD branches. The name of the
//     AliAODExtension object is the file name where the AOD branches will be
//     stored.
//-------------------------------------------------------------------------

#include "AliAODBranchReplicator.h"
#include "AliAODEvent.h"
#include "AliCodeTimer.h"
#include "AliLog.h"
#include "Riostream.h"
#include "TDirectory.h"
#include "TFile.h"
#include "TList.h"
#include "TMap.h"
#include "TMap.h"
#include "TObjString.h"
#include "TROOT.h"
#include "TString.h"
#include "TTree.h"

using std::endl;
using std::cout;
ClassImp(AliAODExtension)

//______________________________________________________________________________
AliAODExtension::AliAODExtension() : TNamed(),
fAODEvent(0), fTreeE(0), fFileE(0), fNtotal(0), fNpassed(0),
fSelected(kFALSE), fRepFiMap(0x0), fRepFiList(0x0), fEnableReferences(kTRUE), fObjectList(0x0)
{
  // default ctor
}

//______________________________________________________________________________
AliAODExtension::AliAODExtension(const char* name, const char* title, Bool_t isfilter)
:TNamed(name,title),
fAODEvent(0),
fTreeE(0),
fFileE(0),
fNtotal(0),
fNpassed(0),
fSelected(kFALSE),
fRepFiMap(0x0),
fRepFiList(0x0),
fEnableReferences(kTRUE),
fObjectList(0x0)
{
  // Constructor.
  if (isfilter) {
    TObject::SetBit(kFilteredAOD);
    printf("####### Added AOD filter %s\n", name);
  } else printf("####### Added AOD extension %s\n", name);
  KeepUnspecifiedBranches();
}

//______________________________________________________________________________
AliAODExtension::~AliAODExtension()
{
  // Destructor.
  if(fFileE){
    // is already handled in TerminateIO
    fFileE->Close();
    delete fFileE;
    fTreeE = 0;
    fAODEvent = 0;
  }
  if (fTreeE) delete fTreeE;
  if (fRepFiMap) fRepFiMap->DeleteAll();
  delete fRepFiMap; // the map is owner
  delete fRepFiList; // the list is not
  delete fObjectList; // not owner
}

//______________________________________________________________________________
void AliAODExtension::AddBranch(const char* cname, void* addobj)
{
  // Add a new branch to the aod

  if (!fAODEvent) {
    char type[20];
    gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)%p, \"%%s\", s_tmp.Data());", type));
    Init(type);
  }
  TDirectory *owd = gDirectory;
  if (fFileE) {
    fFileE->cd();
  }
  char** apointer = (char**) addobj;
  TObject* obj = (TObject*) *apointer;

  fAODEvent->AddObject(obj);

  TString bname(obj->GetName());

  if (!fTreeE->FindBranch(bname.Data()))
  {
    Bool_t acceptAdd(kTRUE);

    if ( TestBit(kDropUnspecifiedBranches) )
    {
      // check that this branch is in our list of specified ones...
      // otherwise do not add it !
      TIter next(fRepFiMap);
      TObjString* p;

      acceptAdd=kFALSE;

      while ( ( p = static_cast<TObjString*>(next()) ) && !acceptAdd )
      {
        if ( p->String() == bname ) acceptAdd=kTRUE;
      }
    }

    if ( acceptAdd )
    {
      // Do the same as if we book via
      // TTree::Branch(TCollection*)

      fObjectList->Add(obj);

      const Int_t kSplitlevel = 99; // default value in TTree::Branch()
      const Int_t kBufsize = 32000; // default value in TTree::Branch()

      fTreeE->Bronch(bname.Data(), cname,
                     fAODEvent->GetList()->GetObjectRef(obj),
                     kBufsize, kSplitlevel - 1);
    }
  }
  owd->cd();
}

//______________________________________________________________________________
Bool_t AliAODExtension::FinishEvent()
{
  // Fill current event.
  fNtotal++;
  if (!IsFilteredAOD()) {
    fAODEvent->MakeEntriesReferencable();
    fTreeE->Fill();
    return kTRUE;
  }
  // Filtered AOD. Fill only if event is selected.
  if (!fSelected) return kTRUE;

  TIter next(fRepFiList);

  AliAODBranchReplicator* repfi;

  while ( ( repfi = static_cast<AliAODBranchReplicator*>(next()) ) )
  {
    repfi->ReplicateAndFilter(*fAODEvent);
  }
  fNpassed++;
  fTreeE->Fill();
  fSelected = kFALSE; // so that next event will not be selected unless demanded
  return kTRUE;
}

//______________________________________________________________________________
Bool_t AliAODExtension::Init(Option_t *option)
{
  // Initialize IO.

  AliCodeTimerAuto(GetName(),0);

  if(!fAODEvent)
  {
    fAODEvent = new AliAODEvent();
  }

  TDirectory *owd = gDirectory;
  TString opt(option);
  opt.ToLower();

  if (opt.Contains("proof"))
  {
    // proof
    // Merging via files. Need to access analysis manager via interpreter.
    gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
    gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\", \"%s\");", fName.Data()));
    fFileE = gFile;
  }
  else
  {
    fFileE = new TFile(GetName(), "RECREATE");
  }
  fTreeE = new TTree("aodTree", "AliAOD tree");

  delete fObjectList;
  fObjectList = new TList;
  fObjectList->SetOwner(kFALSE); // be explicit we're not the owner...
  TList* inputList = fAODEvent->GetList();
  TIter next(inputList);
  TObject* o;

  while ( ( o = next() ) )
  {
    // Loop on the objects that are within the main AOD, and see what to do with them :
    // - transmit them to our AOD as they are
    // - filter them (by means of an AliAODBranchReplicator)
    // - drop them completely

    Bool_t mustKeep(kFALSE);

    TString test(o->ClassName());
    test.ToUpper();
    // check if there is a replicator for the header
    Bool_t headerHasReplicator = fRepFiMap && (fRepFiMap->FindObject(o->GetName())!=0x0);
    if (test.BeginsWith("ALIAODHEADER") && !headerHasReplicator)
    {
      // do not allow to drop header branch
      mustKeep=kTRUE;
    }

    if ( fRepFiMap && !mustKeep )
    {
      // we have some replicators, so let's see what the relevant one decides about this object
      TObject* specified = fRepFiMap->FindObject(o->GetName()); // FindObject finds key=o->GetName() in the map
      if (specified)
      {
        AliAODBranchReplicator* repfi = dynamic_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(o->GetName())); // GetValue gets the replicator corresponding to key=o->GetName()
        if ( repfi )
        {
          TList* replicatedList = repfi->GetList();
          if (replicatedList)
          {
            AliAODEvent::AssignIDtoCollection(replicatedList);
            TIter nextRep(replicatedList);
            TObject* objRep;
            while ( ( objRep = nextRep() ) )
            {
              if ( !fObjectList->FindObject(objRep) ) // insure we're not adding several times the same object
              {
                fObjectList->Add(objRep);
              }
            }
          }
          else
          {
            AliError(Form("replicatedList from %s is null !",repfi->GetName()));
          }
        }
      }
      else
      {
        if ( !TestBit(kDropUnspecifiedBranches) )
        {
          // object o will be transmitted to the output AOD, unchanged
          fObjectList->Add(o);
        }
      }
    }
    else
    {
      // no replicator, so decide based on the policy about dropping unspecified branches
      if ( mustKeep || !TestBit(kDropUnspecifiedBranches) )
      {
        // object o will be transmitted to the output AOD, unchanged
        fObjectList->Add(o);
      }
    }
  }

  if (fEnableReferences)
  {
    fTreeE->BranchRef();
  }

  fTreeE->Branch(fObjectList);

  owd->cd();

  return kTRUE;
}

//______________________________________________________________________________
void AliAODExtension::Print(Option_t* opt) const
{
  // Print info about this extension

  cout << opt << Form("%s - %s - %s - aod %p",IsFilteredAOD() ? "FilteredAOD" : "Extension",
                      GetName(),GetTitle(),GetAOD()) << endl;
  if ( !fEnableReferences )
  {
    cout << opt << opt << "References are disabled ! Hope you know what you are doing !" << endl;
  }
  if ( TestBit(kDropUnspecifiedBranches) )
  {
    cout << opt << opt << "All branches not explicitely specified will be dropped" << endl;
  }

  TIter next(fRepFiMap);
  TObjString* s;

  while ( ( s = static_cast<TObjString*>(next()) ) )
  {
    AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));

    cout << opt << opt << "Branch " << s->String();
    if (br)
    {
      cout << " will be filtered by class " << br->ClassName();
    }
    else
    {
      cout << " will be transmitted as is";
    }
    cout << endl;
  }
}

//______________________________________________________________________________
void AliAODExtension::SetEvent(AliAODEvent* event)
{
  // Connects to an external event
  if (!IsFilteredAOD()) {
    Error("SetEvent", "Not allowed to set external event for non filtered AOD's");
    return;
  }
  fAODEvent = event;
}

//______________________________________________________________________________
void AliAODExtension::AddAODtoTreeUserInfo()
{
  // Add aod event to tree user info

  if (!fTreeE) return;

  AliAODEvent* aodEvent(fAODEvent);

  if ( IsFilteredAOD() )
  {
    // cannot attach fAODEvent (which is shared with our AliAODHandler mother)
    // so we create a custom (empty) AliAODEvent
    // Has also the advantage we can specify only the list of objects
    // that are actually there in this filtered aod
    //
    aodEvent = new AliAODEvent;
    TIter nextObj(fObjectList);
    TObject* o;
    while ( ( o = nextObj() ) )
    {
      aodEvent->AddObject(o);
    }
  }

  fTreeE->GetUserInfo()->Add(aodEvent);
}

//______________________________________________________________________________
Bool_t AliAODExtension::TerminateIO()
{
  // Terminate IO
  if (TObject::TestBit(kFilteredAOD))
    printf("AOD Filter %s: events processed: %d   passed: %d\n", GetName(), fNtotal, fNpassed);
  else
    printf("AOD extension %s: events processed: %d\n", GetName(), fNtotal);
  if (fFileE)
  {
    fFileE->Write();
    fFileE->Close();
    delete fFileE;
    fFileE = 0;
    fTreeE = 0;
    fAODEvent = 0;
  }
  return kTRUE;
}

//______________________________________________________________________________
void AliAODExtension::FilterBranch(const char* branchName, AliAODBranchReplicator* repfi)
{
  // Specify a filter/replicator for a given branch
  //
  // If repfi=0x0, this will disable the branch (in the output) completely.
  //
  // repfi is adopted by this class, i.e. user should not delete it.
  //
  // WARNING : branch name must be exact.
  //
  // See also the documentation for AliAODBranchReplicator class.
  //

  if (!fRepFiMap)
  {
    fRepFiMap = new TMap;
    fRepFiMap->SetOwnerKeyValue(kTRUE,kTRUE);
    fRepFiList = new TList;
    fRepFiList->SetOwner(kFALSE);
  }

  fRepFiMap->Add(new TObjString(branchName),repfi);

  if (repfi && !fRepFiList->FindObject(repfi))
  {
    // insure we get unique and non-null replicators in this list
    fRepFiList->Add(repfi);
  }
}

<|endoftext|>


<commit_before>// Example items to include
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
#include <math.h>

int foo [5] = { 14, 4, 144, 20, 13411 };
//ARRAY SYNTAX

int main ()
{
    //FOR LOOPS
    for(int j = 0; j < 4; j++){
        cout << j << endl;
        //PRINTS NUMBERS. COUT is to print out. CIN is to take input from user
        cout << (sizeof(foo)/sizeof(*foo)) << endl;
        //(sizeof(foo)/sizeof(*foo)) is how you find the length of an array
        cout << foo[j] << endl;
        //PRINTS OUT THE J ELEMENT IN THE ARRAY
        swap(foo[j-1], foo[j]);
        //Swaps elements in an array
        while(j > j-1){
            cout << "The world is still spinning" << endl;
        }
        //while loop
    }

    cout << "test" << endl;
    //END ALL C++ MAIN FUNCTIONS WITH RETURNING 0
    return 0;
}<commit_msg>Added start of vectors + reference<commit_after>// Example items to include
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
#include <math.h>

int foo [5] = { 14, 4, 144, 20, 13411 };
//ARRAY SYNTAX
vector<int> v;
//Declares a vector, v, of integers
int size_t size = 10;
vector<int> array(size);    // make room for 10 integers,

int main ()
{
    //FOR LOOPS
    for(int j = 0; j < 4; j++){
        cout << j << endl;
        //PRINTS NUMBERS. COUT is to print out. CIN is to take input from user
        cout << (sizeof(foo)/sizeof(*foo)) << endl;
        //(sizeof(foo)/sizeof(*foo)) is how you find the length of an array
        cout << foo[j] << endl;
        //PRINTS OUT THE J ELEMENT IN THE ARRAY
        swap(foo[j-1], foo[j]);
        //Swaps elements in an array
        while(j > j-1){
            cout << "The world is still spinning" << endl;
        }
        //while loop
    }
    //using vector array right now
    // and initialize them to 0
    // do something with them:
    for(int i=0; i<size; ++i){
        array[i] = i;
        //print out parts of the vector
    }

    cout << "test" << endl;
    //END ALL C++ MAIN FUNCTIONS WITH RETURNING 0
    return 0;
}
/*
//Refrences
http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm

*/<|endoftext|>


<commit_before>#include "../include/IntegerEncodingInitializer.hpp"

namespace clusterer
{
namespace backend
{

IntegerEncodingInitializer::IntegerEncodingInitializer(
        const Graph* g, unsigned maxClusters) : graph(g)
{
    if (maxClusters == 0 || maxClusters >= graph->getNoVertices())
    { maxClusters = graph->getNoVertices() - 1; }

    std::random_device rd;
    rng.seed(rd());
    uni_dist = new std::uniform_int_distribution<unsigned>(0, maxClusters);
}

IntegerVectorEncoding IntegerEncodingInitializer::getRandomSolution()
{
    IntegerVectorEncoding result(graph);
    for (int vert = 0; vert < graph->getNoVertices(); vert++)
    { result.addToCluster(vert, (*uni_dist)(rng)); }
    return result;
}

std::vector<IntegerVectorEncoding> IntegerEncodingInitializer::getInitialPopulation(int count)
{
    std::vector<IntegerVectorEncoding> result;
    for (int i = 0; i < count; i++)
    { result.push_back(getRandomSolution()); }
    return result;
}

}  // namespace backend
}  // namespace clusterer

<commit_msg>initializer fix<commit_after>#include "../include/IntegerEncodingInitializer.hpp"

namespace clusterer
{
namespace backend
{

IntegerEncodingInitializer::IntegerEncodingInitializer(
        const Graph* g, unsigned maxClusters) : graph(g)
{
    if (maxClusters == 0 || maxClusters >= graph->getNoVertices())
    { maxClusters = graph->getNoVertices() - 1; }

    std::random_device rd;
    rng.seed(rd());
    uni_dist = new std::uniform_int_distribution<unsigned>(0, maxClusters);
}

IntegerVectorEncoding IntegerEncodingInitializer::getRandomSolution()
{
    IntegerVectorEncoding result(graph);
    for (int vert = 0; vert < graph->getNoVertices(); vert++)
    { result.addToCluster(vert, (*uni_dist)(rng)); }
    result.normalize();
    return result;
}

std::vector<IntegerVectorEncoding> IntegerEncodingInitializer::getInitialPopulation(int count)
{
    std::vector<IntegerVectorEncoding> result;
    for (int i = 0; i < count; i++)
    { result.push_back(getRandomSolution()); }
    return result;
}

}  // namespace backend
}  // namespace clusterer

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 ARM. All rights reserved.
 */
#include "include/m2mtimerimpl_mbed.h"
#include "lwm2m-client/m2mtimerobserver.h"

M2MTimerImpl& M2MTimerImpl::operator=(const M2MTimerImpl& other)
{
    if( this != &other){
        _single_shot= other._single_shot;
        _ticker = other._ticker;
        _interval = other._interval;
    }
    return *this;
}

// Prevents the use of copy constructor
M2MTimerImpl::M2MTimerImpl(const M2MTimerImpl& other)
:_observer(other._observer)
{
    *this = other;
}

M2MTimerImpl::M2MTimerImpl(M2MTimerObserver& observer)
: _observer(observer),
  _single_shot(true),
  _interval(0)
{
}

M2MTimerImpl::~M2MTimerImpl()
{
}

void M2MTimerImpl::start_timer( uint64_t interval,
                                bool single_shot)
{
    _single_shot = single_shot;
    _interval =  interval ;
    _ticker.detach();
    _ticker.attach_us(this,
                      &M2MTimerImpl::timer_expired,
                      _interval * 1000);
}

void M2MTimerImpl::stop_timer()
{
    _interval = 0;
    _single_shot = false;
    _ticker.detach();
}

void M2MTimerImpl::timer_expired()
{
    _observer.timer_expired();
    if(!_single_shot) {
        start_timer(_interval,true);
    }
}
<commit_msg>timer fix<commit_after>/*
 * Copyright (c) 2015 ARM. All rights reserved.
 */
#include "include/m2mtimerimpl_mbed.h"
#include "lwm2m-client/m2mtimerobserver.h"

M2MTimerImpl& M2MTimerImpl::operator=(const M2MTimerImpl& other)
{
    if( this != &other){
        _single_shot= other._single_shot;
        //_ticker = other._ticker;
        _interval = other._interval;
    }
    return *this;
}

// Prevents the use of copy constructor
M2MTimerImpl::M2MTimerImpl(const M2MTimerImpl& other)
:_observer(other._observer)
{
    *this = other;
}

M2MTimerImpl::M2MTimerImpl(M2MTimerObserver& observer)
: _observer(observer),
  _single_shot(true),
  _interval(0)
{
}

M2MTimerImpl::~M2MTimerImpl()
{
}

void M2MTimerImpl::start_timer( uint64_t interval,
                                bool single_shot)
{
    _single_shot = single_shot;
    _interval =  interval ;
    _ticker.detach();
    _ticker.attach_us(this,
                      &M2MTimerImpl::timer_expired,
                      _interval * 1000);
}

void M2MTimerImpl::stop_timer()
{
    _interval = 0;
    _single_shot = false;
    _ticker.detach();
}

void M2MTimerImpl::timer_expired()
{
    _observer.timer_expired();
    if(!_single_shot) {
        start_timer(_interval,true);
    }
}
<|endoftext|>


<commit_before>#include <windows.h>
#include <OvRender.h>
#include <sloverlay.h>
#include <overlay.h>

SlOverlayMenu* MnuMenu;

MenuVars MnuOsd[20];
MenuVars MnuCache[10];

WCHAR* GroupOpt[] = {L"", L""};
WCHAR* ItemOpt[] = {L"Off", L"On"};

BOOLEAN MnuInitialized;

//Add menu items to menu

VOID
AddItems()
{
    MnuMenu->AddGroup(L"OSD", GroupOpt, &MnuOsd[0].Var);

    if (MnuOsd[0].Var)
    {
        MnuMenu->AddItem(L"GPU Core utilization",    ItemOpt, &MnuOsd[1].Var);
        MnuMenu->AddItem(L"GPU Core temperature",    ItemOpt, &MnuOsd[2].Var);
        MnuMenu->AddItem(L"GPU Engine Clock",        ItemOpt, &MnuOsd[3].Var);
        MnuMenu->AddItem(L"GPU Memory Clock",        ItemOpt, &MnuOsd[4].Var);
        MnuMenu->AddItem(L"GPU VRAM usage",          ItemOpt, &MnuOsd[5].Var);
        MnuMenu->AddItem(L"CPU utilization",         ItemOpt, &MnuOsd[6].Var);
        MnuMenu->AddItem(L"CPU temperature",         ItemOpt, &MnuOsd[7].Var);
        MnuMenu->AddItem(L"RAM usage",               ItemOpt, &MnuOsd[8].Var);
        MnuMenu->AddItem(L"Max core usage",          ItemOpt, &MnuOsd[9].Var);
        MnuMenu->AddItem(L"Max thread usage",        ItemOpt, &MnuOsd[10].Var);
        MnuMenu->AddItem(L"Disk read-write rate",    ItemOpt, &MnuOsd[11].Var);
        MnuMenu->AddItem(L"Disk response time",      ItemOpt, &MnuOsd[12].Var);
        MnuMenu->AddItem(L"Frame Buffer count",      ItemOpt, &MnuOsd[13].Var);
        MnuMenu->AddItem(L"Show Time",               ItemOpt, &MnuOsd[14].Var);
    }

    MnuMenu->AddGroup(L"CACHE", GroupOpt, &MnuCache[0].Var);

    if (MnuCache[0].Var)
    {
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[1].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[2].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[3].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[4].Var);
    }
}

VOID
ProcessOptions()
{
    if (MnuOsd[1].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_LOAD;
    /*else
        PushSharedMemory->OSDFlags &= ~OSD_GPU_LOAD;*/
    //this needs to be fixed, if it was enable by main gui
    //checkbox then it'll get disabled. too lazy...

    if (MnuOsd[2].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_TEMP;

    if (MnuOsd[3].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_E_CLK;

    if (MnuOsd[4].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_M_CLK;

    if (MnuOsd[9].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MCU;

    if (MnuOsd[10].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MTU;
}

VOID
MnuRender( OvOverlay* Overlay )
{
    if (!MnuInitialized)
    {
        MnuMenu = new SlOverlayMenu(300);
        MnuInitialized = TRUE;
    }

    if( MnuMenu->mSet.MaxItems == 0 )
        AddItems();

    //Call drawing and navigation functions
    MnuMenu->Render(100, 200, Overlay);
    ProcessOptions();
}
<commit_msg>added time to in-game settings<commit_after>#include <windows.h>
#include <OvRender.h>
#include <sloverlay.h>
#include <overlay.h>

SlOverlayMenu* MnuMenu;

MenuVars MnuOsd[20];
MenuVars MnuCache[10];

WCHAR* GroupOpt[] = {L"", L""};
WCHAR* ItemOpt[] = {L"Off", L"On"};

BOOLEAN MnuInitialized;

//Add menu items to menu

VOID
AddItems()
{
    MnuMenu->AddGroup(L"OSD", GroupOpt, &MnuOsd[0].Var);

    if (MnuOsd[0].Var)
    {
        MnuMenu->AddItem(L"GPU Core utilization",    ItemOpt, &MnuOsd[1].Var);
        MnuMenu->AddItem(L"GPU Core temperature",    ItemOpt, &MnuOsd[2].Var);
        MnuMenu->AddItem(L"GPU Engine Clock",        ItemOpt, &MnuOsd[3].Var);
        MnuMenu->AddItem(L"GPU Memory Clock",        ItemOpt, &MnuOsd[4].Var);
        MnuMenu->AddItem(L"GPU VRAM usage",          ItemOpt, &MnuOsd[5].Var);
        MnuMenu->AddItem(L"CPU utilization",         ItemOpt, &MnuOsd[6].Var);
        MnuMenu->AddItem(L"CPU temperature",         ItemOpt, &MnuOsd[7].Var);
        MnuMenu->AddItem(L"RAM usage",               ItemOpt, &MnuOsd[8].Var);
        MnuMenu->AddItem(L"Max core usage",          ItemOpt, &MnuOsd[9].Var);
        MnuMenu->AddItem(L"Max thread usage",        ItemOpt, &MnuOsd[10].Var);
        MnuMenu->AddItem(L"Disk read-write rate",    ItemOpt, &MnuOsd[11].Var);
        MnuMenu->AddItem(L"Disk response time",      ItemOpt, &MnuOsd[12].Var);
        MnuMenu->AddItem(L"Frame Buffer count",      ItemOpt, &MnuOsd[13].Var);
        MnuMenu->AddItem(L"Show Time",               ItemOpt, &MnuOsd[14].Var);
    }

    MnuMenu->AddGroup(L"CACHE", GroupOpt, &MnuCache[0].Var);

    if (MnuCache[0].Var)
    {
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[1].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[2].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[3].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[4].Var);
    }
}

VOID
ProcessOptions()
{
    if (MnuOsd[1].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_LOAD;
    /*else
        PushSharedMemory->OSDFlags &= ~OSD_GPU_LOAD;*/
    //this needs to be fixed, if it was enable by main gui
    //checkbox then it'll get disabled. too lazy...

    if (MnuOsd[2].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_TEMP;

    if (MnuOsd[3].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_E_CLK;

    if (MnuOsd[4].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_M_CLK;

    if (MnuOsd[9].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MCU;

    if (MnuOsd[10].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MTU;

    if (MnuOsd[14].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_TIME;
}

VOID
MnuRender( OvOverlay* Overlay )
{
    if (!MnuInitialized)
    {
        MnuMenu = new SlOverlayMenu(300);
        MnuInitialized = TRUE;
    }

    if( MnuMenu->mSet.MaxItems == 0 )
        AddItems();

    //Call drawing and navigation functions
    MnuMenu->Render(100, 200, Overlay);
    ProcessOptions();
}
<|endoftext|>