<commit_before>#include <netinet/in.h>
#include <sys/types.h>

#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pthread.h>
#ifdef __FreeBSD__
#include <pthread_np.h>
#endif
#include <sched.h>
#include <sys/cpuset.h>
#include <sys/resource.h>
#include <sys/time.h>

#include <fstream>
#include <iostream>
#include <thread>

#include "Engine.h"
#include "PcapSource.h"
#include "Session.h"
#include "regexbench.h"

using namespace regexbench;

uint32_t regexbench::getPLOffset(const std::string& packet)
{
  uint16_t offset = 0;
  uint16_t ether_type =
      ntohs(reinterpret_cast<const ether_header*>(packet.data())->ether_type);
  if (ether_type == ETHERTYPE_VLAN) {
    offset = 4;
    ether_type =
        ntohs(reinterpret_cast<const ether_header*>(packet.data() + offset)
                  ->ether_type);
  }
  switch (ether_type) {
  case ETHERTYPE_IP: {
    offset += sizeof(ether_header);
    const ip* ih = reinterpret_cast<const ip*>(packet.data() + offset);
    offset += ih->ip_hl << 2;
    switch (ih->ip_p) {
    case IPPROTO_TCP:
      offset += reinterpret_cast<const tcphdr*>(packet.data() + offset)
#ifdef __linux__
                    ->doff
#else
                    ->th_off
#endif
                << 2;
      break;
    case IPPROTO_UDP:
      offset += sizeof(udphdr);
      break;
    case IPPROTO_ICMP:
      offset += ICMP_MINLEN;
      break;
    default:
      break;
    }
  } break;
  case ETHERTYPE_IPV6: {
    offset += sizeof(ether_header) + sizeof(ip6_hdr);
    const ip6_hdr* ih6 =
        reinterpret_cast<const ip6_hdr*>(packet.data() + offset);
    switch (ih6->ip6_ctlun.ip6_un1.ip6_un1_nxt) {
    case IPPROTO_TCP:
      offset += reinterpret_cast<const tcphdr*>(packet.data() + offset)
#ifdef __linux__
                    ->doff
#else
                    ->th_off
#endif
                << 2;
      break;
    case IPPROTO_UDP:
      offset += sizeof(udphdr);
      break;
    case IPPROTO_ICMP:
      offset += ICMP_MINLEN;
      break;
    default:
      break;
    }
  } break;
  default:
    break;
  }
  return offset;
}

std::vector<MatchMeta> regexbench::buildMatchMeta(const PcapSource& src,
                                                  size_t& nsessions)
{
  std::vector<MatchMeta> matcher_info;
  SessionTable sessionTable;
  for (const auto& pkt : src) {
    auto offset = getPLOffset(pkt);
    size_t sid = 0;
    Session s(pkt.data());
    sessionTable.find(s, sid);

    matcher_info.emplace_back(sid, offset, pkt.size() - offset);
  }
  nsessions = sessionTable.getSessionNum();
  return matcher_info;
}

#if 0
MatchResult regexbench::match(Engine& engine, const PcapSource& src,
                              long repeat, const std::vector<MatchMeta>& meta)
{
  struct rusage begin, end;
  MatchResult result;
  getrusage(RUSAGE_SELF, &begin);
  for (long i = 0; i < repeat; ++i) {
    for (size_t j = 0; j < src.getNumberOfPackets(); j++) {
      auto matches =
          engine.match(src[j].data() + meta[j].oft, meta[j].len, meta[j].sid);
      if (matches) {
        result.nmatches += matches;
        result.nmatched_pkts++;
      }
    }
  }
  getrusage(RUSAGE_SELF, &end);
  timersub(&(end.ru_utime), &(begin.ru_utime), &result.udiff);
  timersub(&(end.ru_stime), &(begin.ru_stime), &result.sdiff);
  return result;
}
#else
#ifdef __linux__
using cpuset_t = cpu_set_t;
#endif
void regexbench::matchThread(Engine* engine, const PcapSource* src, long repeat,
                             size_t core, size_t sel,
                             const std::vector<MatchMeta>* meta,
                             MatchResult* result)
{
  cpuset_t cpuset;
  CPU_ZERO(&cpuset);
  CPU_SET(core, &cpuset);
  if (pthread_setaffinity_np(pthread_self(), sizeof(cpuset_t), &cpuset) != 0) {
    std::cerr << "Setting affinty to a match thread failed" << std::endl;
    return;
  }
  // std::cout << "set match thread_" << sel << "'s affinity to " << core <<
  // std::endl;

  struct rusage begin, end;
  getrusage(RUSAGE_THREAD, &begin);
  for (long i = 0; i < repeat; ++i) {
    for (size_t j = 0; j < src->getNumberOfPackets(); j++) {
      auto matches = engine->match((*src)[j].data() + (*meta)[j].oft,
                                   (*meta)[j].len, (*meta)[j].sid, sel);
      if (matches) {
        result->nmatches += matches;
        result->nmatched_pkts++;
      }
    }
  }
  getrusage(RUSAGE_THREAD, &end);
  timersub(&(end.ru_utime), &(begin.ru_utime), &result->udiff);
  timersub(&(end.ru_stime), &(begin.ru_stime), &result->sdiff);
}
#endif

std::vector<MatchResult> regexbench::match(Engine& engine,
                                           const PcapSource& src, long repeat,
                                           const std::vector<size_t>& cores,
                                           const std::vector<MatchMeta>& meta)
{
  std::vector<std::thread> threads;
  std::vector<size_t>::const_iterator coreIter, coreEnd;
  std::vector<size_t> defaultCores;

  std::vector<MatchResult> results;
  if (cores.size() < 2) {
    defaultCores.push_back(0); // TODO : revisit
    defaultCores.push_back(0);
    results.resize(1);
    coreIter = defaultCores.cbegin();
    coreEnd = defaultCores.cend();
  } else {
    results.resize(cores.size() - 1);
    coreIter = cores.cbegin();
    coreEnd = cores.cend();
  }
  auto mainCore = *coreIter++;

  // set affinity to main thread itself
  cpuset_t cpuset;
  CPU_ZERO(&cpuset);
  CPU_SET(mainCore, &cpuset);
  if (pthread_setaffinity_np(pthread_self(), sizeof(cpuset_t), &cpuset) != 0) {
    std::cerr << "Setting affinty to a match thread failed" << std::endl;
    return std::vector<MatchResult>();
  }

  size_t i = 0;
  for (; coreIter != coreEnd; ++coreIter, ++i) {
    threads.push_back(std::thread(&regexbench::matchThread, &engine, &src,
                                  repeat, *coreIter, i, &meta, &results[i]));
  }
  for (auto& thr : threads)
    thr.join();

  return results;
}

std::vector<regexbench::Rule> regexbench::loadRules(const std::string& filename)
{
  std::ifstream ruleifs(filename);
  if (!ruleifs) {
    std::cerr << "cannot open rule file: " << filename << std::endl;
    std::exit(EXIT_FAILURE);
  }
  return regexbench::loadRules(ruleifs);
}
<commit_msg>Fix compile error in linux introduced by prev commit<commit_after>#include <netinet/in.h>
#include <sys/types.h>

#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pthread.h>
#ifdef __FreeBSD__
#include <pthread_np.h>
#endif
#include <sched.h>
#ifdef __FreeBSD__
#include <sys/cpuset.h>
#endif
#include <sys/resource.h>
#include <sys/time.h>

#include <fstream>
#include <iostream>
#include <thread>

#include "Engine.h"
#include "PcapSource.h"
#include "Session.h"
#include "regexbench.h"

using namespace regexbench;

uint32_t regexbench::getPLOffset(const std::string& packet)
{
  uint16_t offset = 0;
  uint16_t ether_type =
      ntohs(reinterpret_cast<const ether_header*>(packet.data())->ether_type);
  if (ether_type == ETHERTYPE_VLAN) {
    offset = 4;
    ether_type =
        ntohs(reinterpret_cast<const ether_header*>(packet.data() + offset)
                  ->ether_type);
  }
  switch (ether_type) {
  case ETHERTYPE_IP: {
    offset += sizeof(ether_header);
    const ip* ih = reinterpret_cast<const ip*>(packet.data() + offset);
    offset += ih->ip_hl << 2;
    switch (ih->ip_p) {
    case IPPROTO_TCP:
      offset += reinterpret_cast<const tcphdr*>(packet.data() + offset)
#ifdef __linux__
                    ->doff
#else
                    ->th_off
#endif
                << 2;
      break;
    case IPPROTO_UDP:
      offset += sizeof(udphdr);
      break;
    case IPPROTO_ICMP:
      offset += ICMP_MINLEN;
      break;
    default:
      break;
    }
  } break;
  case ETHERTYPE_IPV6: {
    offset += sizeof(ether_header) + sizeof(ip6_hdr);
    const ip6_hdr* ih6 =
        reinterpret_cast<const ip6_hdr*>(packet.data() + offset);
    switch (ih6->ip6_ctlun.ip6_un1.ip6_un1_nxt) {
    case IPPROTO_TCP:
      offset += reinterpret_cast<const tcphdr*>(packet.data() + offset)
#ifdef __linux__
                    ->doff
#else
                    ->th_off
#endif
                << 2;
      break;
    case IPPROTO_UDP:
      offset += sizeof(udphdr);
      break;
    case IPPROTO_ICMP:
      offset += ICMP_MINLEN;
      break;
    default:
      break;
    }
  } break;
  default:
    break;
  }
  return offset;
}

std::vector<MatchMeta> regexbench::buildMatchMeta(const PcapSource& src,
                                                  size_t& nsessions)
{
  std::vector<MatchMeta> matcher_info;
  SessionTable sessionTable;
  for (const auto& pkt : src) {
    auto offset = getPLOffset(pkt);
    size_t sid = 0;
    Session s(pkt.data());
    sessionTable.find(s, sid);

    matcher_info.emplace_back(sid, offset, pkt.size() - offset);
  }
  nsessions = sessionTable.getSessionNum();
  return matcher_info;
}

#if 0
MatchResult regexbench::match(Engine& engine, const PcapSource& src,
                              long repeat, const std::vector<MatchMeta>& meta)
{
  struct rusage begin, end;
  MatchResult result;
  getrusage(RUSAGE_SELF, &begin);
  for (long i = 0; i < repeat; ++i) {
    for (size_t j = 0; j < src.getNumberOfPackets(); j++) {
      auto matches =
          engine.match(src[j].data() + meta[j].oft, meta[j].len, meta[j].sid);
      if (matches) {
        result.nmatches += matches;
        result.nmatched_pkts++;
      }
    }
  }
  getrusage(RUSAGE_SELF, &end);
  timersub(&(end.ru_utime), &(begin.ru_utime), &result.udiff);
  timersub(&(end.ru_stime), &(begin.ru_stime), &result.sdiff);
  return result;
}
#else
#ifdef __linux__
using cpuset_t = cpu_set_t;
#endif
void regexbench::matchThread(Engine* engine, const PcapSource* src, long repeat,
                             size_t core, size_t sel,
                             const std::vector<MatchMeta>* meta,
                             MatchResult* result)
{
  cpuset_t cpuset;
  CPU_ZERO(&cpuset);
  CPU_SET(core, &cpuset);
  if (pthread_setaffinity_np(pthread_self(), sizeof(cpuset_t), &cpuset) != 0) {
    std::cerr << "Setting affinty to a match thread failed" << std::endl;
    return;
  }
  // std::cout << "set match thread_" << sel << "'s affinity to " << core <<
  // std::endl;

  struct rusage begin, end;
  getrusage(RUSAGE_THREAD, &begin);
  for (long i = 0; i < repeat; ++i) {
    for (size_t j = 0; j < src->getNumberOfPackets(); j++) {
      auto matches = engine->match((*src)[j].data() + (*meta)[j].oft,
                                   (*meta)[j].len, (*meta)[j].sid, sel);
      if (matches) {
        result->nmatches += matches;
        result->nmatched_pkts++;
      }
    }
  }
  getrusage(RUSAGE_THREAD, &end);
  timersub(&(end.ru_utime), &(begin.ru_utime), &result->udiff);
  timersub(&(end.ru_stime), &(begin.ru_stime), &result->sdiff);
}
#endif

std::vector<MatchResult> regexbench::match(Engine& engine,
                                           const PcapSource& src, long repeat,
                                           const std::vector<size_t>& cores,
                                           const std::vector<MatchMeta>& meta)
{
  std::vector<std::thread> threads;
  std::vector<size_t>::const_iterator coreIter, coreEnd;
  std::vector<size_t> defaultCores;

  std::vector<MatchResult> results;
  if (cores.size() < 2) {
    defaultCores.push_back(0); // TODO : revisit
    defaultCores.push_back(0);
    results.resize(1);
    coreIter = defaultCores.cbegin();
    coreEnd = defaultCores.cend();
  } else {
    results.resize(cores.size() - 1);
    coreIter = cores.cbegin();
    coreEnd = cores.cend();
  }
  auto mainCore = *coreIter++;

  // set affinity to main thread itself
  cpuset_t cpuset;
  CPU_ZERO(&cpuset);
  CPU_SET(mainCore, &cpuset);
  if (pthread_setaffinity_np(pthread_self(), sizeof(cpuset_t), &cpuset) != 0) {
    std::cerr << "Setting affinty to a match thread failed" << std::endl;
    return std::vector<MatchResult>();
  }

  size_t i = 0;
  for (; coreIter != coreEnd; ++coreIter, ++i) {
    threads.push_back(std::thread(&regexbench::matchThread, &engine, &src,
                                  repeat, *coreIter, i, &meta, &results[i]));
  }
  for (auto& thr : threads)
    thr.join();

  return results;
}

std::vector<regexbench::Rule> regexbench::loadRules(const std::string& filename)
{
  std::ifstream ruleifs(filename);
  if (!ruleifs) {
    std::cerr << "cannot open rule file: " << filename << std::endl;
    std::exit(EXIT_FAILURE);
  }
  return regexbench::loadRules(ruleifs);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: framework.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:34:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX
#define INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX
#include "rtl/ustring.hxx"
#include "rtl/byteseq.hxx"
#include "jvmfwk/framework.h"
#include "jvmfwk/vendorplugin.h"

/** typedefs for functions from vendorplugin.h
 */
typedef javaPluginError (*jfw_plugin_getAllJavaInfos_ptr)(
    rtl_uString * sVendor,
    rtl_uString * sMinVersion,
    rtl_uString * sMaxVersion,
    rtl_uString * * arExcludeList,
    sal_Int32  nLenList,
    JavaInfo*** parJavaInfo,
    sal_Int32 *nLenInfoList);

typedef javaPluginError (*jfw_plugin_getJavaInfoByPath_ptr)(
    rtl_uString * sPath,
    rtl_uString * sVendor,
    rtl_uString * sMinVersion,
    rtl_uString * sMaxVersion,
    rtl_uString * * arExcludeList,
    sal_Int32  nLenList,
    JavaInfo** ppInfo);

/** starts a Java Virtual Machine.

    The function shall ensure, that the VM does not abort the process
    during instantiation.

 */
typedef javaPluginError (*jfw_plugin_startJavaVirtualMachine_ptr)(
    const JavaInfo *info,
    const JavaVMOption* options,
    sal_Int32 cOptions,
    JavaVM ** ppVM,
    JNIEnv ** ppEnv);

namespace jfw
{

class CJavaInfo
{
    static JavaInfo * copyJavaInfo(const JavaInfo * pInfo);

    enum _transfer_ownership {TRANSFER};
    /*Attaching the pointer to this class. The argument pInfo must not
    be freed afterwards.
    */
    CJavaInfo(::JavaInfo * info, _transfer_ownership);

public:
    ::JavaInfo * pInfo;

    CJavaInfo();
    explicit CJavaInfo(const ::JavaInfo* pInfo);
    CJavaInfo(const CJavaInfo &);
    ~CJavaInfo();
    CJavaInfo& operator =(const ::JavaInfo* info);
    CJavaInfo & operator = (const CJavaInfo& info);

    /* The returned class takes ownership of the argument info. info
    must not been freed afterwards.
    */
    static CJavaInfo createWrapper(::JavaInfo* info);
    /*Attaching the pointer to this class. The argument pInfo must not
    be freed afterwards.
    */
    void attach(::JavaInfo* pInfo);
    ::JavaInfo * detach();
    const ::JavaInfo* operator ->() const;
//    ::JavaInfo** operator & ();
    operator ::JavaInfo* ();
    operator ::JavaInfo const * () const;
    ::JavaInfo* cloneJavaInfo() const;

    rtl::OUString getVendor() const;
    rtl::OUString getLocation() const;
    rtl::OUString getVersion() const;
    sal_uInt64 getFeatures() const;
    sal_uInt64 getRequirements() const;
    rtl::ByteSequence getVendorData() const;
};

class FrameworkException
{
public:

    FrameworkException(javaFrameworkError err, const rtl::OString& msg):
        errorCode(err), message(msg)
        {
        }
    javaFrameworkError errorCode;
    rtl::OString message;
};
}
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.7.126); FILE MERGED 2008/03/31 07:24:51 rt 1.7.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: framework.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX
#define INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX
#include "rtl/ustring.hxx"
#include "rtl/byteseq.hxx"
#include "jvmfwk/framework.h"
#include "jvmfwk/vendorplugin.h"

/** typedefs for functions from vendorplugin.h
 */
typedef javaPluginError (*jfw_plugin_getAllJavaInfos_ptr)(
    rtl_uString * sVendor,
    rtl_uString * sMinVersion,
    rtl_uString * sMaxVersion,
    rtl_uString * * arExcludeList,
    sal_Int32  nLenList,
    JavaInfo*** parJavaInfo,
    sal_Int32 *nLenInfoList);

typedef javaPluginError (*jfw_plugin_getJavaInfoByPath_ptr)(
    rtl_uString * sPath,
    rtl_uString * sVendor,
    rtl_uString * sMinVersion,
    rtl_uString * sMaxVersion,
    rtl_uString * * arExcludeList,
    sal_Int32  nLenList,
    JavaInfo** ppInfo);

/** starts a Java Virtual Machine.

    The function shall ensure, that the VM does not abort the process
    during instantiation.

 */
typedef javaPluginError (*jfw_plugin_startJavaVirtualMachine_ptr)(
    const JavaInfo *info,
    const JavaVMOption* options,
    sal_Int32 cOptions,
    JavaVM ** ppVM,
    JNIEnv ** ppEnv);

namespace jfw
{

class CJavaInfo
{
    static JavaInfo * copyJavaInfo(const JavaInfo * pInfo);

    enum _transfer_ownership {TRANSFER};
    /*Attaching the pointer to this class. The argument pInfo must not
    be freed afterwards.
    */
    CJavaInfo(::JavaInfo * info, _transfer_ownership);

public:
    ::JavaInfo * pInfo;

    CJavaInfo();
    explicit CJavaInfo(const ::JavaInfo* pInfo);
    CJavaInfo(const CJavaInfo &);
    ~CJavaInfo();
    CJavaInfo& operator =(const ::JavaInfo* info);
    CJavaInfo & operator = (const CJavaInfo& info);

    /* The returned class takes ownership of the argument info. info
    must not been freed afterwards.
    */
    static CJavaInfo createWrapper(::JavaInfo* info);
    /*Attaching the pointer to this class. The argument pInfo must not
    be freed afterwards.
    */
    void attach(::JavaInfo* pInfo);
    ::JavaInfo * detach();
    const ::JavaInfo* operator ->() const;
//    ::JavaInfo** operator & ();
    operator ::JavaInfo* ();
    operator ::JavaInfo const * () const;
    ::JavaInfo* cloneJavaInfo() const;

    rtl::OUString getVendor() const;
    rtl::OUString getLocation() const;
    rtl::OUString getVersion() const;
    sal_uInt64 getFeatures() const;
    sal_uInt64 getRequirements() const;
    rtl::ByteSequence getVendorData() const;
};

class FrameworkException
{
public:

    FrameworkException(javaFrameworkError err, const rtl::OString& msg):
        errorCode(err), message(msg)
        {
        }
    javaFrameworkError errorCode;
    rtl::OString message;
};
}
#endif
<|endoftext|>


<commit_before><commit_msg>Bugfix: `Scene::get_twin_turbo_factor`: return `NAN` as a fallback.<commit_after><|endoftext|>


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

#include <stdlib.h>
#include <string.h>
#include "memory_align.h"
#include "macros.h"

namespace WelsCommon {

#ifdef MEMORY_CHECK
static FILE*    fpMemChkPoint;
static uint32_t nCountRequestNum;
static int32_t  g_iMemoryLength;
#endif

CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
#ifdef MEMORY_MONITOR
  : m_nMemoryUsageInBytes (0)
#endif//MEMORY_MONITOR
{
  if ((kuiCacheLineSize == 0) || (kuiCacheLineSize & 0x0f))
    m_nCacheLineSize = 0x10;
  else
    m_nCacheLineSize = kuiCacheLineSize;
}

CMemoryAlign::~CMemoryAlign() {
#ifdef MEMORY_MONITOR
  assert (m_nMemoryUsageInBytes == 0);
#endif//MEMORY_MONITOR
}

void* WelsMalloc (const uint32_t kuiSize, const char* kpTag, const uint32_t kiAlign) {
  const int32_t kiSizeOfVoidPointer     = sizeof (void**);
  const int32_t kiSizeOfInt             = sizeof (int32_t);
  const int32_t kiAlignedBytes          = kiAlign - 1;
  const int32_t kiTrialRequestedSize    = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  const int32_t kiActualRequestedSize   = kiTrialRequestedSize;
  const uint32_t kiPayloadSize          = kuiSize;

  uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
#ifdef MEMORY_CHECK
  if (fpMemChkPoint == NULL) {
    fpMemChkPoint    = fopen ("./enc_mem_check_point.txt",  "at+");
    nCountRequestNum = 0;
  }

  if (fpMemChkPoint != NULL) {
    if (kpTag != NULL)
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
               (void*)pBuf, kiActualRequestedSize, kuiSize, nCountRequestNum++, kpTag);
    else
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
               kiActualRequestedSize, kuiSize, nCountRequestNum++);
    fflush (fpMemChkPoint);
  }
#endif
  uint8_t* pAlignedBuffer;

  if (NULL == pBuf)
    return NULL;

  pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
  * ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
  * ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;

  return pAlignedBuffer;
}

void WelsFree (void* pPointer, const char* kpTag) {
  if (pPointer) {
#ifdef MEMORY_CHECK
    if (fpMemChkPoint != NULL) {
      if (kpTag != NULL)
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
                 g_iMemoryLength);
      else
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
      fflush (fpMemChkPoint);
    }
#endif
    free (* (((void**) pPointer) - 1));
  }
}

void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag);
  if (NULL == pPointer) {
    return NULL;
  }
  // zero memory
  memset (pPointer, 0, kuiSize);

  return pPointer;
}

void* CMemoryAlign::WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsCommon::WelsMalloc (kuiSize, kpTag, m_nCacheLineSize);
#ifdef MEMORY_MONITOR
  if (pPointer != NULL) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes += kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  return pPointer;
}

void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
#ifdef MEMORY_MONITOR
  if (pPointer) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes -= kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  WelsCommon::WelsFree (pPointer, kpTag);
}

void* WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag, 16);
  if (NULL == pPointer) {
    return NULL;
  }
  memset (pPointer, 0, kuiSize);
  return pPointer;
}

const uint32_t CMemoryAlign::WelsGetCacheLineSize() const {
  return m_nCacheLineSize;
}

const uint32_t CMemoryAlign::WelsGetMemoryUsage() const {
  return m_nMemoryUsageInBytes;
}

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

#include <stdlib.h>
#include <string.h>
#include "memory_align.h"
#include "macros.h"

namespace WelsCommon {

#ifdef MEMORY_CHECK
static FILE*    fpMemChkPoint;
static uint32_t nCountRequestNum;
static int32_t  g_iMemoryLength;
#endif

CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
#ifdef MEMORY_MONITOR
  : m_nMemoryUsageInBytes (0)
#endif//MEMORY_MONITOR
{
  if ((kuiCacheLineSize == 0) || (kuiCacheLineSize & 0x0f))
    m_nCacheLineSize = 0x10;
  else
    m_nCacheLineSize = kuiCacheLineSize;
}

CMemoryAlign::~CMemoryAlign() {
#ifdef MEMORY_MONITOR
  assert (m_nMemoryUsageInBytes == 0);
#endif//MEMORY_MONITOR
}

void* WelsMalloc (const uint32_t kuiSize, const char* kpTag, const uint32_t kiAlign) {
  const int32_t kiSizeOfVoidPointer     = sizeof (void**);
  const int32_t kiSizeOfInt             = sizeof (int32_t);
  const int32_t kiAlignedBytes          = kiAlign - 1;
  const int32_t kiTrialRequestedSize    = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  const int32_t kiActualRequestedSize   = kiTrialRequestedSize;
  const uint32_t kiPayloadSize          = kuiSize;

  uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
  if (NULL == pBuf)
    return NULL;

#ifdef MEMORY_CHECK
  if (fpMemChkPoint == NULL) {
    fpMemChkPoint    = fopen ("./enc_mem_check_point.txt",  "at+");
    nCountRequestNum = 0;
  }

  if (fpMemChkPoint != NULL) {
    if (kpTag != NULL)
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
               (void*)pBuf, kiActualRequestedSize, kuiSize, nCountRequestNum++, kpTag);
    else
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
               kiActualRequestedSize, kuiSize, nCountRequestNum++);
    fflush (fpMemChkPoint);
  }
#endif
  uint8_t* pAlignedBuffer;
  pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
  * ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
  * ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;

  return pAlignedBuffer;
}

void WelsFree (void* pPointer, const char* kpTag) {
  if (pPointer) {
#ifdef MEMORY_CHECK
    if (fpMemChkPoint != NULL) {
      if (kpTag != NULL)
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
                 g_iMemoryLength);
      else
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
      fflush (fpMemChkPoint);
    }
#endif
    free (* (((void**) pPointer) - 1));
  }
}

void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag);
  if (NULL == pPointer) {
    return NULL;
  }
  // zero memory
  memset (pPointer, 0, kuiSize);

  return pPointer;
}

void* CMemoryAlign::WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsCommon::WelsMalloc (kuiSize, kpTag, m_nCacheLineSize);
#ifdef MEMORY_MONITOR
  if (pPointer != NULL) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes += kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  return pPointer;
}

void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
#ifdef MEMORY_MONITOR
  if (pPointer) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes -= kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  WelsCommon::WelsFree (pPointer, kpTag);
}

void* WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag, 16);
  if (NULL == pPointer) {
    return NULL;
  }
  memset (pPointer, 0, kuiSize);
  return pPointer;
}

const uint32_t CMemoryAlign::WelsGetCacheLineSize() const {
  return m_nCacheLineSize;
}

const uint32_t CMemoryAlign::WelsGetMemoryUsage() const {
  return m_nMemoryUsageInBytes;
}

} // end of namespace WelsCommon
<|endoftext|>


<commit_before>#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <mpi.h>
#include <fcntl.h>
#include <sched.h>

#include "log.h"
#include "config.h"

#include "socktransport.h"

SockTransport::SockTransport()
{
   getProcInfo();
   initSockets();
   initBufferLists();

   m_global_node = new SockNode(GLOBAL_TAG, this);
}

void SockTransport::getProcInfo()
{
   SInt32 err;

   LOG_PRINT("getProcInfo()");

   err = MPI_Init(NULL, NULL);
   LOG_ASSERT_ERROR(err == MPI_SUCCESS, "MPI_Init_thread fail.");

   err = MPI_Comm_size(MPI_COMM_WORLD, &m_num_procs);
   LOG_ASSERT_ERROR(err == MPI_SUCCESS, "MPI_Comm_size fail.");
   LOG_ASSERT_ERROR(m_num_procs == (SInt32)Config::getSingleton()->getProcessCount(), "Config no. processes doesn't match MPI no. processes.");

   err = MPI_Comm_rank(MPI_COMM_WORLD, &m_proc_index);
   LOG_ASSERT_ERROR(err == MPI_SUCCESS, "MPI_Comm_rank fail.");

   Config::getSingleton()->setProcessNum(m_proc_index);
   LOG_PRINT("Process number set to %i", Config::getSingleton()->getCurrentProcessNum());
}

void SockTransport::initSockets()
{
   SInt32 my_port;

   LOG_PRINT("initSockets()");

   // -- server side
   my_port = BASE_PORT + m_proc_index;
   m_server_socket.listen(my_port, m_num_procs);

   // -- client side
   m_send_sockets = new Socket[m_num_procs];
   for (SInt32 proc = 0; proc < m_num_procs; proc++)
   {
      m_send_sockets[proc].connect("127.0.0.1", // FIXME: assume single machine
                                   BASE_PORT + proc);

      m_send_sockets[proc].send(&m_proc_index, sizeof(m_proc_index));
   }

   // -- accept connections
   m_recv_sockets = new Socket[m_num_procs];
   m_recv_locks = new Lock[m_num_procs];

   for (SInt32 proc = 0; proc < m_num_procs; proc++)
   {
      Socket sock = m_server_socket.accept();

      SInt32 proc_index;
      sock.recv(&proc_index, sizeof(proc_index), true);

      LOG_ASSERT_ERROR(0 <= proc_index && proc_index < m_num_procs,
                       "Connected process out of range: %d",
                       proc_index);

      m_recv_sockets[proc_index] = sock;
   }
}

void SockTransport::initBufferLists()
{
   m_num_lists
      = Config::getSingleton()->getTotalCores() // for cores
      + 1; // for global node

   m_buffer_lists = new buffer_list[m_num_lists];
   m_buffer_locks = new Lock[m_num_lists];
}

void SockTransport::updateBufferLists()
{
   for (SInt32 i = 0; i < m_num_procs; i++)
   {
      while (true)
      {
         UInt32 length;

         m_recv_locks[i].acquire();

         // first get packet length, abort if none available
         if (!m_recv_sockets[i].recv(&length, sizeof(length), false))
         {
            m_recv_locks[i].release();
            break;
         }

         // now receive packet
         SInt32 tag;
         m_recv_sockets[i].recv(&tag, sizeof(tag), true);

         Byte *buffer = new Byte[length];
         m_recv_sockets[i].recv(buffer, length, true);

         m_recv_locks[i].release();

         if (tag == GLOBAL_TAG)
            tag = m_num_lists - 1;

         m_buffer_locks[tag].acquire();
         m_buffer_lists[tag].push_back(buffer);
         m_buffer_locks[tag].release();
      }
   }
}

SockTransport::~SockTransport()
{
   LOG_PRINT("dtor");

   delete m_global_node;

   delete [] m_buffer_locks;
   delete [] m_buffer_lists;

   m_server_socket.close();

   for (SInt32 i = 0; i < m_num_procs; i++)
   {
      m_recv_sockets[i].close();
      m_send_sockets[i].close();
   }

   delete [] m_recv_locks;
   delete [] m_recv_sockets;
   delete [] m_send_sockets;
}

Transport::Node* SockTransport::createNode(core_id_t core_id)
{
   return new SockNode(core_id, this);
}

void SockTransport::barrier()
{
   // FIXME: implement
}

Transport::Node* SockTransport::getGlobalNode()
{
   return m_global_node;
}

// -- SockTransport::SockNode

SockTransport::SockNode::SockNode(core_id_t core_id, SockTransport *trans)
   : Node(core_id)
   , m_transport(trans)
{
}

SockTransport::SockNode::~SockNode()
{
}

void SockTransport::SockNode::globalSend(SInt32 dest_proc,
                                         const void *buffer,
                                         UInt32 length)
{
   send(dest_proc, GLOBAL_TAG, buffer, length);
}

void SockTransport::SockNode::send(core_id_t dest_core,
                                   const void *buffer,
                                   UInt32 length)
{
   int dest_proc = Config::getSingleton()->getProcessNumForCore(dest_core);
   send(dest_proc, dest_core, buffer, length);
}

Byte* SockTransport::SockNode::recv()
{
   LOG_PRINT("Entering recv");

   core_id_t tag = getCoreId();
   tag = (tag == GLOBAL_TAG) ? m_transport->m_num_lists - 1 : tag;

   buffer_list &list = m_transport->m_buffer_lists[tag];
   Lock &lock = m_transport->m_buffer_locks[tag];

   while (true)
   {
      m_transport->updateBufferLists();

      lock.acquire();

      if (!list.empty())
      {
         Byte *buffer = list.front();
         list.pop_front();
         lock.release();

         LOG_PRINT("Message recv'd");

         return buffer;
      }
      else
      {
         lock.release();
         sched_yield();
      }
   }
}

bool SockTransport::SockNode::query()
{
   m_transport->updateBufferLists();

   core_id_t tag = getCoreId();
   tag = (tag == GLOBAL_TAG) ? m_transport->m_num_lists - 1 : tag;

   buffer_list &list = m_transport->m_buffer_lists[tag];
   Lock &lock = m_transport->m_buffer_locks[tag];

   lock.acquire();
   bool result = !list.empty();
   lock.release();
   return result;
}

void SockTransport::SockNode::send(SInt32 dest_proc,
                                   UInt32 tag,
                                   const void *buffer,
                                   UInt32 length)
{
   SInt32 pkt_len = length + sizeof(tag) + sizeof(length);

   Byte *pkt_buff = new Byte[pkt_len];

   Packet *p = (Packet*)pkt_buff;
   p->length = length;
   p->tag = tag;
   memcpy(&p->data, buffer, length);

   m_transport->m_send_sockets[dest_proc].send(pkt_buff, pkt_len);

   LOG_PRINT("Message sent.");

   delete [] pkt_buff;
}

// -- Socket

SockTransport::Socket::Socket()
   : m_socket(-1)
{
}

SockTransport::Socket::Socket(SInt32 sock)
   : m_socket(sock)
{
}

SockTransport::Socket::~Socket()
{
}

void SockTransport::Socket::listen(SInt32 port, SInt32 max_pending)
{
   SInt32 err;

   LOG_ASSERT_ERROR(m_socket == -1, "Listening on already-open socket: %d", m_socket);

   m_socket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   LOG_ASSERT_ERROR(m_socket >= 0, "Failed to create socket.");

   SInt32 on = 1;
   err = ::setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
   LOG_ASSERT_ERROR(err >= 0, "Failed to set socket options.");

// Not needed
//    err = fcntl(m_server_socket, F_SETFL, O_NONBLOCK);
//    LOG_ASSERT_ERROR(err >= 0, "Failed to set non-blocking.");

   struct sockaddr_in addr;
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = INADDR_ANY;
   addr.sin_port = htons(port);

   err = ::bind(m_socket,
                (struct sockaddr *) &addr,
                sizeof(addr));
   LOG_ASSERT_ERROR(err >= 0, "Failed to bind");

   err = ::listen(m_socket,
                  max_pending);
   LOG_ASSERT_ERROR(err >= 0, "Failed to listen.");

   LOG_PRINT("Listening on socket: %d", m_socket);
}

SockTransport::Socket SockTransport::Socket::accept()
{
   struct sockaddr_in client;
   UInt32 client_len;
   SInt32 sock;

   memset(&client, 0, sizeof(client));
   client_len = sizeof(client);

   sock = ::accept(m_socket,
                   (struct sockaddr *)&client,
                   &client_len);
   LOG_ASSERT_ERROR(sock >= 0, "Failed to accept.");

   LOG_PRINT("Accepted connection %d on socket %d", sock, m_socket);

   return Socket(sock);
}

void SockTransport::Socket::connect(const char* addr, SInt32 port)
{
   SInt32 err;

   LOG_ASSERT_ERROR(m_socket == -1, "Connecting on already-open socket: %d", m_socket);

   // create socket
   m_socket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   LOG_ASSERT_ERROR(m_socket >= 0, "Failed to create socket -- addr: %s, port: %d.", addr, port);

   // connect
   struct sockaddr_in saddr;
   memset(&saddr, 0, sizeof(saddr));
   saddr.sin_family = AF_INET;
   saddr.sin_addr.s_addr = inet_addr(addr);
   saddr.sin_port = htons(port);

   err = ::connect(m_socket, (struct sockaddr *)&saddr, sizeof(saddr));
   LOG_ASSERT_ERROR(err >= 0, "Failed to connect -- addr: %s, port: %d", addr, port);

   LOG_PRINT("Connected on socket %d to %s:%d", m_socket, addr, port);
}

void SockTransport::Socket::send(const void* buffer, UInt32 length)
{
   SInt32 sent;
   sent = ::send(m_socket, buffer, length, 0);
   LOG_ASSERT_ERROR(UInt32(sent) == length, "Failure sending packet on socket %d -- %d != %d", m_socket, sent, length);
}

bool SockTransport::Socket::recv(void *buffer, UInt32 length, bool block)
{
   SInt32 recvd;

   while (true)
   {
      recvd = ::recv(m_socket, buffer, length, MSG_DONTWAIT);

      if (recvd >= 1)
      {
         if (recvd < SInt32(length))
         {
            buffer = (void*)((Byte*)buffer + recvd);
            length -= recvd;

            // block to receive remainder of message
            recvd = ::recv(m_socket, buffer, length, 0);
         }

         LOG_ASSERT_ERROR(UInt32(recvd) == length,
                          "Didn't receive full message on socket %d -- %d != %d",
                          m_socket, recvd, length);
         return true;
      }
      else
      {
         if (!block)
         {
            return false;
         }
         else
         {
            sched_yield();
         }
      }
   }
}

void SockTransport::Socket::close()
{
   LOG_PRINT("Closing socket: %d", m_socket);

   SInt32 err;
   err = ::close(m_socket);
   LOG_ASSERT_WARNING(err >= 0, "Failed to close socket: %d", err);

   m_socket = -1;
}
<commit_msg>[trans/sock] Block in connect. Close listening socket last.<commit_after>#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <mpi.h>
#include <fcntl.h>
#include <sched.h>

#include "log.h"
#include "config.h"

#include "socktransport.h"

SockTransport::SockTransport()
{
   getProcInfo();
   initSockets();
   initBufferLists();

   m_global_node = new SockNode(GLOBAL_TAG, this);
}

void SockTransport::getProcInfo()
{
   SInt32 err;

   LOG_PRINT("getProcInfo()");

   err = MPI_Init(NULL, NULL);
   LOG_ASSERT_ERROR(err == MPI_SUCCESS, "MPI_Init_thread fail.");

   err = MPI_Comm_size(MPI_COMM_WORLD, &m_num_procs);
   LOG_ASSERT_ERROR(err == MPI_SUCCESS, "MPI_Comm_size fail.");
   LOG_ASSERT_ERROR(m_num_procs == (SInt32)Config::getSingleton()->getProcessCount(), "Config no. processes doesn't match MPI no. processes.");

   err = MPI_Comm_rank(MPI_COMM_WORLD, &m_proc_index);
   LOG_ASSERT_ERROR(err == MPI_SUCCESS, "MPI_Comm_rank fail.");

   Config::getSingleton()->setProcessNum(m_proc_index);
   LOG_PRINT("Process number set to %i", Config::getSingleton()->getCurrentProcessNum());
}

void SockTransport::initSockets()
{
   SInt32 my_port;

   LOG_PRINT("initSockets()");

   // -- server side
   my_port = BASE_PORT + m_proc_index;
   m_server_socket.listen(my_port, m_num_procs);

   // -- client side
   m_send_sockets = new Socket[m_num_procs];
   for (SInt32 proc = 0; proc < m_num_procs; proc++)
   {
      m_send_sockets[proc].connect("127.0.0.1", // FIXME: assume single machine
                                   BASE_PORT + proc);

      m_send_sockets[proc].send(&m_proc_index, sizeof(m_proc_index));
   }

   // -- accept connections
   m_recv_sockets = new Socket[m_num_procs];
   m_recv_locks = new Lock[m_num_procs];

   for (SInt32 proc = 0; proc < m_num_procs; proc++)
   {
      Socket sock = m_server_socket.accept();

      SInt32 proc_index;
      sock.recv(&proc_index, sizeof(proc_index), true);

      LOG_ASSERT_ERROR(0 <= proc_index && proc_index < m_num_procs,
                       "Connected process out of range: %d",
                       proc_index);

      m_recv_sockets[proc_index] = sock;
   }
}

void SockTransport::initBufferLists()
{
   m_num_lists
      = Config::getSingleton()->getTotalCores() // for cores
      + 1; // for global node

   m_buffer_lists = new buffer_list[m_num_lists];
   m_buffer_locks = new Lock[m_num_lists];
}

void SockTransport::updateBufferLists()
{
   for (SInt32 i = 0; i < m_num_procs; i++)
   {
      while (true)
      {
         UInt32 length;

         m_recv_locks[i].acquire();

         // first get packet length, abort if none available
         if (!m_recv_sockets[i].recv(&length, sizeof(length), false))
         {
            m_recv_locks[i].release();
            break;
         }

         // now receive packet
         SInt32 tag;
         m_recv_sockets[i].recv(&tag, sizeof(tag), true);

         Byte *buffer = new Byte[length];
         m_recv_sockets[i].recv(buffer, length, true);

         m_recv_locks[i].release();

         if (tag == GLOBAL_TAG)
            tag = m_num_lists - 1;

         m_buffer_locks[tag].acquire();
         m_buffer_lists[tag].push_back(buffer);
         m_buffer_locks[tag].release();
      }
   }
}

SockTransport::~SockTransport()
{
   LOG_PRINT("dtor");

   delete m_global_node;

   delete [] m_buffer_locks;
   delete [] m_buffer_lists;

   for (SInt32 i = 0; i < m_num_procs; i++)
   {
      m_recv_sockets[i].close();
      m_send_sockets[i].close();
   }
   m_server_socket.close();

   delete [] m_recv_locks;
   delete [] m_recv_sockets;
   delete [] m_send_sockets;
}

Transport::Node* SockTransport::createNode(core_id_t core_id)
{
   return new SockNode(core_id, this);
}

void SockTransport::barrier()
{
   // FIXME: implement
}

Transport::Node* SockTransport::getGlobalNode()
{
   return m_global_node;
}

// -- SockTransport::SockNode

SockTransport::SockNode::SockNode(core_id_t core_id, SockTransport *trans)
   : Node(core_id)
   , m_transport(trans)
{
}

SockTransport::SockNode::~SockNode()
{
}

void SockTransport::SockNode::globalSend(SInt32 dest_proc,
                                         const void *buffer,
                                         UInt32 length)
{
   send(dest_proc, GLOBAL_TAG, buffer, length);
}

void SockTransport::SockNode::send(core_id_t dest_core,
                                   const void *buffer,
                                   UInt32 length)
{
   int dest_proc = Config::getSingleton()->getProcessNumForCore(dest_core);
   send(dest_proc, dest_core, buffer, length);
}

Byte* SockTransport::SockNode::recv()
{
   LOG_PRINT("Entering recv");

   core_id_t tag = getCoreId();
   tag = (tag == GLOBAL_TAG) ? m_transport->m_num_lists - 1 : tag;

   buffer_list &list = m_transport->m_buffer_lists[tag];
   Lock &lock = m_transport->m_buffer_locks[tag];

   while (true)
   {
      m_transport->updateBufferLists();

      lock.acquire();

      if (!list.empty())
      {
         Byte *buffer = list.front();
         list.pop_front();
         lock.release();

         LOG_PRINT("Message recv'd");

         return buffer;
      }
      else
      {
         lock.release();
         sched_yield();
      }
   }
}

bool SockTransport::SockNode::query()
{
   m_transport->updateBufferLists();

   core_id_t tag = getCoreId();
   tag = (tag == GLOBAL_TAG) ? m_transport->m_num_lists - 1 : tag;

   buffer_list &list = m_transport->m_buffer_lists[tag];
   Lock &lock = m_transport->m_buffer_locks[tag];

   lock.acquire();
   bool result = !list.empty();
   lock.release();
   return result;
}

void SockTransport::SockNode::send(SInt32 dest_proc,
                                   UInt32 tag,
                                   const void *buffer,
                                   UInt32 length)
{
   SInt32 pkt_len = length + sizeof(tag) + sizeof(length);

   Byte *pkt_buff = new Byte[pkt_len];

   Packet *p = (Packet*)pkt_buff;
   p->length = length;
   p->tag = tag;
   memcpy(&p->data, buffer, length);

   m_transport->m_send_sockets[dest_proc].send(pkt_buff, pkt_len);

   LOG_PRINT("Message sent.");

   delete [] pkt_buff;
}

// -- Socket

SockTransport::Socket::Socket()
   : m_socket(-1)
{
}

SockTransport::Socket::Socket(SInt32 sock)
   : m_socket(sock)
{
}

SockTransport::Socket::~Socket()
{
}

void SockTransport::Socket::listen(SInt32 port, SInt32 max_pending)
{
   SInt32 err;

   LOG_ASSERT_ERROR(m_socket == -1, "Listening on already-open socket: %d", m_socket);

   m_socket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   LOG_ASSERT_ERROR(m_socket >= 0, "Failed to create socket.");

   SInt32 on = 1;
   err = ::setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
   LOG_ASSERT_ERROR(err >= 0, "Failed to set socket options.");

// Not needed
//    err = fcntl(m_server_socket, F_SETFL, O_NONBLOCK);
//    LOG_ASSERT_ERROR(err >= 0, "Failed to set non-blocking.");

   struct sockaddr_in addr;
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = INADDR_ANY;
   addr.sin_port = htons(port);

   err = ::bind(m_socket,
                (struct sockaddr *) &addr,
                sizeof(addr));
   LOG_ASSERT_ERROR(err >= 0, "Failed to bind");

   err = ::listen(m_socket,
                  max_pending);
   LOG_ASSERT_ERROR(err >= 0, "Failed to listen.");

   LOG_PRINT("Listening on socket: %d", m_socket);
}

SockTransport::Socket SockTransport::Socket::accept()
{
   struct sockaddr_in client;
   UInt32 client_len;
   SInt32 sock;

   memset(&client, 0, sizeof(client));
   client_len = sizeof(client);

   sock = ::accept(m_socket,
                   (struct sockaddr *)&client,
                   &client_len);
   LOG_ASSERT_ERROR(sock >= 0, "Failed to accept.");

   LOG_PRINT("Accepted connection %d on socket %d", sock, m_socket);

   return Socket(sock);
}

void SockTransport::Socket::connect(const char* addr, SInt32 port)
{
   SInt32 err;

   LOG_ASSERT_ERROR(m_socket == -1, "Connecting on already-open socket: %d", m_socket);

   // create socket
   m_socket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   LOG_ASSERT_ERROR(m_socket >= 0, "Failed to create socket -- addr: %s, port: %d.", addr, port);

   // connect
   struct sockaddr_in saddr;
   memset(&saddr, 0, sizeof(saddr));
   saddr.sin_family = AF_INET;
   saddr.sin_addr.s_addr = inet_addr(addr);
   saddr.sin_port = htons(port);

   while (true)
   {
      err = ::connect(m_socket, (struct sockaddr *)&saddr, sizeof(saddr));

      //LOG_ASSERT_ERROR(err >= 0, "Failed to connect -- addr: %s, port: %d", addr, port);

      if (err >= 0)
         break;
      else
         sched_yield();
   }

   LOG_PRINT("Connected on socket %d to %s:%d", m_socket, addr, port);
}

void SockTransport::Socket::send(const void* buffer, UInt32 length)
{
   SInt32 sent;
   sent = ::send(m_socket, buffer, length, 0);
   LOG_ASSERT_ERROR(UInt32(sent) == length, "Failure sending packet on socket %d -- %d != %d", m_socket, sent, length);
}

bool SockTransport::Socket::recv(void *buffer, UInt32 length, bool block)
{
   SInt32 recvd;

   while (true)
   {
      recvd = ::recv(m_socket, buffer, length, MSG_DONTWAIT);

      if (recvd >= 1)
      {
         if (recvd < SInt32(length))
         {
            buffer = (void*)((Byte*)buffer + recvd);
            length -= recvd;

            // block to receive remainder of message
            recvd = ::recv(m_socket, buffer, length, 0);
         }

         LOG_ASSERT_ERROR(UInt32(recvd) == length,
                          "Didn't receive full message on socket %d -- %d != %d",
                          m_socket, recvd, length);
         return true;
      }
      else
      {
         if (!block)
         {
            return false;
         }
         else
         {
            sched_yield();
         }
      }
   }
}

void SockTransport::Socket::close()
{
   LOG_PRINT("Closing socket: %d", m_socket);

   SInt32 err;
   err = ::close(m_socket);
   LOG_ASSERT_WARNING(err >= 0, "Failed to close socket: %d", err);

   m_socket = -1;
}
<|endoftext|>


<commit_before>#include "ofApp.h"

//step the turing machine and return new symbol
int ofApp::step(turing_machine &t){
    auto result = delta(t);
    t.state = get<0>(result);
    t.tape[t.index] = get<1>(result);
    t.index += (int(get<2>(result)) - int(1<<bits)/2)/jump_div;
    t.index = (t.index + tape_length) % tape_length;
    return t.tape[t.index];
}
//define the program
tuple<unsigned char, unsigned char, unsigned char> ofApp::delta(turing_machine &t){
    unsigned char new_state, new_symbol, jump;
    int address = getAddress(t);
    //address %= program_length;
    new_state = t.program[address];
    new_symbol = t.program[address+1];
    jump = t.program[address+2];
    return make_tuple(new_state, new_symbol, jump);
}

//get address of instruction for current state
int ofApp::getAddress(turing_machine &t){
    //return (t.state + (int(t.tape[t.index])<<bits))<<1;
    return 3*(t.tape[t.index] + (int(t.state)<<bits));
}

unsigned char ofApp::random(){
    unsigned char ret = rand();
    return ret>>(8-bits);
    //return ofRandom((1<<bits) + 1);
}

void ofApp::randomize_state(turing_machine &t){
    t.state = random();
}

void ofApp::randomize_index(turing_machine &t){
    t.index = rand() % tape_length;
}

void ofApp::randomize_tape(turing_machine &t){
    if(print) cout<<"randomizing tape: ";
    for(int i=0; i<tape_length; i++){
        t.tape[i] = random();
        if(print) cout<<t.tape[i];
    }
    if(print) cout<<endl;
}

void ofApp::randomize_instruction(turing_machine &t){
    int address = getAddress(t);
    //address %= program_length;
    t.program[address] = random();
    t.program[address+1] = random();
    t.program[address+2] = random();
}

void ofApp::audioOut(float * output, int bufferSize, int nChannels){
    for(int i=0; i<bufferSize; i++){
        for(int c=0; c<nChannels; c++){
            output[nChannels*i+c] = float(step(tm[c]))/(1<<bits) - .5;;
        }
    }
}

//--------------------------------------------------------------
void ofApp::setup(){
    for(int i=0; i<2; i++){
        turing_machine t;
        t.tape = (unsigned char*)calloc(tape_length,sizeof(unsigned char));
        t.state = 0;
        t.index = 0;
        tm.push_back(t);
    }
    tm[0].program = tm[1].tape;
    tm[1].program = tm[0].tape;

    int channels = 2;
    int sample_rate = 48000;
    ofSoundStreamListDevices();
    ss.setDeviceID(3);
    ss.setup(this, channels, 0, sample_rate, 256, 4);

    print = false;

    ofSetMinMagFilters(GL_NEAREST, GL_NEAREST);
}

void ofApp::close(){
    ss.close();
}

//--------------------------------------------------------------
void ofApp::update(){
    stringstream ss;
    ss << ofGetFrameRate();
    ofSetWindowTitle(ss.str());
   // int s = step();
   if(print)
        cout<<"symbol: "<<tm[0].tape[tm[0].index]<<", state: "<<tm[0].state<<endl;
}

//--------------------------------------------------------------
void ofApp::draw(){
    int ww = ofGetWindowWidth(), wh = ofGetWindowHeight();
    int n = tm.size();
    for(int i=0; i<n; i++){
        ofPixels pix;
        pix.setFromExternalPixels(tm[i].tape, 1<<bits, 1<<bits, 3);
        //int address = getAddress(tm[1-i]);
        ofImage img(pix);
        //img.getPixelsRef().resize(ww/n, wh, OF_INTERPOLATE_NEAREST_NEIGHBOR);
        //img.setColor(address, ofColor(255));
        img.update();
        //img.setColor(address, ofColor(0,0,255));
        img.draw(ww/n*i,0,ww/n, wh);
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if(key == 'r'){
        cout<<"randomizing tapes"<<endl;
        for(auto i = tm.begin(); i<tm.end(); i++)
            randomize_tape(*i);
    }
    if(key == 's'){
        cout<<"randomizing states: ";
        for(auto i = tm.begin(); i<tm.end(); i++){
            randomize_state(*i);
            cout<<i->state<<" "<<endl;
        }
    }
    if(key == 'p'){
        cout<<"randomizing indeces: ";
        for(auto i = tm.begin(); i<tm.end(); i++){
            randomize_index(*i);
            cout<<i->index<<" "<<endl;
        }
    }
    if(key == 'i'){
        for(auto i = tm.begin(); i<tm.end(); i++)
            randomize_instruction(*i);
    }
    if(key == 'p'){
        print = !print;
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>small fixes<commit_after>#include "ofApp.h"

//step the turing machine and return new symbol
int ofApp::step(turing_machine &t){
    auto result = delta(t);
    t.state = get<0>(result);
    t.tape[t.index] = get<1>(result);
    t.index += (int(get<2>(result)) - int(1<<bits)/2)/jump_div;
    t.index = (t.index + tape_length) % tape_length;
    return t.tape[t.index];
}
//define the program
tuple<unsigned char, unsigned char, unsigned char> ofApp::delta(turing_machine &t){
    unsigned char new_state, new_symbol, jump;
    int address = getAddress(t);
    //address %= program_length;
    new_state = t.program[address];
    new_symbol = t.program[address+1];
    jump = t.program[address+2];
    return make_tuple(new_state, new_symbol, jump);
}

//get address of instruction for current state
int ofApp::getAddress(turing_machine &t){
    //return (t.state + (int(t.tape[t.index])<<bits))<<1;
    return 3*(t.tape[t.index] + (int(t.state)<<bits));
}

unsigned char ofApp::random(){
    unsigned char ret = rand();
    return ret>>(8-bits);
    //return ofRandom((1<<bits) + 1);
}

void ofApp::randomize_state(turing_machine &t){
    t.state = random();
}

void ofApp::randomize_index(turing_machine &t){
    t.index = rand() % tape_length;
}

void ofApp::randomize_tape(turing_machine &t){
    if(print) cout<<"randomizing tape: ";
    for(int i=0; i<tape_length; i++){
        t.tape[i] = random();
        if(print) cout<<t.tape[i];
    }
    if(print) cout<<endl;
}

void ofApp::randomize_instruction(turing_machine &t){
    int address = getAddress(t);
    //address %= program_length;
    t.program[address] = random();
    t.program[address+1] = random();
    t.program[address+2] = random();
}

void ofApp::audioOut(float * output, int bufferSize, int nChannels){
    for(int i=0; i<bufferSize; i++){
        for(int c=0; c<nChannels; c++){
            output[nChannels*i+c] = float(step(tm[c]))/(1<<bits) - .5;;
        }
    }
}

//--------------------------------------------------------------
void ofApp::setup(){
    for(int i=0; i<2; i++){
        turing_machine t;
        t.tape = (unsigned char*)calloc(tape_length,sizeof(unsigned char));
        t.state = 0;
        t.index = 0;
        tm.push_back(t);
    }
    tm[0].program = tm[1].tape;
    tm[1].program = tm[0].tape;

    int channels = 2;
    int sample_rate = 48000;
    ofSoundStreamListDevices();
    ss.setDeviceID(3);
    ss.setup(this, channels, 0, sample_rate, 256, 4);

    print = false;

    ofSetMinMagFilters(GL_NEAREST, GL_NEAREST);
}

void ofApp::close(){
    ss.close();
}

//--------------------------------------------------------------
void ofApp::update(){
    stringstream ss;
    ss << ofGetFrameRate();
    ofSetWindowTitle(ss.str());
   // int s = step();
   if(print)
        cout<<"symbol: "<<tm[0].tape[tm[0].index]<<", state: "<<tm[0].state<<endl;
}

//--------------------------------------------------------------
void ofApp::draw(){
    int ww = ofGetWindowWidth(), wh = ofGetWindowHeight();
    int n = tm.size();
    for(int i=0; i<n; i++){
        ofPixels pix;
        pix.setFromExternalPixels(tm[i].tape, 1<<bits, 1<<bits, 3);
        ofImage img(pix);
        //int address = getAddress(tm[1-i]);
        //img.setColor(address, ofColor(255));
        //img.update();
        img.draw(ww/n*i,0,ww/n, wh);
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if(key == 'r'){
        cout<<"randomizing tapes"<<endl;
        for(auto i = tm.begin(); i<tm.end(); i++)
            randomize_tape(*i);
    }
    if(key == 's'){
        cout<<"randomizing states: ";
        for(auto i = tm.begin(); i<tm.end(); i++){
            randomize_state(*i);
            cout<<i->state<<" "<<endl;
        }
    }
    if(key == 'p'){
        cout<<"randomizing indeces: ";
        for(auto i = tm.begin(); i<tm.end(); i++){
            randomize_index(*i);
            cout<<i->index<<" "<<endl;
        }
    }
    if(key == 'i'){
        for(auto i = tm.begin(); i<tm.end(); i++)
            randomize_instruction(*i);
    }
    //if(key == 't'){
    //    print = !print;
    //}
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>#include "ofApp.h"

#define kVolHistorySize (400)
#define kNumberOfBands (32)

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0, 0, 0);

    loudest_band_ = 0;

    sample_rate_ = 44100;

    // 0 output channels,
    // 2 input channels
    // 44100 samples per second
    // N samples per buffer
    // 4 num buffers (latency)
    ofSoundStreamSetup(0, 2, this, sample_rate_, beat_.getBufferSize(), 4);

    font_.loadFont("Batang.ttf", 160, true, true, true);

    gist_.setUseForOnsetDetection(GIST_PEAK_ENERGY);
    gist_.setThreshold(GIST_PEAK_ENERGY, .05);

    // Volume
    left.assign(beat_.getBufferSize(), 0.0);
    right.assign(beat_.getBufferSize(), 0.0);
    vol_history_.assign(kVolHistorySize, 0.0);
    current_vol_ = 0;
    smoothed_vol_     = 0.0;
    scaled_vol_		= 0.0;

    // Enable beat detection
    beat_.enableBeatDetect();

    // Listen to Gist events
    ofAddListener(GistEvent::ON,this,&ofApp::onNoteOn);
    ofAddListener(GistEvent::OFF,this,&ofApp::onNoteOff);

    // onset detection
    onset_decay_rate_ = 0.05;
    onset_minimum_threshold_ = 0.1;
    onset_threshold_ = onset_minimum_threshold_;

    setup_done_ = true;
}

//--------------------------------------------------------------
void ofApp::update(){
    beat_.update(ofGetElapsedTimeMillis());

    //lets scale the vol up to a 0-1 range
    scaled_vol_ = ofMap(smoothed_vol_, 0.0, 0.17, 0.0, 1.0, true);

    //lets record the volume into an array
    vol_history_.push_back(scaled_vol_);

    //if we are bigger the the size we want to record - lets drop the oldest value
    if( vol_history_.size() >= kVolHistorySize ){
        vol_history_.erase(vol_history_.begin(), vol_history_.begin()+1);
    }

    // find loudest band
    float max = 0;
    int new_loudest = -1;
    for (int i = 0; i < kNumberOfBands; i++) {
        float selectedBand = beat_.getBand(i);
        if (selectedBand > max) {
            max = selectedBand;
            new_loudest = i;
        }
    }
    loudest_band_ = new_loudest;
}

//--------------------------------------------------------------
void ofApp::draw(){
    // Draw black background
    ofSetColor(255, 255, 255);
    ofFill();

    if (draw_hud_) {
        drawHUD();
    }
}

void ofApp::drawHUD() {
    // draw debug variables
    ofDrawBitmapString("onset threshold: "+ofToString(onset_threshold_), 10, 20);
    ofDrawBitmapString("kick: "+ofToString(beat_.kick()), 10, 40);
    ofDrawBitmapString("snare: "+ofToString(beat_.snare()), 10, 60);
    ofDrawBitmapString("hihat: "+ofToString(beat_.hihat()), 10, 80);
    ofDrawBitmapString("current vol: "+ofToString(current_vol_), 10, 100);
    ofDrawBitmapString("smoothed vol: "+ofToString(smoothed_vol_), 10, 120);

    // kick bar
    ofSetColor(102, 102, 255);
    ofNoFill();
    ofRect(150, 30, 100, 10);
    ofFill();
    ofRect(150, 30, ofMap(beat_.kick(), 0, 1, 0, 100), 10);

    // snare bar
    ofSetColor(102, 102, 255);
    ofNoFill();
    ofRect(150, 50, 100, 10);
    ofFill();
    ofRect(150, 50, ofMap(beat_.snare(), 0, 1, 0, 100), 10);

    // hihat bar
    ofSetColor(102, 102, 255);
    ofNoFill();
    ofRect(150, 70, 100, 10);
    ofFill();
    ofRect(150, 70, ofMap(beat_.hihat(), 0, 1, 0, 100), 10);

    ofSetColor(255, 255, 255);

    ofDrawBitmapString("GIST ONSET EVENT", 300, 20);
    ofDrawBitmapString("energy: "+ofToString(gist_event_energy_), 300, 40);
    ofDrawBitmapString("frequency: "+ofToString(gist_event_frequency_), 300, 60);
    ofDrawBitmapString("onset amount: "+ofToString(gist_event_onset_amount_), 300, 80);
    ofDrawBitmapString("note on: "+ofToString(gist_event_note_on_), 300, 100);

    ofDrawBitmapString("press 'h' to toggle HUD", 300, 140);

    ofPushStyle();
    ofSetRectMode(OF_RECTMODE_CORNER);
    ofSetLineWidth(2);
    const int kVolumeRange = 1;
    for (int i = 0; i < kNumberOfBands; i++) {
        float selectedBand = beat_.getBand(i);

        ofSetColor(255, 255, 255);

        float hz = ((i+1) * sample_rate_) / beat_.getBufferSize();
        std::string text = ofToString(i) + ") " + ofToString(hz) + " hz " + ofToString(selectedBand);
        ofDrawBitmapString(text, 10, 140 + (20*i));

        if (i== loudest_band_) {
            ofSetColor(255, 0, 10);
        } else {
            ofSetColor(51, 204, 51);
        }
        if (beat_.isBeat(i)) {
            ofFill();
        } else {
            ofNoFill();
        }
        float x = ofGetWidth()*((float)i/kNumberOfBands);
        float y = ofGetHeight()-20;
        float w = ofGetWidth()/kNumberOfBands;
        float h = -ofMap(selectedBand, 0, kVolumeRange, 0, ofGetHeight() / 10);
        ofRect(x, y, w, h);
    }
    ofPopStyle();

    ofNoFill();

    // draw the left channel:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 20, 0);

    ofSetColor(225);
    ofDrawBitmapString("Left Channel", 4, 18);

    ofSetLineWidth(1);
    ofRect(0, 0, 440, 200);

    ofSetColor(245, 58, 135);
    ofSetLineWidth(3);

    ofBeginShape();
    for (unsigned int i = 0; i < left.size(); i++){
        ofVertex(i*2, 100 -left[i]*180.0f);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();

    // draw the right channel:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 220, 0);

    ofSetColor(225);
    ofDrawBitmapString("Right Channel", 4, 18);

    ofSetLineWidth(1);
    ofRect(0, 0, 440, 200);

    ofSetColor(245, 58, 135);
    ofSetLineWidth(3);

    ofBeginShape();
    for (unsigned int i = 0; i < right.size(); i++){
        ofVertex(i*2, 100 -right[i]*180.0f);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();

    // draw the average volume:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 420, 0);

    ofSetColor(225);
    ofDrawBitmapString("Scaled average vol (0-100): " + ofToString(scaled_vol_ * 100.0, 0), 4, 18);

    ofSetColor(245, 58, 135);
    ofCircle(200, 100, scaled_vol_ * 100.0f);

    //lets draw the volume history as a graph
    ofBeginShape();
    for (unsigned int i = 0; i < vol_history_.size(); i++){
        if( i == 0 ) ofVertex(i, 300);

        ofVertex(i, 300 - vol_history_[i] * 70);

        if( i == vol_history_.size() -1 ) ofVertex(i, 300);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();
}

void ofApp::audioReceived(float* input, int bufferSize, int nChannels) {
    if (!setup_done_) {
        return;
    }

    beat_.audioReceived(input, bufferSize, channel_count_);

    channel_count_ = nChannels;

    //convert float array to vector
    vector<float>buffer;
    buffer.assign(&input[0],&input[bufferSize]);
    gist_.processAudio(buffer, bufferSize, nChannels, sample_rate_);

    calculateVolume(input, bufferSize);

    // detect onset
    onset_threshold_ = ofLerp(onset_threshold_, onset_minimum_threshold_, onset_decay_rate_);
    if (current_vol_ > onset_threshold_) {
        // onset detected!
        onset_threshold_ = current_vol_;
    }
}

void ofApp::calculateVolume(float *input, int bufferSize) {
    // samples are "interleaved"
    int numCounted = 0;

    //lets go through each sample and calculate the root mean square which is a rough way to calculate volume
    for (int i = 0; i < bufferSize; i++){
        left[i]		= input[i*2]*0.5;
        right[i]	= input[i*2+1]*0.5;

        current_vol_ += left[i] * left[i];
        current_vol_ += right[i] * right[i];
        numCounted+=2;
    }

    //this is how we get the mean of rms :)
    current_vol_ /= (float)numCounted;

    // this is how we get the root of rms :)
    current_vol_ = sqrt( current_vol_ );

    smoothed_vol_ *= 0.93;
    smoothed_vol_ += 0.07 * current_vol_;
}

void ofApp::onNoteOn(GistEvent &e){
    gist_event_energy_ = e.energy;
    gist_event_frequency_ = e.frequency;
    gist_event_note_ = e.note;
    gist_event_onset_amount_ = e.onsetAmount;

    gist_event_note_on_ = true;
};

void ofApp::onNoteOff(GistEvent &e){
    gist_event_energy_ = e.energy;
    gist_event_frequency_ = e.frequency;
    gist_event_note_ = e.note;
    gist_event_onset_amount_ = e.onsetAmount;

    gist_event_note_on_ = false;
};

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if ('h' == key) {
        draw_hud_ = !draw_hud_;
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}<commit_msg>print out all gist features<commit_after>#include "ofApp.h"

#define kVolHistorySize (400)
#define kNumberOfBands (32)

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0, 0, 0);

    loudest_band_ = 0;

    sample_rate_ = 44100;

    // 0 output channels,
    // 2 input channels
    // 44100 samples per second
    // N samples per buffer
    // 4 num buffers (latency)
    ofSoundStreamSetup(0, 2, this, sample_rate_, beat_.getBufferSize(), 4);

    font_.loadFont("Batang.ttf", 160, true, true, true);

    gist_.setUseForOnsetDetection(GIST_PEAK_ENERGY);
    gist_.setThreshold(GIST_PEAK_ENERGY, .05);

    gist_.setDetect(GIST_PITCH);
    gist_.setDetect(GIST_NOTE);
    gist_.setDetect(GIST_ROOT_MEAN_SQUARE);
    gist_.setDetect(GIST_PEAK_ENERGY);
    gist_.setDetect(GIST_SPECTRAL_CREST);
    gist_.setDetect(GIST_ZERO_CROSSING_RATE);
    gist_.setDetect(GIST_SPECTRAL_CENTROID);
    gist_.setDetect(GIST_SPECTRAL_FLATNESS);
    gist_.setDetect(GIST_SPECTRAL_DIFFERENCE);
    gist_.setDetect(GIST_SPECTRAL_DIFFERENCE_COMPLEX);
    gist_.setDetect(GIST_SPECTRAL_DIFFERENCE_HALFWAY);
    gist_.setDetect(GIST_HIGH_FREQUENCY_CONTENT);

    // Volume
    left.assign(beat_.getBufferSize(), 0.0);
    right.assign(beat_.getBufferSize(), 0.0);
    vol_history_.assign(kVolHistorySize, 0.0);
    current_vol_ = 0;
    smoothed_vol_     = 0.0;
    scaled_vol_		= 0.0;

    // Enable beat detection
    beat_.enableBeatDetect();

    // Listen to Gist events
    ofAddListener(GistEvent::ON,this,&ofApp::onNoteOn);
    ofAddListener(GistEvent::OFF,this,&ofApp::onNoteOff);

    // onset detection
    onset_decay_rate_ = 0.05;
    onset_minimum_threshold_ = 0.1;
    onset_threshold_ = onset_minimum_threshold_;

    setup_done_ = true;
}

//--------------------------------------------------------------
void ofApp::update(){
    beat_.update(ofGetElapsedTimeMillis());

    //lets scale the vol up to a 0-1 range
    scaled_vol_ = ofMap(smoothed_vol_, 0.0, 0.17, 0.0, 1.0, true);

    //lets record the volume into an array
    vol_history_.push_back(scaled_vol_);

    //if we are bigger the the size we want to record - lets drop the oldest value
    if( vol_history_.size() >= kVolHistorySize ){
        vol_history_.erase(vol_history_.begin(), vol_history_.begin()+1);
    }

    // find loudest band
    float max = 0;
    int new_loudest = -1;
    for (int i = 0; i < kNumberOfBands; i++) {
        float selectedBand = beat_.getBand(i);
        if (selectedBand > max) {
            max = selectedBand;
            new_loudest = i;
        }
    }
    loudest_band_ = new_loudest;
}

//--------------------------------------------------------------
void ofApp::draw(){
    // Draw black background
    ofSetColor(255, 255, 255);
    ofFill();

    if (draw_hud_) {
        drawHUD();
    }
}

void ofApp::drawHUD() {
    // FIXME: show beat ranges too (have couple of predefined ranges or
    // something, for example 0-10, 20-32 etc.

    // draw debug variables
    ofDrawBitmapString("onset threshold: "+ofToString(onset_threshold_), 10, 20);
    ofDrawBitmapString("kick: "+ofToString(beat_.kick()), 10, 40);
    ofDrawBitmapString("snare: "+ofToString(beat_.snare()), 10, 60);
    ofDrawBitmapString("hihat: "+ofToString(beat_.hihat()), 10, 80);
    ofDrawBitmapString("current vol: "+ofToString(current_vol_), 10, 100);
    ofDrawBitmapString("smoothed vol: "+ofToString(smoothed_vol_), 10, 120);

    // kick bar
    ofSetColor(102, 102, 255);
    ofNoFill();
    ofRect(150, 30, 100, 10);
    ofFill();
    ofRect(150, 30, ofMap(beat_.kick(), 0, 1, 0, 100), 10);

    // snare bar
    ofSetColor(102, 102, 255);
    ofNoFill();
    ofRect(150, 50, 100, 10);
    ofFill();
    ofRect(150, 50, ofMap(beat_.snare(), 0, 1, 0, 100), 10);

    // hihat bar
    ofSetColor(102, 102, 255);
    ofNoFill();
    ofRect(150, 70, 100, 10);
    ofFill();
    ofRect(150, 70, ofMap(beat_.hihat(), 0, 1, 0, 100), 10);

    // Draw Gist onset event info
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("GIST ONSET EVENT", 300, 20);
    ofDrawBitmapString("energy: "+ofToString(gist_event_energy_), 300, 40);
    ofDrawBitmapString("frequency: "+ofToString(gist_event_frequency_), 300, 60);
    ofDrawBitmapString("onset amount: "+ofToString(gist_event_onset_amount_), 300, 80);
    ofDrawBitmapString("note on: "+ofToString(gist_event_note_on_), 300, 100);

    // Key hints
    ofDrawBitmapString("press 'h' to toggle HUD", 300, 140);

    // Draw Gist info
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("GIST FEATURES", 300, 180);
    ofDrawBitmapString("pitch: "+ofToString(gist_.getValue(GIST_PITCH)), 300, 200);
    ofDrawBitmapString("note: "+ofToString(gist_.getValue(GIST_NOTE)), 300, 220);
    ofDrawBitmapString("root mean square: "+ofToString(gist_.getValue(GIST_ROOT_MEAN_SQUARE)), 300, 240);
    ofDrawBitmapString("peak energy: "+ofToString(gist_.getValue(GIST_PEAK_ENERGY)), 300, 260);
    ofDrawBitmapString("special crest: "+ofToString(gist_.getValue(GIST_SPECTRAL_CREST)), 300, 280);
    ofDrawBitmapString("zero crossing rate: "+ofToString(gist_.getValue(GIST_ZERO_CROSSING_RATE)), 300, 300);
    ofDrawBitmapString("SPECTRAL FEATURES", 300, 320);
    ofDrawBitmapString("centroid: "+ofToString(gist_.getValue(GIST_SPECTRAL_CENTROID)), 300, 340);
    ofDrawBitmapString("flatness: "+ofToString(gist_.getValue(GIST_SPECTRAL_FLATNESS)), 300, 360);
    ofDrawBitmapString("difference: "+ofToString(gist_.getValue(GIST_SPECTRAL_DIFFERENCE)), 300, 380);
    ofDrawBitmapString("difference complex: "+ofToString(gist_.getValue(GIST_SPECTRAL_DIFFERENCE_COMPLEX)), 300, 400);
    ofDrawBitmapString("difference halfway: "+ofToString(gist_.getValue(GIST_SPECTRAL_DIFFERENCE_HALFWAY)), 300, 420);
    ofDrawBitmapString("high freq. content: "+ofToString(gist_.getValue(GIST_HIGH_FREQUENCY_CONTENT)), 300, 440);

    // Draw individual bands as bars, also show frequencies and values
    // for each band.
    ofPushStyle();
    ofSetRectMode(OF_RECTMODE_CORNER);
    ofSetLineWidth(2);
    const int kVolumeRange = 1;
    for (int i = 0; i < kNumberOfBands; i++) {
        float selectedBand = beat_.getBand(i);

        ofSetColor(255, 255, 255);

        float hz = ((i+1) * sample_rate_) / beat_.getBufferSize();
        std::string text = ofToString(i) + ") " + ofToString(hz) + " hz " + ofToString(selectedBand);
        ofDrawBitmapString(text, 10, 140 + (20*i));

        if (i== loudest_band_) {
            ofSetColor(255, 0, 10);
        } else {
            ofSetColor(51, 204, 51);
        }
        if (beat_.isBeat(i)) {
            ofFill();
        } else {
            ofNoFill();
        }
        float x = ofGetWidth()*((float)i/kNumberOfBands);
        float y = ofGetHeight()-20;
        float w = ofGetWidth()/kNumberOfBands;
        float h = -ofMap(selectedBand, 0, kVolumeRange, 0, ofGetHeight() / 10);
        ofRect(x, y, w, h);
    }
    ofPopStyle();

    ofNoFill();

    // draw the left channel:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 20, 0);

    ofSetColor(225);
    ofDrawBitmapString("Left Channel", 4, 18);

    ofSetLineWidth(1);
    ofRect(0, 0, 440, 200);

    ofSetColor(245, 58, 135);
    ofSetLineWidth(3);

    ofBeginShape();
    for (unsigned int i = 0; i < left.size(); i++){
        ofVertex(i*2, 100 -left[i]*180.0f);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();

    // draw the right channel:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 220, 0);

    ofSetColor(225);
    ofDrawBitmapString("Right Channel", 4, 18);

    ofSetLineWidth(1);
    ofRect(0, 0, 440, 200);

    ofSetColor(245, 58, 135);
    ofSetLineWidth(3);

    ofBeginShape();
    for (unsigned int i = 0; i < right.size(); i++){
        ofVertex(i*2, 100 -right[i]*180.0f);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();

    // draw the average volume:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 420, 0);

    ofSetColor(225);
    ofDrawBitmapString("Scaled average vol (0-100): " + ofToString(scaled_vol_ * 100.0, 0), 4, 18);

    ofSetColor(245, 58, 135);
    ofFill();
    ofCircle(200, 100, scaled_vol_ * 100.0f);

    //lets draw the volume history as a graph
    ofNoFill();
    ofBeginShape();
    for (unsigned int i = 0; i < vol_history_.size(); i++){
        if( i == 0 ) ofVertex(i, 300);

        ofVertex(i, 300 - vol_history_[i] * 70);

        if( i == vol_history_.size() -1 ) ofVertex(i, 300);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();
}

void ofApp::audioReceived(float* input, int bufferSize, int nChannels) {
    if (!setup_done_) {
        return;
    }

    beat_.audioReceived(input, bufferSize, channel_count_);

    channel_count_ = nChannels;

    //convert float array to vector
    vector<float>buffer;
    buffer.assign(&input[0],&input[bufferSize]);
    gist_.processAudio(buffer, bufferSize, nChannels, sample_rate_);

    calculateVolume(input, bufferSize);

    // detect onset
    onset_threshold_ = ofLerp(onset_threshold_, onset_minimum_threshold_, onset_decay_rate_);
    if (current_vol_ > onset_threshold_) {
        // onset detected!
        onset_threshold_ = current_vol_;
    }
}

void ofApp::calculateVolume(float *input, int bufferSize) {
    // samples are "interleaved"
    int numCounted = 0;

    //lets go through each sample and calculate the root mean square which is a rough way to calculate volume
    for (int i = 0; i < bufferSize; i++){
        left[i]		= input[i*2]*0.5;
        right[i]	= input[i*2+1]*0.5;

        current_vol_ += left[i] * left[i];
        current_vol_ += right[i] * right[i];
        numCounted+=2;
    }

    //this is how we get the mean of rms :)
    current_vol_ /= (float)numCounted;

    // this is how we get the root of rms :)
    current_vol_ = sqrt( current_vol_ );

    smoothed_vol_ *= 0.93;
    smoothed_vol_ += 0.07 * current_vol_;
}

void ofApp::onNoteOn(GistEvent &e){
    gist_event_energy_ = e.energy;
    gist_event_frequency_ = e.frequency;
    gist_event_note_ = e.note;
    gist_event_onset_amount_ = e.onsetAmount;

    gist_event_note_on_ = true;
};

void ofApp::onNoteOff(GistEvent &e){
    gist_event_energy_ = e.energy;
    gist_event_frequency_ = e.frequency;
    gist_event_note_ = e.note;
    gist_event_onset_amount_ = e.onsetAmount;

    gist_event_note_on_ = false;
};

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if ('h' == key) {
        draw_hud_ = !draw_hud_;
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}<|endoftext|>