<commit_before>///
/// @file   config.hpp
/// @brief  Macros, typedefs and constants that set various limits
///         and array sizes within primesieve.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef CONFIG_PRIMESIEVE_HPP
#define CONFIG_PRIMESIEVE_HPP

/// Include config.h generated by ./configure script
#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

/// Enable the UINT64_C() macro from <stdint.h>
#if !defined(__STDC_CONSTANT_MACROS)
  #define __STDC_CONSTANT_MACROS
#endif

#include <stdint.h>

/// Disable assert() macro
#if !defined(DEBUG) && !defined(NDEBUG)
  #define NDEBUG
#endif

/// Disable the default copy constructor and assignment operator
#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(ClassName) \
  ClassName(const ClassName&); \
  void operator=(const ClassName&)
#endif

/// Default CPU L1 data cache size in kilobytes (per core)
#ifndef L1_DCACHE_SIZE
  #define L1_DCACHE_SIZE 32
#endif

#ifndef SIEVESIZE
  #define SIEVESIZE L1_DCACHE_SIZE
#endif

namespace primesieve {

/// byte_t must be unsigned in primesieve
typedef unsigned char byte_t;
typedef unsigned int uint_t;

enum {
  /// SieveOfEratosthenes objects use a bit array with 30 numbers per
  /// byte for sieving, the 8 bits of each byte correspond to the
  /// offsets { 7, 11, 13, 17, 19, 23, 29, 31 }.
  ///
  NUMBERS_PER_BYTE = 30
};

namespace config {

enum {
  /// Default sieve size in kilobytes of the PrimeSieve class. Set
  /// PRIMESIEVE_SIEVESIZE to your CPUs L1 data cache size to get the
  /// best performance.
  /// @pre PRIMESIEVE_SIEVESIZE >= 1 && <= 2048
  ///
  PRIMESIEVE_SIEVESIZE = SIEVESIZE,

  /// Sieve size in kilobytes of the PrimeGenerator class.
  /// @pre PRIMEGENERATOR_SIEVESIZE >= 1 && <= 2048
  ///
  PRIMEGENERATOR_SIEVESIZE = L1_DCACHE_SIZE,

  /// Default pre-sieve limit. Multiples of primes up to this limit
  /// are pre-sieved to speed up the sieve of Eratosthenes.
  /// @pre PRESIEVE >= 13 && <= 23.
  ///
  PRESIEVE = 19,

  /// Pre-sieving is not used unless the sieving interval is >=
  /// PRESIEVE_THRESHOLD. (Pre-sieving is expensive to initialize.)
  ///
  PRESIEVE_THRESHOLD = 100000000,

  /// Number of sieving primes per Bucket in EratSmall, EratMedium and
  /// EratBig objects, affects performance by about 3%.
  ///
  /// - For x86-64 CPUs post  2010 use 1024
  /// - For x86-64 CPUs prior 2010 use 512
  /// - For PowerPC G4 CPUs   2003 use 256
  ///
  BUCKETSIZE = 1 << 10,

  /// EratBig allocates BYTES_PER_ALLOC of new memory each time
  /// it needs more buckets. Default = 8 megabytes.
  ///
  BYTES_PER_ALLOC = (1 << 20) * 8,

  /// primesieve::iterator objects cache up to ITERATOR_CACHE_SMALL
  /// bytes of primes when generating primes below 10^10. Either
  /// L3_CACHE_SIZE or L3_CACHE_SIZE / 2 are good values.
  ///
  ITERATOR_CACHE_SMALL = (1 << 20) * 4,

  /// primesieve::iterator maximum cache size (in bytes), used if
  /// pi(sqrt(n)) * 8 bytes > ITERATOR_CACHE_MAX.
  ///
  ITERATOR_CACHE_MAX = (1 << 20) * 512
};

  /// Sieving primes <= (sieveSize in bytes * FACTOR_ERATSMALL)
  /// are processed in EratSmall objects, speed up ~ 5%.
  /// @pre FACTOR_ERATSMALL >= 0 && <= 3
  ///
  /// - For x86-64 CPUs post  2010 use 0.5 (or 0.3)
  /// - For x86-64 CPUs prior 2010 use 0.8
  /// - For PowerPC G4 CPUs   2003 use 1.0
  ///
  const double FACTOR_ERATSMALL = 0.5;

  /// Sieving primes <= (sieveSize in bytes * FACTOR_ERATMEDIUM)
  /// (and > EratSmall see above) are processed in EratMedium objects.
  /// @pre FACTOR_ERATMEDIUM >= 0 && <= 9
  ///
  const double FACTOR_ERATMEDIUM = 7.5;

  /// Each thread sieves at least an interval of size
  /// MIN_THREAD_INTERVAL to reduce the initialization overhead.
  /// @pre MIN_THREAD_INTERVAL >= 100
  ///
  const uint64_t MIN_THREAD_INTERVAL = static_cast<uint64_t>(1e7);

  /// Each thread sieves at most an interval of size
  /// MAX_THREAD_INTERVAL to prevent load imbalance near 99%.
  ///
  const uint64_t MAX_THREAD_INTERVAL = static_cast<uint64_t>(2e10);

} // namespace config
} // namespace primesieve

#endif
<commit_msg>Optimize for Intel Skylake CPUs<commit_after>///
/// @file   config.hpp
/// @brief  Macros, typedefs and constants that set various limits
///         and array sizes within primesieve.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef CONFIG_PRIMESIEVE_HPP
#define CONFIG_PRIMESIEVE_HPP

/// Include config.h generated by ./configure script
#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

/// Enable the UINT64_C() macro from <stdint.h>
#if !defined(__STDC_CONSTANT_MACROS)
  #define __STDC_CONSTANT_MACROS
#endif

#include <stdint.h>

/// Disable assert() macro
#if !defined(DEBUG) && !defined(NDEBUG)
  #define NDEBUG
#endif

/// Disable the default copy constructor and assignment operator
#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(ClassName) \
  ClassName(const ClassName&); \
  void operator=(const ClassName&)
#endif

/// Default CPU L1 data cache size in kilobytes (per core)
#ifndef L1_DCACHE_SIZE
  #define L1_DCACHE_SIZE 32
#endif

#ifndef SIEVESIZE
  #define SIEVESIZE L1_DCACHE_SIZE
#endif

namespace primesieve {

/// byte_t must be unsigned in primesieve
typedef unsigned char byte_t;
typedef unsigned int uint_t;

enum {
  /// SieveOfEratosthenes objects use a bit array with 30 numbers per
  /// byte for sieving, the 8 bits of each byte correspond to the
  /// offsets { 7, 11, 13, 17, 19, 23, 29, 31 }.
  ///
  NUMBERS_PER_BYTE = 30
};

namespace config {

enum {
  /// Default sieve size in kilobytes of the PrimeSieve class. Set
  /// PRIMESIEVE_SIEVESIZE to your CPUs L1 data cache size to get the
  /// best performance.
  /// @pre PRIMESIEVE_SIEVESIZE >= 1 && <= 2048
  ///
  PRIMESIEVE_SIEVESIZE = SIEVESIZE,

  /// Sieve size in kilobytes of the PrimeGenerator class.
  /// @pre PRIMEGENERATOR_SIEVESIZE >= 1 && <= 2048
  ///
  PRIMEGENERATOR_SIEVESIZE = L1_DCACHE_SIZE,

  /// Default pre-sieve limit. Multiples of primes up to this limit
  /// are pre-sieved to speed up the sieve of Eratosthenes.
  /// @pre PRESIEVE >= 13 && <= 23.
  ///
  PRESIEVE = 19,

  /// Pre-sieving is not used unless the sieving interval is >=
  /// PRESIEVE_THRESHOLD. (Pre-sieving is expensive to initialize.)
  ///
  PRESIEVE_THRESHOLD = 100000000,

  /// Number of sieving primes per Bucket in EratSmall, EratMedium and
  /// EratBig objects, affects performance by about 3%.
  ///
  /// - For x86-64 CPUs post  2010 use 1024
  /// - For x86-64 CPUs prior 2010 use 512
  /// - For PowerPC G4 CPUs   2003 use 256
  ///
  BUCKETSIZE = 1 << 10,

  /// EratBig allocates BYTES_PER_ALLOC of new memory each time
  /// it needs more buckets. Default = 8 megabytes.
  ///
  BYTES_PER_ALLOC = (1 << 20) * 8,

  /// primesieve::iterator objects cache up to ITERATOR_CACHE_SMALL
  /// bytes of primes when generating primes below 10^10. Either
  /// L3_CACHE_SIZE or L3_CACHE_SIZE / 2 are good values.
  ///
  ITERATOR_CACHE_SMALL = (1 << 20) * 4,

  /// primesieve::iterator maximum cache size (in bytes), used if
  /// pi(sqrt(n)) * 8 bytes > ITERATOR_CACHE_MAX.
  ///
  ITERATOR_CACHE_MAX = (1 << 20) * 512
};

  /// Sieving primes <= (sieveSize in bytes * FACTOR_ERATSMALL)
  /// are processed in EratSmall objects, speed up ~ 5%.
  /// @pre FACTOR_ERATSMALL >= 0 && <= 3
  ///
  /// - For x86-64 CPUs post  2010 use 0.5 (or 0.3)
  /// - For x86-64 CPUs prior 2010 use 0.8
  /// - For PowerPC G4 CPUs   2003 use 1.0
  ///
  const double FACTOR_ERATSMALL = 0.5;

  /// Sieving primes <= (sieveSize in bytes * FACTOR_ERATMEDIUM)
  /// (and > EratSmall see above) are processed in EratMedium objects.
  /// @pre FACTOR_ERATMEDIUM >= 0 && <= 9
  ///
  /// Statistically ideal factor for 4th Wheel is:
  /// FACTOR_ERATMEDIUM * (4.468 / 2) + FACTOR_ERATMEDIUM * 10 = 30
  /// FACTOR_ERATMEDIUM * (2.234 + 10) = 30
  /// FACTOR_ERATMEDIUM =  30 / 12.234
  /// FACTOR_ERATMEDIUM = 2.452
  ///
  const double FACTOR_ERATMEDIUM = 2.452;

  /// Each thread sieves at least an interval of size
  /// MIN_THREAD_INTERVAL to reduce the initialization overhead.
  /// @pre MIN_THREAD_INTERVAL >= 100
  ///
  const uint64_t MIN_THREAD_INTERVAL = static_cast<uint64_t>(1e7);

  /// Each thread sieves at most an interval of size
  /// MAX_THREAD_INTERVAL to prevent load imbalance near 99%.
  ///
  const uint64_t MAX_THREAD_INTERVAL = static_cast<uint64_t>(2e10);

} // namespace config
} // namespace primesieve

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/test/trace_event_analyzer.h"
#include "base/version.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/tracing.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/gpu/gpu_blacklist.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "net/base/net_util.h"
#include "ui/gfx/gl/gl_switches.h"

namespace {

typedef uint32 GpuResultFlags;
#define EXPECT_NO_GPU_PROCESS         GpuResultFlags(0)
// Expect GPU process to be created.
#define EXPECT_GPU_PROCESS            GpuResultFlags(1<<0)
// Expect num_contexts_ to be created (onscreen or offscreen).
#define EXPECT_GPU_CONTEXTS           GpuResultFlags(1<<1)
// Expect a SwapBuffers to occur (see gles2_cmd_decoder.cc).
#define EXPECT_GPU_SWAP_BUFFERS       GpuResultFlags(1<<2)

class GpuFeatureTest : public InProcessBrowserTest {
 public:
  GpuFeatureTest()
      : num_contexts_(0),
        num_offscreen_contexts_(0) {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    // This enables DOM automation for tab contents.
    EnableDOMAutomation();
#if !defined(OS_MACOSX)
    CHECK(!command_line->HasSwitch(switches::kUseGL)) <<
        "kUseGL must not be set by test framework code!";
    command_line->AppendSwitchASCII(switches::kUseGL, "osmesa");
#endif
  }

  void SetupBlacklist(const std::string& json_blacklist) {
    scoped_ptr<Version> os_version(Version::GetVersionFromString("1.0"));
    GpuBlacklist* blacklist = new GpuBlacklist("1.0");

    ASSERT_TRUE(blacklist->LoadGpuBlacklist(
        json_blacklist, GpuBlacklist::kAllOs));
    GpuDataManager::GetInstance()->SetGpuBlacklist(blacklist);
  }

  void RunTest(const FilePath& url, GpuResultFlags expectations) {
    using namespace trace_analyzer;

    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("gpu"));
    test_path = test_path.Append(url);

    ASSERT_TRUE(file_util::PathExists(test_path))
        << "Missing test file: " << test_path.value();

    ASSERT_TRUE(tracing::BeginTracing("test_gpu"));

    ui_test_utils::DOMMessageQueue message_queue;
    // Have to use a new tab for the blacklist to work.
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), net::FilePathToFileURL(test_path), NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_NONE);
    // Wait for message indicating the test has finished running.
    ASSERT_TRUE(message_queue.WaitForMessage(NULL));

    std::string json_events;
    ASSERT_TRUE(tracing::EndTracing(&json_events));

    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));
    analyzer->AssociateBeginEndEvents();
    TraceAnalyzer::TraceEventVector events;

    size_t num_gpu_processes = (expectations & EXPECT_GPU_PROCESS) ? 1 : 0;
    analyzer->FindEvents(Query::MatchBeginName("OnGraphicsInfoCollected"),
                         &events);
    EXPECT_EQ(num_gpu_processes, events.size());

    // Check for context creation if expected:
    if (expectations & EXPECT_GPU_CONTEXTS) {
      analyzer->FindEvents(
          Query(EVENT_NAME) == Query::String("TryCreateGLContext"),
          &events);
      EXPECT_EQ(num_contexts_, events.size());
      analyzer->FindEvents(
          Query(EVENT_NAME) == Query::String("CreateGLContextSuccess"),
          &events);
      EXPECT_EQ(num_contexts_, events.size());
    }

    // Check for swap buffers if expected:
    if (expectations & EXPECT_GPU_SWAP_BUFFERS) {
      analyzer->FindEvents(
          Query(EVENT_NAME) == Query::String("SwapBuffers"),
          &events);
      EXPECT_GT(events.size(), size_t(0));
    }
  }

 protected:
  size_t num_contexts_;
  size_t num_offscreen_contexts_;
};

#if defined(OS_CHROMEOS)
// http://crbug.com/106259
#define MAYBE_AcceleratedCompositingAllowed DISABLED_testSetBooleanPrefTriggers
#else
#define MAYBE_AcceleratedCompositingAllowed AcceleratedCompositingAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MAYBE_AcceleratedCompositingAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  num_contexts_ = 1;
  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, EXPECT_GPU_PROCESS | EXPECT_GPU_SWAP_BUFFERS |
          EXPECT_GPU_CONTEXTS);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_compositing\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAcceleratedCompositing));

  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, EXPECT_NO_GPU_PROCESS);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, FLAKY_WebGLAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  num_contexts_ = 2;
  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, EXPECT_GPU_PROCESS | EXPECT_GPU_SWAP_BUFFERS |
          EXPECT_GPU_CONTEXTS);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"webgl\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureWebgl));

  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, EXPECT_NO_GPU_PROCESS);
}

#if defined(OS_LINUX)
// http://crbug.com/104142
#define Canvas2DAllowed FLAKY_Canvas2DAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

#if defined(OS_MACOSX)
  // TODO(zmo): enabling Mac when skia backend is enabled.
  const GpuResultFlags expectations = EXPECT_NO_GPU_PROCESS;
#else
  num_contexts_ = 2;
  const GpuResultFlags expectations = EXPECT_GPU_PROCESS |
                                      EXPECT_GPU_SWAP_BUFFERS |
                                      EXPECT_GPU_CONTEXTS;
#endif
  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, expectations);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_2d_canvas\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas));

  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, EXPECT_NO_GPU_PROCESS);
}

}  // namespace anonymous

<commit_msg>Call util function instead of duplicate the code in gpu_feature_browsertest.cc<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/test/trace_event_analyzer.h"
#include "base/version.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/tracing.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/gpu/gpu_blacklist.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "net/base/net_util.h"
#include "ui/gfx/gl/gl_switches.h"

namespace {

typedef uint32 GpuResultFlags;
#define EXPECT_NO_GPU_PROCESS         GpuResultFlags(0)
// Expect GPU process to be created.
#define EXPECT_GPU_PROCESS            GpuResultFlags(1<<0)
// Expect num_contexts_ to be created (onscreen or offscreen).
#define EXPECT_GPU_CONTEXTS           GpuResultFlags(1<<1)
// Expect a SwapBuffers to occur (see gles2_cmd_decoder.cc).
#define EXPECT_GPU_SWAP_BUFFERS       GpuResultFlags(1<<2)

class GpuFeatureTest : public InProcessBrowserTest {
 public:
  GpuFeatureTest()
      : num_contexts_(0),
        num_offscreen_contexts_(0) {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    // This enables DOM automation for tab contents.
    EnableDOMAutomation();
#if !defined(OS_MACOSX)
    CHECK(test_launcher_utils::OverrideGLImplementation(
        command_line, gfx::kGLImplementationOSMesaName)) <<
        "kUseGL must not be set by test framework code!";
#endif
  }

  void SetupBlacklist(const std::string& json_blacklist) {
    scoped_ptr<Version> os_version(Version::GetVersionFromString("1.0"));
    GpuBlacklist* blacklist = new GpuBlacklist("1.0");

    ASSERT_TRUE(blacklist->LoadGpuBlacklist(
        json_blacklist, GpuBlacklist::kAllOs));
    GpuDataManager::GetInstance()->SetGpuBlacklist(blacklist);
  }

  void RunTest(const FilePath& url, GpuResultFlags expectations) {
    using namespace trace_analyzer;

    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("gpu"));
    test_path = test_path.Append(url);

    ASSERT_TRUE(file_util::PathExists(test_path))
        << "Missing test file: " << test_path.value();

    ASSERT_TRUE(tracing::BeginTracing("test_gpu"));

    ui_test_utils::DOMMessageQueue message_queue;
    // Have to use a new tab for the blacklist to work.
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), net::FilePathToFileURL(test_path), NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_NONE);
    // Wait for message indicating the test has finished running.
    ASSERT_TRUE(message_queue.WaitForMessage(NULL));

    std::string json_events;
    ASSERT_TRUE(tracing::EndTracing(&json_events));

    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));
    analyzer->AssociateBeginEndEvents();
    TraceAnalyzer::TraceEventVector events;

    size_t num_gpu_processes = (expectations & EXPECT_GPU_PROCESS) ? 1 : 0;
    analyzer->FindEvents(Query::MatchBeginName("OnGraphicsInfoCollected"),
                         &events);
    EXPECT_EQ(num_gpu_processes, events.size());

    // Check for context creation if expected:
    if (expectations & EXPECT_GPU_CONTEXTS) {
      analyzer->FindEvents(
          Query(EVENT_NAME) == Query::String("TryCreateGLContext"),
          &events);
      EXPECT_EQ(num_contexts_, events.size());
      analyzer->FindEvents(
          Query(EVENT_NAME) == Query::String("CreateGLContextSuccess"),
          &events);
      EXPECT_EQ(num_contexts_, events.size());
    }

    // Check for swap buffers if expected:
    if (expectations & EXPECT_GPU_SWAP_BUFFERS) {
      analyzer->FindEvents(
          Query(EVENT_NAME) == Query::String("SwapBuffers"),
          &events);
      EXPECT_GT(events.size(), size_t(0));
    }
  }

 protected:
  size_t num_contexts_;
  size_t num_offscreen_contexts_;
};

#if defined(OS_CHROMEOS)
// http://crbug.com/106259
#define MAYBE_AcceleratedCompositingAllowed DISABLED_testSetBooleanPrefTriggers
#else
#define MAYBE_AcceleratedCompositingAllowed AcceleratedCompositingAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MAYBE_AcceleratedCompositingAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  num_contexts_ = 1;
  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, EXPECT_GPU_PROCESS | EXPECT_GPU_SWAP_BUFFERS |
          EXPECT_GPU_CONTEXTS);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_compositing\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAcceleratedCompositing));

  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, EXPECT_NO_GPU_PROCESS);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, FLAKY_WebGLAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  num_contexts_ = 2;
  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, EXPECT_GPU_PROCESS | EXPECT_GPU_SWAP_BUFFERS |
          EXPECT_GPU_CONTEXTS);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"webgl\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureWebgl));

  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, EXPECT_NO_GPU_PROCESS);
}

#if defined(OS_LINUX)
// http://crbug.com/104142
#define Canvas2DAllowed FLAKY_Canvas2DAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

#if defined(OS_MACOSX)
  // TODO(zmo): enabling Mac when skia backend is enabled.
  const GpuResultFlags expectations = EXPECT_NO_GPU_PROCESS;
#else
  num_contexts_ = 2;
  const GpuResultFlags expectations = EXPECT_GPU_PROCESS |
                                      EXPECT_GPU_SWAP_BUFFERS |
                                      EXPECT_GPU_CONTEXTS;
#endif
  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, expectations);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_2d_canvas\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas));

  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, EXPECT_NO_GPU_PROCESS);
}

}  // namespace anonymous

<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include <seastar/http/request_parser.hh>
#include <seastar/http/request.hh>
#include <seastar/core/seastar.hh>
#include <seastar/core/sstring.hh>
#include <seastar/core/app-template.hh>
#include <seastar/core/circular_buffer.hh>
#include <seastar/core/distributed.hh>
#include <seastar/core/queue.hh>
#include <seastar/core/gate.hh>
#include <seastar/core/metrics_registration.hh>
#include <seastar/util/std-compat.hh>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>
#include <bitset>
#include <limits>
#include <cctype>
#include <vector>
#include <boost/intrusive/list.hpp>
#include <seastar/http/routes.hh>
#include <seastar/net/tls.hh>
#include <seastar/core/shared_ptr.hh>

namespace seastar {

namespace httpd {

class http_server;
class http_stats;
struct reply;

using namespace std::chrono_literals;

class http_stats {
    metrics::metric_groups _metric_groups;
public:
    http_stats(http_server& server, const sstring& name);
};

class connection : public boost::intrusive::list_base_hook<> {
    http_server& _server;
    connected_socket _fd;
    input_stream<char> _read_buf;
    output_stream<char> _write_buf;
    static constexpr size_t limit = 4096;
    using tmp_buf = temporary_buffer<char>;
    http_request_parser _parser;
    std::unique_ptr<request> _req;
    std::unique_ptr<reply> _resp;
    // null element marks eof
    queue<std::unique_ptr<reply>> _replies { 10 };
    bool _done = false;
public:
    connection(http_server& server, connected_socket&& fd,
            socket_address addr)
            : _server(server), _fd(std::move(fd)), _read_buf(_fd.input()), _write_buf(
                    _fd.output()) {
        on_new_connection();
    }
    ~connection();
    void on_new_connection();

    future<> process();
    void shutdown();
    future<> read();
    future<> read_one();
    future<> respond();
    future<> do_response_loop();

    void set_headers(reply& resp);

    future<> start_response();
    future<> write_reply_headers(std::unordered_map<sstring, sstring>::iterator hi);

    static short hex_to_byte(char c);

    /**
     * Convert a hex encoded 2 bytes substring to char
     */
    static char hexstr_to_char(const std::string_view& in, size_t from);

    /**
     * URL_decode a substring and place it in the given out sstring
     */
    static bool url_decode(const std::string_view& in, sstring& out);

    /**
     * Add a single query parameter to the parameter list
     */
    static void add_param(request& req, const std::string_view& param);

    /**
     * Set the query parameters in the request objects.
     * query param appear after the question mark and are separated
     * by the ampersand sign
     */
    static sstring set_query_param(request& req);

    future<bool> generate_reply(std::unique_ptr<request> req);
    void generate_error_reply_and_close(std::unique_ptr<request> req, reply::status_type status, const sstring& msg);

    future<> write_body();

    output_stream<char>& out();
};

class http_server_tester;

class http_server {
    std::vector<server_socket> _listeners;
    http_stats _stats;
    uint64_t _total_connections = 0;
    uint64_t _current_connections = 0;
    uint64_t _requests_served = 0;
    uint64_t _read_errors = 0;
    uint64_t _respond_errors = 0;
    shared_ptr<seastar::tls::server_credentials> _credentials;
    sstring _date = http_date();
    timer<> _date_format_timer { [this] {_date = http_date();} };
    size_t _content_length_limit = std::numeric_limits<size_t>::max();
    bool _content_streaming = false;
    gate _task_gate;
public:
    routes _routes;
    using connection = seastar::httpd::connection;
    explicit http_server(const sstring& name) : _stats(*this, name) {
        _date_format_timer.arm_periodic(1s);
    }
    /*!
     * \brief set tls credentials for the server
     * Setting the tls credentials will set the http-server to work in https mode.
     *
     * To use the https, create server credentials and pass it to the server before it starts.
     *
     * Use case example using seastar threads for clarity:

        distributed<http_server> server; // typical server

        seastar::shared_ptr<seastar::tls::credentials_builder> creds = seastar::make_shared<seastar::tls::credentials_builder>();
        sstring ms_cert = "MyCertificate.crt";
        sstring ms_key = "MyKey.key";

        creds->set_dh_level(seastar::tls::dh_params::level::MEDIUM);

        creds->set_x509_key_file(ms_cert, ms_key, seastar::tls::x509_crt_format::PEM).get();
        creds->set_system_trust().get();

        server.invoke_on_all([creds](http_server& server) {
            server.set_tls_credentials(creds->build_server_credentials());
            return make_ready_future<>();
        }).get();
     *
     */
    void set_tls_credentials(shared_ptr<seastar::tls::server_credentials> credentials);

    size_t get_content_length_limit() const;

    void set_content_length_limit(size_t limit);

    bool get_content_streaming() const;

    void set_content_streaming(bool b);

    future<> listen(socket_address addr, listen_options lo);
    future<> listen(socket_address addr);
    future<> stop();

    future<> do_accepts(int which);

    uint64_t total_connections() const;
    uint64_t current_connections() const;
    uint64_t requests_served() const;
    uint64_t read_errors() const;
    uint64_t reply_errors() const;
    // Write the current date in the specific "preferred format" defined in
    // RFC 7231, Section 7.1.1.1.
    static sstring http_date();
private:
    future<> do_accept_one(int which);
    boost::intrusive::list<connection> _connections;
    friend class seastar::httpd::connection;
    friend class http_server_tester;
};

class http_server_tester {
public:
    static std::vector<server_socket>& listeners(http_server& server) {
        return server._listeners;
    }
};

/*
 * A helper class to start, set and listen an http server
 * typical use would be:
 *
 * auto server = new http_server_control();
 *                 server->start().then([server] {
 *                 server->set_routes(set_routes);
 *              }).then([server, port] {
 *                  server->listen(port);
 *              }).then([port] {
 *                  std::cout << "Seastar HTTP server listening on port " << port << " ...\n";
 *              });
 */
class http_server_control {
    std::unique_ptr<distributed<http_server>> _server_dist;
private:
    static sstring generate_server_name();
public:
    http_server_control() : _server_dist(new distributed<http_server>) {
    }

    future<> start(const sstring& name = generate_server_name());
    future<> stop();
    future<> set_routes(std::function<void(routes& r)> fun);
    future<> listen(socket_address addr);
    future<> listen(socket_address addr, listen_options lo);
    distributed<http_server>& server();
};

}

}
<commit_msg>httpd: add a ctor without addr parameter<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include <seastar/http/request_parser.hh>
#include <seastar/http/request.hh>
#include <seastar/core/seastar.hh>
#include <seastar/core/sstring.hh>
#include <seastar/core/app-template.hh>
#include <seastar/core/circular_buffer.hh>
#include <seastar/core/distributed.hh>
#include <seastar/core/queue.hh>
#include <seastar/core/gate.hh>
#include <seastar/core/metrics_registration.hh>
#include <seastar/util/std-compat.hh>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>
#include <bitset>
#include <limits>
#include <cctype>
#include <vector>
#include <boost/intrusive/list.hpp>
#include <seastar/http/routes.hh>
#include <seastar/net/tls.hh>
#include <seastar/core/shared_ptr.hh>

namespace seastar {

namespace httpd {

class http_server;
class http_stats;
struct reply;

using namespace std::chrono_literals;

class http_stats {
    metrics::metric_groups _metric_groups;
public:
    http_stats(http_server& server, const sstring& name);
};

class connection : public boost::intrusive::list_base_hook<> {
    http_server& _server;
    connected_socket _fd;
    input_stream<char> _read_buf;
    output_stream<char> _write_buf;
    static constexpr size_t limit = 4096;
    using tmp_buf = temporary_buffer<char>;
    http_request_parser _parser;
    std::unique_ptr<request> _req;
    std::unique_ptr<reply> _resp;
    // null element marks eof
    queue<std::unique_ptr<reply>> _replies { 10 };
    bool _done = false;
public:
    [[deprecated("use connection(http_server&, connected_socket&&)")]]
    connection(http_server& server, connected_socket&& fd,
            socket_address) : connection(server, std::move(fd)) {}
    connection(http_server& server, connected_socket&& fd)
            : _server(server), _fd(std::move(fd)), _read_buf(_fd.input()), _write_buf(
                    _fd.output()) {
        on_new_connection();
    }
    ~connection();
    void on_new_connection();

    future<> process();
    void shutdown();
    future<> read();
    future<> read_one();
    future<> respond();
    future<> do_response_loop();

    void set_headers(reply& resp);

    future<> start_response();
    future<> write_reply_headers(std::unordered_map<sstring, sstring>::iterator hi);

    static short hex_to_byte(char c);

    /**
     * Convert a hex encoded 2 bytes substring to char
     */
    static char hexstr_to_char(const std::string_view& in, size_t from);

    /**
     * URL_decode a substring and place it in the given out sstring
     */
    static bool url_decode(const std::string_view& in, sstring& out);

    /**
     * Add a single query parameter to the parameter list
     */
    static void add_param(request& req, const std::string_view& param);

    /**
     * Set the query parameters in the request objects.
     * query param appear after the question mark and are separated
     * by the ampersand sign
     */
    static sstring set_query_param(request& req);

    future<bool> generate_reply(std::unique_ptr<request> req);
    void generate_error_reply_and_close(std::unique_ptr<request> req, reply::status_type status, const sstring& msg);

    future<> write_body();

    output_stream<char>& out();
};

class http_server_tester;

class http_server {
    std::vector<server_socket> _listeners;
    http_stats _stats;
    uint64_t _total_connections = 0;
    uint64_t _current_connections = 0;
    uint64_t _requests_served = 0;
    uint64_t _read_errors = 0;
    uint64_t _respond_errors = 0;
    shared_ptr<seastar::tls::server_credentials> _credentials;
    sstring _date = http_date();
    timer<> _date_format_timer { [this] {_date = http_date();} };
    size_t _content_length_limit = std::numeric_limits<size_t>::max();
    bool _content_streaming = false;
    gate _task_gate;
public:
    routes _routes;
    using connection = seastar::httpd::connection;
    explicit http_server(const sstring& name) : _stats(*this, name) {
        _date_format_timer.arm_periodic(1s);
    }
    /*!
     * \brief set tls credentials for the server
     * Setting the tls credentials will set the http-server to work in https mode.
     *
     * To use the https, create server credentials and pass it to the server before it starts.
     *
     * Use case example using seastar threads for clarity:

        distributed<http_server> server; // typical server

        seastar::shared_ptr<seastar::tls::credentials_builder> creds = seastar::make_shared<seastar::tls::credentials_builder>();
        sstring ms_cert = "MyCertificate.crt";
        sstring ms_key = "MyKey.key";

        creds->set_dh_level(seastar::tls::dh_params::level::MEDIUM);

        creds->set_x509_key_file(ms_cert, ms_key, seastar::tls::x509_crt_format::PEM).get();
        creds->set_system_trust().get();

        server.invoke_on_all([creds](http_server& server) {
            server.set_tls_credentials(creds->build_server_credentials());
            return make_ready_future<>();
        }).get();
     *
     */
    void set_tls_credentials(shared_ptr<seastar::tls::server_credentials> credentials);

    size_t get_content_length_limit() const;

    void set_content_length_limit(size_t limit);

    bool get_content_streaming() const;

    void set_content_streaming(bool b);

    future<> listen(socket_address addr, listen_options lo);
    future<> listen(socket_address addr);
    future<> stop();

    future<> do_accepts(int which);

    uint64_t total_connections() const;
    uint64_t current_connections() const;
    uint64_t requests_served() const;
    uint64_t read_errors() const;
    uint64_t reply_errors() const;
    // Write the current date in the specific "preferred format" defined in
    // RFC 7231, Section 7.1.1.1.
    static sstring http_date();
private:
    future<> do_accept_one(int which);
    boost::intrusive::list<connection> _connections;
    friend class seastar::httpd::connection;
    friend class http_server_tester;
};

class http_server_tester {
public:
    static std::vector<server_socket>& listeners(http_server& server) {
        return server._listeners;
    }
};

/*
 * A helper class to start, set and listen an http server
 * typical use would be:
 *
 * auto server = new http_server_control();
 *                 server->start().then([server] {
 *                 server->set_routes(set_routes);
 *              }).then([server, port] {
 *                  server->listen(port);
 *              }).then([port] {
 *                  std::cout << "Seastar HTTP server listening on port " << port << " ...\n";
 *              });
 */
class http_server_control {
    std::unique_ptr<distributed<http_server>> _server_dist;
private:
    static sstring generate_server_name();
public:
    http_server_control() : _server_dist(new distributed<http_server>) {
    }

    future<> start(const sstring& name = generate_server_name());
    future<> stop();
    future<> set_routes(std::function<void(routes& r)> fun);
    future<> listen(socket_address addr);
    future<> listen(socket_address addr, listen_options lo);
    distributed<http_server>& server();
};

}

}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_SVTOOLS_ASYNCLINK_HXX
#define INCLUDED_SVTOOLS_ASYNCLINK_HXX

#include <svtools/svtdllapi.h>
#include <tools/solar.h>
#include <tools/link.hxx>
#include <osl/mutex.hxx>

class Timer;

namespace svtools {

class SVT_DLLPUBLIC AsynchronLink
{
    Link   _aLink;
    sal_uLong  _nEventId;
    Timer* _pTimer;
    sal_Bool   _bInCall;
    sal_Bool*  _pDeleted;
    void*  _pArg;
    ::osl::Mutex* _pMutex;

    DECL_DLLPRIVATE_STATIC_LINK( AsynchronLink, HandleCall, void* );
    SVT_DLLPRIVATE void Call_Impl( void* pArg );

public:
    AsynchronLink( const Link& rLink ) :
        _aLink( rLink ), _nEventId( 0 ), _pTimer( 0 ), _bInCall( sal_False ),
        _pDeleted( 0 ), _pMutex( 0 ){}
    AsynchronLink() : _nEventId( 0 ), _pTimer( 0 ), _bInCall( sal_False ),
            _pDeleted( 0 ), _pMutex( 0 ){}
    ~AsynchronLink();

    void CreateMutex();
    void operator=( const Link& rLink ) { _aLink = rLink; }
    void Call( void* pObj, sal_Bool bAllowDoubles = sal_False,
               sal_Bool bUseTimer = sal_False );
    void ClearPendingCall( );
    sal_Bool IsSet() const { return _aLink.IsSet(); }
    Link GetLink() const { return _aLink; }
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#708192 Uninitialized pointer field<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_SVTOOLS_ASYNCLINK_HXX
#define INCLUDED_SVTOOLS_ASYNCLINK_HXX

#include <svtools/svtdllapi.h>
#include <tools/solar.h>
#include <tools/link.hxx>
#include <osl/mutex.hxx>

class Timer;

namespace svtools {

class SVT_DLLPUBLIC AsynchronLink
{
    Link   _aLink;
    sal_uLong  _nEventId;
    Timer* _pTimer;
    sal_Bool   _bInCall;
    sal_Bool*  _pDeleted;
    void*  _pArg;
    ::osl::Mutex* _pMutex;

    DECL_DLLPRIVATE_STATIC_LINK( AsynchronLink, HandleCall, void* );
    SVT_DLLPRIVATE void Call_Impl( void* pArg );

public:
    AsynchronLink( const Link& rLink )
        : _aLink( rLink )
        , _nEventId( 0 )
        , _pTimer( 0 )
        , _bInCall( sal_False )
        , _pDeleted( 0 )
        , _pArg( 0 )
        , _pMutex( 0 )
    {}
    AsynchronLink()
        : _nEventId( 0 )
        , _pTimer( 0 )
        , _bInCall( sal_False )
        , _pDeleted( 0 )
        , _pArg( 0 )
        , _pMutex( 0 )
    {}
    ~AsynchronLink();

    void CreateMutex();
    void operator=( const Link& rLink ) { _aLink = rLink; }
    void Call( void* pObj, sal_Bool bAllowDoubles = sal_False,
               sal_Bool bUseTimer = sal_False );
    void ClearPendingCall( );
    sal_Bool IsSet() const { return _aLink.IsSet(); }
    Link GetLink() const { return _aLink; }
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//===-LTOBackend.cpp - LLVM Link Time Optimizer Backend -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the "backend" phase of LTO, i.e. it performs
// optimization and code generation on a loaded module. It is generally used
// internally by the LTO class but can also be used independently, for example
// to implement a standalone ThinLTO backend.
//
//===----------------------------------------------------------------------===//

#include "llvm/LTO/LTOBackend.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/LTO/LTO.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/Transforms/Utils/SplitModule.h"

using namespace llvm;
using namespace lto;

Error Config::addSaveTemps(std::string OutputFileName,
                           bool UseInputModulePath) {
  ShouldDiscardValueNames = false;

  std::error_code EC;
  ResolutionFile = llvm::make_unique<raw_fd_ostream>(
      OutputFileName + "resolution.txt", EC, sys::fs::OpenFlags::F_Text);
  if (EC)
    return errorCodeToError(EC);

  auto setHook = [&](std::string PathSuffix, ModuleHookFn &Hook) {
    // Keep track of the hook provided by the linker, which also needs to run.
    ModuleHookFn LinkerHook = Hook;
    Hook = [=](unsigned Task, const Module &M) {
      // If the linker's hook returned false, we need to pass that result
      // through.
      if (LinkerHook && !LinkerHook(Task, M))
        return false;

      std::string PathPrefix;
      // If this is the combined module (not a ThinLTO backend compile) or the
      // user hasn't requested using the input module's path, emit to a file
      // named from the provided OutputFileName with the Task ID appended.
      if (M.getModuleIdentifier() == "ld-temp.o" || !UseInputModulePath) {
        PathPrefix = OutputFileName + utostr(Task);
      } else
        PathPrefix = M.getModuleIdentifier();
      std::string Path = PathPrefix + "." + PathSuffix + ".bc";
      std::error_code EC;
      raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None);
      if (EC) {
        // Because -save-temps is a debugging feature, we report the error
        // directly and exit.
        llvm::errs() << "failed to open " << Path << ": " << EC.message()
                     << '\n';
        exit(1);
      }
      WriteBitcodeToFile(&M, OS, /*ShouldPreserveUseListOrder=*/false);
      return true;
    };
  };

  setHook("0.preopt", PreOptModuleHook);
  setHook("1.promote", PostPromoteModuleHook);
  setHook("2.internalize", PostInternalizeModuleHook);
  setHook("3.import", PostImportModuleHook);
  setHook("4.opt", PostOptModuleHook);
  setHook("5.precodegen", PreCodeGenModuleHook);

  CombinedIndexHook = [=](const ModuleSummaryIndex &Index) {
    std::string Path = OutputFileName + "index.bc";
    std::error_code EC;
    raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None);
    if (EC) {
      // Because -save-temps is a debugging feature, we report the error
      // directly and exit.
      llvm::errs() << "failed to open " << Path << ": " << EC.message() << '\n';
      exit(1);
    }
    WriteIndexToFile(Index, OS);
    return true;
  };

  return Error();
}

namespace {

std::unique_ptr<TargetMachine>
createTargetMachine(Config &C, StringRef TheTriple, const Target *TheTarget) {
  SubtargetFeatures Features;
  Features.getDefaultSubtargetFeatures(Triple(TheTriple));
  for (const std::string &A : C.MAttrs)
    Features.AddFeature(A);

  return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
      TheTriple, C.CPU, Features.getString(), C.Options, C.RelocModel,
      C.CodeModel, C.CGOptLevel));
}

static void runOldPMPasses(Config &C, Module &M, TargetMachine *TM,
                           bool IsThinLto) {
  legacy::PassManager passes;
  passes.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));

  PassManagerBuilder PMB;
  PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple()));
  PMB.Inliner = createFunctionInliningPass();
  // Unconditionally verify input since it is not verified before this
  // point and has unknown origin.
  PMB.VerifyInput = true;
  PMB.VerifyOutput = !C.DisableVerify;
  PMB.LoopVectorize = true;
  PMB.SLPVectorize = true;
  PMB.OptLevel = C.OptLevel;
  if (IsThinLto)
    PMB.populateThinLTOPassManager(passes);
  else
    PMB.populateLTOPassManager(passes);
  passes.run(M);
}

bool opt(Config &C, TargetMachine *TM, unsigned Task, Module &M,
         bool IsThinLto) {
  M.setDataLayout(TM->createDataLayout());
  runOldPMPasses(C, M, TM, IsThinLto);
  if (C.PostOptModuleHook && !C.PostOptModuleHook(Task, M))
    return false;

  return true;
}

/// Monolithic LTO does not support caching (yet), this is a convenient wrapper
/// around AddOutput to workaround this.
static AddOutputFn getUncachedOutputWrapper(AddOutputFn &AddOutput,
                                            unsigned Task) {
  return [Task, &AddOutput](unsigned TaskId) {
    auto Output = AddOutput(Task);
    if (Output->isCachingEnabled() && Output->tryLoadFromCache(""))
      report_fatal_error("Cache hit without a valid key?");
    assert(Task == TaskId && "Unexpexted TaskId mismatch");
    return Output;
  };
}

void codegen(Config &C, TargetMachine *TM, AddOutputFn AddOutput, unsigned Task,
             Module &M) {
  if (C.PreCodeGenModuleHook && !C.PreCodeGenModuleHook(Task, M))
    return;

  auto Output = AddOutput(Task);
  std::unique_ptr<raw_pwrite_stream> OS = Output->getStream();
  legacy::PassManager CodeGenPasses;
  if (TM->addPassesToEmitFile(CodeGenPasses, *OS,
                              TargetMachine::CGFT_ObjectFile))
    report_fatal_error("Failed to setup codegen");
  CodeGenPasses.run(M);
}

void splitCodeGen(Config &C, TargetMachine *TM, AddOutputFn AddOutput,
                  unsigned ParallelCodeGenParallelismLevel,
                  std::unique_ptr<Module> M) {
  ThreadPool CodegenThreadPool(ParallelCodeGenParallelismLevel);
  unsigned ThreadCount = 0;
  const Target *T = &TM->getTarget();

  SplitModule(
      std::move(M), ParallelCodeGenParallelismLevel,
      [&](std::unique_ptr<Module> MPart) {
        // We want to clone the module in a new context to multi-thread the
        // codegen. We do it by serializing partition modules to bitcode
        // (while still on the main thread, in order to avoid data races) and
        // spinning up new threads which deserialize the partitions into
        // separate contexts.
        // FIXME: Provide a more direct way to do this in LLVM.
        SmallString<0> BC;
        raw_svector_ostream BCOS(BC);
        WriteBitcodeToFile(MPart.get(), BCOS);

        // Enqueue the task
        CodegenThreadPool.async(
            [&](const SmallString<0> &BC, unsigned ThreadId) {
              LTOLLVMContext Ctx(C);
              ErrorOr<std::unique_ptr<Module>> MOrErr = parseBitcodeFile(
                  MemoryBufferRef(StringRef(BC.data(), BC.size()), "ld-temp.o"),
                  Ctx);
              if (!MOrErr)
                report_fatal_error("Failed to read bitcode");
              std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());

              std::unique_ptr<TargetMachine> TM =
                  createTargetMachine(C, MPartInCtx->getTargetTriple(), T);

              codegen(C, TM.get(),
                      getUncachedOutputWrapper(AddOutput, ThreadId), ThreadId,
                      *MPartInCtx);
            },
            // Pass BC using std::move to ensure that it get moved rather than
            // copied into the thread's context.
            std::move(BC), ThreadCount++);
      },
      false);
}

Expected<const Target *> initAndLookupTarget(Config &C, Module &M) {
  if (!C.OverrideTriple.empty())
    M.setTargetTriple(C.OverrideTriple);
  else if (M.getTargetTriple().empty())
    M.setTargetTriple(C.DefaultTriple);

  std::string Msg;
  const Target *T = TargetRegistry::lookupTarget(M.getTargetTriple(), Msg);
  if (!T)
    return make_error<StringError>(Msg, inconvertibleErrorCode());
  return T;
}

}

Error lto::backend(Config &C, AddOutputFn AddOutput,
                   unsigned ParallelCodeGenParallelismLevel,
                   std::unique_ptr<Module> M) {
  Expected<const Target *> TOrErr = initAndLookupTarget(C, *M);
  if (!TOrErr)
    return TOrErr.takeError();

  std::unique_ptr<TargetMachine> TM =
      createTargetMachine(C, M->getTargetTriple(), *TOrErr);

  if (!C.CodeGenOnly)
    if (!opt(C, TM.get(), 0, *M, /*IsThinLto=*/false))
      return Error();

  if (ParallelCodeGenParallelismLevel == 1) {
    codegen(C, TM.get(), getUncachedOutputWrapper(AddOutput, 0), 0, *M);
  } else {
    splitCodeGen(C, TM.get(), AddOutput, ParallelCodeGenParallelismLevel,
                 std::move(M));
  }
  return Error();
}

Error lto::thinBackend(Config &Conf, unsigned Task, AddOutputFn AddOutput,
                       Module &Mod, ModuleSummaryIndex &CombinedIndex,
                       const FunctionImporter::ImportMapTy &ImportList,
                       const GVSummaryMapTy &DefinedGlobals,
                       MapVector<StringRef, MemoryBufferRef> &ModuleMap) {
  Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod);
  if (!TOrErr)
    return TOrErr.takeError();

  std::unique_ptr<TargetMachine> TM =
      createTargetMachine(Conf, Mod.getTargetTriple(), *TOrErr);

  if (Conf.CodeGenOnly) {
    codegen(Conf, TM.get(), AddOutput, Task, Mod);
    return Error();
  }

  if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod))
    return Error();

  renameModuleForThinLTO(Mod, CombinedIndex);

  thinLTOResolveWeakForLinkerModule(Mod, DefinedGlobals);

  if (Conf.PostPromoteModuleHook && !Conf.PostPromoteModuleHook(Task, Mod))
    return Error();

  if (!DefinedGlobals.empty())
    thinLTOInternalizeModule(Mod, DefinedGlobals);

  if (Conf.PostInternalizeModuleHook &&
      !Conf.PostInternalizeModuleHook(Task, Mod))
    return Error();

  auto ModuleLoader = [&](StringRef Identifier) {
    assert(Mod.getContext().isODRUniquingDebugTypes() &&
           "ODR Type uniquing shoudl be enabled on the context");
    return std::move(getLazyBitcodeModule(MemoryBuffer::getMemBuffer(
                                              ModuleMap[Identifier], false),
                                          Mod.getContext(),
                                          /*ShouldLazyLoadMetadata=*/true)
                         .get());
  };

  FunctionImporter Importer(CombinedIndex, ModuleLoader);
  Importer.importFunctions(Mod, ImportList);

  if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
    return Error();

  if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLto=*/true))
    return Error();

  codegen(Conf, TM.get(), AddOutput, Task, Mod);
  return Error();
}
<commit_msg>[lib/LTO] Simplify a bit. NFCI.<commit_after>//===-LTOBackend.cpp - LLVM Link Time Optimizer Backend -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the "backend" phase of LTO, i.e. it performs
// optimization and code generation on a loaded module. It is generally used
// internally by the LTO class but can also be used independently, for example
// to implement a standalone ThinLTO backend.
//
//===----------------------------------------------------------------------===//

#include "llvm/LTO/LTOBackend.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/LTO/LTO.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/Transforms/Utils/SplitModule.h"

using namespace llvm;
using namespace lto;

Error Config::addSaveTemps(std::string OutputFileName,
                           bool UseInputModulePath) {
  ShouldDiscardValueNames = false;

  std::error_code EC;
  ResolutionFile = llvm::make_unique<raw_fd_ostream>(
      OutputFileName + "resolution.txt", EC, sys::fs::OpenFlags::F_Text);
  if (EC)
    return errorCodeToError(EC);

  auto setHook = [&](std::string PathSuffix, ModuleHookFn &Hook) {
    // Keep track of the hook provided by the linker, which also needs to run.
    ModuleHookFn LinkerHook = Hook;
    Hook = [=](unsigned Task, const Module &M) {
      // If the linker's hook returned false, we need to pass that result
      // through.
      if (LinkerHook && !LinkerHook(Task, M))
        return false;

      std::string PathPrefix;
      // If this is the combined module (not a ThinLTO backend compile) or the
      // user hasn't requested using the input module's path, emit to a file
      // named from the provided OutputFileName with the Task ID appended.
      if (M.getModuleIdentifier() == "ld-temp.o" || !UseInputModulePath) {
        PathPrefix = OutputFileName + utostr(Task);
      } else
        PathPrefix = M.getModuleIdentifier();
      std::string Path = PathPrefix + "." + PathSuffix + ".bc";
      std::error_code EC;
      raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None);
      if (EC) {
        // Because -save-temps is a debugging feature, we report the error
        // directly and exit.
        llvm::errs() << "failed to open " << Path << ": " << EC.message()
                     << '\n';
        exit(1);
      }
      WriteBitcodeToFile(&M, OS, /*ShouldPreserveUseListOrder=*/false);
      return true;
    };
  };

  setHook("0.preopt", PreOptModuleHook);
  setHook("1.promote", PostPromoteModuleHook);
  setHook("2.internalize", PostInternalizeModuleHook);
  setHook("3.import", PostImportModuleHook);
  setHook("4.opt", PostOptModuleHook);
  setHook("5.precodegen", PreCodeGenModuleHook);

  CombinedIndexHook = [=](const ModuleSummaryIndex &Index) {
    std::string Path = OutputFileName + "index.bc";
    std::error_code EC;
    raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None);
    if (EC) {
      // Because -save-temps is a debugging feature, we report the error
      // directly and exit.
      llvm::errs() << "failed to open " << Path << ": " << EC.message() << '\n';
      exit(1);
    }
    WriteIndexToFile(Index, OS);
    return true;
  };

  return Error();
}

namespace {

std::unique_ptr<TargetMachine>
createTargetMachine(Config &C, StringRef TheTriple, const Target *TheTarget) {
  SubtargetFeatures Features;
  Features.getDefaultSubtargetFeatures(Triple(TheTriple));
  for (const std::string &A : C.MAttrs)
    Features.AddFeature(A);

  return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
      TheTriple, C.CPU, Features.getString(), C.Options, C.RelocModel,
      C.CodeModel, C.CGOptLevel));
}

static void runOldPMPasses(Config &C, Module &M, TargetMachine *TM,
                           bool IsThinLto) {
  legacy::PassManager passes;
  passes.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));

  PassManagerBuilder PMB;
  PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple()));
  PMB.Inliner = createFunctionInliningPass();
  // Unconditionally verify input since it is not verified before this
  // point and has unknown origin.
  PMB.VerifyInput = true;
  PMB.VerifyOutput = !C.DisableVerify;
  PMB.LoopVectorize = true;
  PMB.SLPVectorize = true;
  PMB.OptLevel = C.OptLevel;
  if (IsThinLto)
    PMB.populateThinLTOPassManager(passes);
  else
    PMB.populateLTOPassManager(passes);
  passes.run(M);
}

bool opt(Config &C, TargetMachine *TM, unsigned Task, Module &M,
         bool IsThinLto) {
  M.setDataLayout(TM->createDataLayout());
  runOldPMPasses(C, M, TM, IsThinLto);
  return !C.PostOptModuleHook || C.PostOptModuleHook(Task, M);
}

/// Monolithic LTO does not support caching (yet), this is a convenient wrapper
/// around AddOutput to workaround this.
static AddOutputFn getUncachedOutputWrapper(AddOutputFn &AddOutput,
                                            unsigned Task) {
  return [Task, &AddOutput](unsigned TaskId) {
    auto Output = AddOutput(Task);
    if (Output->isCachingEnabled() && Output->tryLoadFromCache(""))
      report_fatal_error("Cache hit without a valid key?");
    assert(Task == TaskId && "Unexpexted TaskId mismatch");
    return Output;
  };
}

void codegen(Config &C, TargetMachine *TM, AddOutputFn AddOutput, unsigned Task,
             Module &M) {
  if (C.PreCodeGenModuleHook && !C.PreCodeGenModuleHook(Task, M))
    return;

  auto Output = AddOutput(Task);
  std::unique_ptr<raw_pwrite_stream> OS = Output->getStream();
  legacy::PassManager CodeGenPasses;
  if (TM->addPassesToEmitFile(CodeGenPasses, *OS,
                              TargetMachine::CGFT_ObjectFile))
    report_fatal_error("Failed to setup codegen");
  CodeGenPasses.run(M);
}

void splitCodeGen(Config &C, TargetMachine *TM, AddOutputFn AddOutput,
                  unsigned ParallelCodeGenParallelismLevel,
                  std::unique_ptr<Module> M) {
  ThreadPool CodegenThreadPool(ParallelCodeGenParallelismLevel);
  unsigned ThreadCount = 0;
  const Target *T = &TM->getTarget();

  SplitModule(
      std::move(M), ParallelCodeGenParallelismLevel,
      [&](std::unique_ptr<Module> MPart) {
        // We want to clone the module in a new context to multi-thread the
        // codegen. We do it by serializing partition modules to bitcode
        // (while still on the main thread, in order to avoid data races) and
        // spinning up new threads which deserialize the partitions into
        // separate contexts.
        // FIXME: Provide a more direct way to do this in LLVM.
        SmallString<0> BC;
        raw_svector_ostream BCOS(BC);
        WriteBitcodeToFile(MPart.get(), BCOS);

        // Enqueue the task
        CodegenThreadPool.async(
            [&](const SmallString<0> &BC, unsigned ThreadId) {
              LTOLLVMContext Ctx(C);
              ErrorOr<std::unique_ptr<Module>> MOrErr = parseBitcodeFile(
                  MemoryBufferRef(StringRef(BC.data(), BC.size()), "ld-temp.o"),
                  Ctx);
              if (!MOrErr)
                report_fatal_error("Failed to read bitcode");
              std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());

              std::unique_ptr<TargetMachine> TM =
                  createTargetMachine(C, MPartInCtx->getTargetTriple(), T);

              codegen(C, TM.get(),
                      getUncachedOutputWrapper(AddOutput, ThreadId), ThreadId,
                      *MPartInCtx);
            },
            // Pass BC using std::move to ensure that it get moved rather than
            // copied into the thread's context.
            std::move(BC), ThreadCount++);
      },
      false);
}

Expected<const Target *> initAndLookupTarget(Config &C, Module &M) {
  if (!C.OverrideTriple.empty())
    M.setTargetTriple(C.OverrideTriple);
  else if (M.getTargetTriple().empty())
    M.setTargetTriple(C.DefaultTriple);

  std::string Msg;
  const Target *T = TargetRegistry::lookupTarget(M.getTargetTriple(), Msg);
  if (!T)
    return make_error<StringError>(Msg, inconvertibleErrorCode());
  return T;
}

}

Error lto::backend(Config &C, AddOutputFn AddOutput,
                   unsigned ParallelCodeGenParallelismLevel,
                   std::unique_ptr<Module> M) {
  Expected<const Target *> TOrErr = initAndLookupTarget(C, *M);
  if (!TOrErr)
    return TOrErr.takeError();

  std::unique_ptr<TargetMachine> TM =
      createTargetMachine(C, M->getTargetTriple(), *TOrErr);

  if (!C.CodeGenOnly)
    if (!opt(C, TM.get(), 0, *M, /*IsThinLto=*/false))
      return Error();

  if (ParallelCodeGenParallelismLevel == 1) {
    codegen(C, TM.get(), getUncachedOutputWrapper(AddOutput, 0), 0, *M);
  } else {
    splitCodeGen(C, TM.get(), AddOutput, ParallelCodeGenParallelismLevel,
                 std::move(M));
  }
  return Error();
}

Error lto::thinBackend(Config &Conf, unsigned Task, AddOutputFn AddOutput,
                       Module &Mod, ModuleSummaryIndex &CombinedIndex,
                       const FunctionImporter::ImportMapTy &ImportList,
                       const GVSummaryMapTy &DefinedGlobals,
                       MapVector<StringRef, MemoryBufferRef> &ModuleMap) {
  Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod);
  if (!TOrErr)
    return TOrErr.takeError();

  std::unique_ptr<TargetMachine> TM =
      createTargetMachine(Conf, Mod.getTargetTriple(), *TOrErr);

  if (Conf.CodeGenOnly) {
    codegen(Conf, TM.get(), AddOutput, Task, Mod);
    return Error();
  }

  if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod))
    return Error();

  renameModuleForThinLTO(Mod, CombinedIndex);

  thinLTOResolveWeakForLinkerModule(Mod, DefinedGlobals);

  if (Conf.PostPromoteModuleHook && !Conf.PostPromoteModuleHook(Task, Mod))
    return Error();

  if (!DefinedGlobals.empty())
    thinLTOInternalizeModule(Mod, DefinedGlobals);

  if (Conf.PostInternalizeModuleHook &&
      !Conf.PostInternalizeModuleHook(Task, Mod))
    return Error();

  auto ModuleLoader = [&](StringRef Identifier) {
    assert(Mod.getContext().isODRUniquingDebugTypes() &&
           "ODR Type uniquing shoudl be enabled on the context");
    return std::move(getLazyBitcodeModule(MemoryBuffer::getMemBuffer(
                                              ModuleMap[Identifier], false),
                                          Mod.getContext(),
                                          /*ShouldLazyLoadMetadata=*/true)
                         .get());
  };

  FunctionImporter Importer(CombinedIndex, ModuleLoader);
  Importer.importFunctions(Mod, ImportList);

  if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
    return Error();

  if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLto=*/true))
    return Error();

  codegen(Conf, TM.get(), AddOutput, Task, Mod);
  return Error();
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file input format is based loosely on
// WebKitTools/DumpRenderTree/ImageDiff.m

// The exact format of this tool's output to stdout is important, to match
// what the run-webkit-tests script expects.

#include <algorithm>
#include <vector>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/gfx/png_decoder.h"
#include "base/logging.h"
#include "base/process_util.h"
#include "base/scoped_ptr.h"

// Causes the app to remain open, waiting for pairs of filenames on stdin.
// The caller is then responsible for terminating this app.
static const wchar_t kOptionPollStdin[] = L"use-stdin";

// Return codes used by this utility.
static const int kStatusSame = 0;
static const int kStatusDifferent = 1;
static const int kStatusError = 2;

class Image {
 public:
  Image() : w_(0), h_(0) {
  }

  bool has_image() const {
    return w_ > 0 && h_ > 0;
  }

  int w() const {
    return w_;
  }

  int h() const {
    return h_;
  }

  // Creates the image from stdin with the given data length. On success, it
  // will return true. On failure, no other methods should be accessed.
  bool CreateFromStdin(int byte_length) {
    if (byte_length <= 0)
      return false;

    scoped_array<unsigned char> source(new unsigned char[byte_length]);
    if (fread(source.get(), 1, byte_length, stdin) != byte_length)
      return false;

    if (!PNGDecoder::Decode(source.get(), byte_length, PNGDecoder::FORMAT_RGBA,
                          &data_, &w_, &h_)) {
      Clear();
      return false;
    }
    return true;
  }

  // Creates the image from the given filename on disk, and returns true on
  // success.
  bool CreateFromFilename(const char* filename) {
    FILE* f = file_util::OpenFile(std::string(filename), "rb");
    if (!f)
      return false;

    std::vector<unsigned char> compressed;
    const int buf_size = 1024;
    unsigned char buf[buf_size];
    size_t num_read = 0;
    while ((num_read = fread(buf, 1, buf_size, f)) > 0) {
      std::copy(buf, &buf[num_read], std::back_inserter(compressed));
    }

    file_util::CloseFile(f);

    if (!PNGDecoder::Decode(&compressed[0], compressed.size(),
                          PNGDecoder::FORMAT_RGBA, &data_, &w_, &h_)) {
      Clear();
      return false;
    }
    return true;
  }

  void Clear() {
    w_ = h_ = 0;
    data_.clear();
  }

  // Returns the RGBA value of the pixel at the given location
  uint32 pixel_at(int x, int y) const {
    DCHECK(x >= 0 && x < w_);
    DCHECK(y >= 0 && y < h_);
    return data_[(y * w_ + x) * 4];
  }

 private:
  // pixel dimensions of the image
  int w_, h_;

  std::vector<unsigned char> data_;
};

float PercentageDifferent(const Image& baseline, const Image& actual) {
  int w = std::min(baseline.w(), actual.w());
  int h = std::min(baseline.h(), actual.h());

  // compute pixels different in the overlap
  int pixels_different = 0;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      if (baseline.pixel_at(x, y) != actual.pixel_at(x, y))
        pixels_different++;
    }
  }

  // count pixels that are a difference in size as also being different
  int max_w = std::max(baseline.w(), actual.w());
  int max_h = std::max(baseline.h(), actual.h());

  // ...pixels off the right side, but not including the lower right corner
  pixels_different += (max_w - w) * h;

  // ...pixels along the bottom, including the lower right corner
  pixels_different += (max_h - h) * max_w;

  // Like the WebKit ImageDiff tool, we define percentage different in terms
  // of the size of the 'actual' bitmap.
  float total_pixels = static_cast<float>(actual.w()) *
                       static_cast<float>(actual.h());
  if (total_pixels == 0)
    return 100.0f;  // when the bitmap is empty, they are 100% different
  return static_cast<float>(pixels_different) / total_pixels * 100;
}

void PrintHelp() {
  fprintf(stderr,
    "Usage:\n"
    "  image_diff <compare file> <reference file>\n"
    "    Compares two files on disk, returning 0 when they are the same\n"
    "  image_diff --use-stdin\n"
    "    Stays open reading pairs of filenames from stdin, comparing them,\n"
    "    and sending 0 to stdout when they are the same\n");
  /* For unfinished webkit-like-mode (see below)
    "\n"
    "  image_diff -s\n"
    "    Reads stream input from stdin, should be EXACTLY of the format\n"
    "    \"Content-length: <byte length> <data>Content-length: ...\n"
    "    it will take as many file pairs as given, and will compare them as\n"
    "    (cmp_file, reference_file) pairs\n");
  */
}

int CompareImages(const char* file1, const char* file2) {
  Image actual_image;
  Image baseline_image;

  if (!actual_image.CreateFromFilename(file1)) {
    fprintf(stderr, "image_diff: Unable to open file \"%s\"\n", file1);
    return kStatusError;
  }
  if (!baseline_image.CreateFromFilename(file2)) {
    fprintf(stderr, "image_diff: Unable to open file \"%s\"\n", file2);
    return kStatusError;
  }

  float percent = PercentageDifferent(actual_image, baseline_image);
  if (percent > 0.0) {
    // failure: The WebKit version also writes the difference image to
    // stdout, which seems excessive for our needs.
    printf("diff: %01.2f%% failed\n", percent);
    return kStatusDifferent;
  }

  // success
  printf("diff: %01.2f%% passed\n", percent);
  return kStatusSame;

/* Untested mode that acts like WebKit's image comparator. I wrote this but
   decided it's too complicated. We may use it in the future if it looks useful

  char buffer[2048];
  while (fgets(buffer, sizeof(buffer), stdin)) {

    if (strncmp("Content-length: ", buffer, 16) == 0) {
      char* context;
      strtok_s(buffer, " ", &context);
      int image_size = strtol(strtok_s(NULL, " ", &context), NULL, 10);

      bool success = false;
      if (image_size > 0 && actual_image.has_image() == 0) {
        if (!actual_image.CreateFromStdin(image_size)) {
          fputs("Error, input image can't be decoded.\n", stderr);
          return 1;
        }
      } else if (image_size > 0 && baseline_image.has_image() == 0) {
        if (!baseline_image.CreateFromStdin(image_size)) {
          fputs("Error, baseline image can't be decoded.\n", stderr);
          return 1;
        }
      } else {
        fputs("Error, image size must be specified.\n", stderr);
        return 1;
      }
    }

    if (actual_image.has_image() && baseline_image.has_image()) {
      float percent = PercentageDifferent(actual_image, baseline_image);
      if (percent > 0.0) {
        // failure: The WebKit version also writes the difference image to
        // stdout, which seems excessive for our needs.
        printf("diff: %01.2f%% failed\n", percent);
      } else {
        // success
        printf("diff: %01.2f%% passed\n", percent);
      }
      actual_image.Clear();
      baseline_image.Clear();
    }

    fflush(stdout);
  }
*/
}

int main(int argc, const char* argv[]) {
  process_util::EnableTerminationOnHeapCorruption();
  CommandLine parsed_command_line;
  if (parsed_command_line.HasSwitch(kOptionPollStdin)) {
    // Watch stdin for filenames.
    char stdin_buffer[2048];
    char filename1_buffer[2048];
    bool have_filename1 = false;
    while (fgets(stdin_buffer, sizeof(stdin_buffer), stdin)) {
      char *newLine = strchr(stdin_buffer, '\n');
      if (newLine)
        *newLine = '\0';
      if (!*stdin_buffer)
        continue;

      if (have_filename1) {
        // CompareImages writes results to stdout unless an error occurred.
        if (CompareImages(filename1_buffer, stdin_buffer) == kStatusError)
          printf("error\n");
        fflush(stdout);
        have_filename1 = false;
      } else {
        // Save the first filename in another buffer and wait for the second
        // filename to arrive via stdin.
        strcpy_s(filename1_buffer, sizeof(filename1_buffer), stdin_buffer);
        have_filename1 = true;
      }
    }
    return 0;
  }

  if (argc == 3) {
    return CompareImages(argv[1], argv[2]);
  }

  PrintHelp();
  return kStatusError;
}

<commit_msg>Fix build errors on Linux. Review URL: http://codereview.chromium.org/6047<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file input format is based loosely on
// WebKitTools/DumpRenderTree/ImageDiff.m

// The exact format of this tool's output to stdout is important, to match
// what the run-webkit-tests script expects.

#include <algorithm>
#include <vector>
#include <string>
#include <iostream>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/gfx/png_decoder.h"
#include "base/logging.h"
#include "base/process_util.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"

// Causes the app to remain open, waiting for pairs of filenames on stdin.
// The caller is then responsible for terminating this app.
static const wchar_t kOptionPollStdin[] = L"use-stdin";

// Return codes used by this utility.
static const int kStatusSame = 0;
static const int kStatusDifferent = 1;
static const int kStatusError = 2;

class Image {
 public:
  Image() : w_(0), h_(0) {
  }

  bool has_image() const {
    return w_ > 0 && h_ > 0;
  }

  int w() const {
    return w_;
  }

  int h() const {
    return h_;
  }

  // Creates the image from stdin with the given data length. On success, it
  // will return true. On failure, no other methods should be accessed.
  bool CreateFromStdin(size_t byte_length) {
    if (byte_length == 0)
      return false;

    scoped_array<unsigned char> source(new unsigned char[byte_length]);
    if (fread(source.get(), 1, byte_length, stdin) != byte_length)
      return false;

    if (!PNGDecoder::Decode(source.get(), byte_length, PNGDecoder::FORMAT_RGBA,
                          &data_, &w_, &h_)) {
      Clear();
      return false;
    }
    return true;
  }

  // Creates the image from the given filename on disk, and returns true on
  // success.
  bool CreateFromFilename(const char* filename) {
    FILE* f = file_util::OpenFile(std::string(filename), "rb");
    if (!f)
      return false;

    std::vector<unsigned char> compressed;
    const int buf_size = 1024;
    unsigned char buf[buf_size];
    size_t num_read = 0;
    while ((num_read = fread(buf, 1, buf_size, f)) > 0) {
      std::copy(buf, &buf[num_read], std::back_inserter(compressed));
    }

    file_util::CloseFile(f);

    if (!PNGDecoder::Decode(&compressed[0], compressed.size(),
                          PNGDecoder::FORMAT_RGBA, &data_, &w_, &h_)) {
      Clear();
      return false;
    }
    return true;
  }

  void Clear() {
    w_ = h_ = 0;
    data_.clear();
  }

  // Returns the RGBA value of the pixel at the given location
  uint32 pixel_at(int x, int y) const {
    DCHECK(x >= 0 && x < w_);
    DCHECK(y >= 0 && y < h_);
    return data_[(y * w_ + x) * 4];
  }

 private:
  // pixel dimensions of the image
  int w_, h_;

  std::vector<unsigned char> data_;
};

float PercentageDifferent(const Image& baseline, const Image& actual) {
  int w = std::min(baseline.w(), actual.w());
  int h = std::min(baseline.h(), actual.h());

  // compute pixels different in the overlap
  int pixels_different = 0;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      if (baseline.pixel_at(x, y) != actual.pixel_at(x, y))
        pixels_different++;
    }
  }

  // count pixels that are a difference in size as also being different
  int max_w = std::max(baseline.w(), actual.w());
  int max_h = std::max(baseline.h(), actual.h());

  // ...pixels off the right side, but not including the lower right corner
  pixels_different += (max_w - w) * h;

  // ...pixels along the bottom, including the lower right corner
  pixels_different += (max_h - h) * max_w;

  // Like the WebKit ImageDiff tool, we define percentage different in terms
  // of the size of the 'actual' bitmap.
  float total_pixels = static_cast<float>(actual.w()) *
                       static_cast<float>(actual.h());
  if (total_pixels == 0)
    return 100.0f;  // when the bitmap is empty, they are 100% different
  return static_cast<float>(pixels_different) / total_pixels * 100;
}

void PrintHelp() {
  fprintf(stderr,
    "Usage:\n"
    "  image_diff <compare file> <reference file>\n"
    "    Compares two files on disk, returning 0 when they are the same\n"
    "  image_diff --use-stdin\n"
    "    Stays open reading pairs of filenames from stdin, comparing them,\n"
    "    and sending 0 to stdout when they are the same\n");
  /* For unfinished webkit-like-mode (see below)
    "\n"
    "  image_diff -s\n"
    "    Reads stream input from stdin, should be EXACTLY of the format\n"
    "    \"Content-length: <byte length> <data>Content-length: ...\n"
    "    it will take as many file pairs as given, and will compare them as\n"
    "    (cmp_file, reference_file) pairs\n");
  */
}

int CompareImages(const char* file1, const char* file2) {
  Image actual_image;
  Image baseline_image;

  if (!actual_image.CreateFromFilename(file1)) {
    fprintf(stderr, "image_diff: Unable to open file \"%s\"\n", file1);
    return kStatusError;
  }
  if (!baseline_image.CreateFromFilename(file2)) {
    fprintf(stderr, "image_diff: Unable to open file \"%s\"\n", file2);
    return kStatusError;
  }

  float percent = PercentageDifferent(actual_image, baseline_image);
  if (percent > 0.0) {
    // failure: The WebKit version also writes the difference image to
    // stdout, which seems excessive for our needs.
    printf("diff: %01.2f%% failed\n", percent);
    return kStatusDifferent;
  }

  // success
  printf("diff: %01.2f%% passed\n", percent);
  return kStatusSame;

/* Untested mode that acts like WebKit's image comparator. I wrote this but
   decided it's too complicated. We may use it in the future if it looks useful

  char buffer[2048];
  while (fgets(buffer, sizeof(buffer), stdin)) {

    if (strncmp("Content-length: ", buffer, 16) == 0) {
      char* context;
      strtok_s(buffer, " ", &context);
      int image_size = strtol(strtok_s(NULL, " ", &context), NULL, 10);

      bool success = false;
      if (image_size > 0 && actual_image.has_image() == 0) {
        if (!actual_image.CreateFromStdin(image_size)) {
          fputs("Error, input image can't be decoded.\n", stderr);
          return 1;
        }
      } else if (image_size > 0 && baseline_image.has_image() == 0) {
        if (!baseline_image.CreateFromStdin(image_size)) {
          fputs("Error, baseline image can't be decoded.\n", stderr);
          return 1;
        }
      } else {
        fputs("Error, image size must be specified.\n", stderr);
        return 1;
      }
    }

    if (actual_image.has_image() && baseline_image.has_image()) {
      float percent = PercentageDifferent(actual_image, baseline_image);
      if (percent > 0.0) {
        // failure: The WebKit version also writes the difference image to
        // stdout, which seems excessive for our needs.
        printf("diff: %01.2f%% failed\n", percent);
      } else {
        // success
        printf("diff: %01.2f%% passed\n", percent);
      }
      actual_image.Clear();
      baseline_image.Clear();
    }

    fflush(stdout);
  }
*/
}

int main(int argc, const char* argv[]) {
  process_util::EnableTerminationOnHeapCorruption();
  CommandLine parsed_command_line;
  if (parsed_command_line.HasSwitch(kOptionPollStdin)) {
    // Watch stdin for filenames.
    std::string stdin_buffer;
    std::string filename1_buffer;
    bool have_filename1 = false;
    while (std::getline(std::cin, stdin_buffer)) {
      if (stdin_buffer.empty())
        continue;

      if (have_filename1) {
        // CompareImages writes results to stdout unless an error occurred.
        if (CompareImages(filename1_buffer.c_str(), stdin_buffer.c_str()) ==
            kStatusError)
          printf("error\n");
        fflush(stdout);
        have_filename1 = false;
      } else {
        // Save the first filename in another buffer and wait for the second
        // filename to arrive via stdin.
        filename1_buffer = stdin_buffer;
        have_filename1 = true;
      }
    }
    return 0;
  }

  if (argc == 3) {
    return CompareImages(argv[1], argv[2]);
  }

  PrintHelp();
  return kStatusError;
}
<|endoftext|>


<commit_before>#ifndef TOOLBOX_TEXT_FILE_HPP
#define TOOLBOX_TEXT_FILE_HPP

#include <toolbox/cpp/filesystem.hpp>
#include <fstream>
#include <streambuf>

namespace toolbox::text_file
{

std::string load(std::ifstream &file)
{
    std::string result;

    file.seekg(0, std::ios::end);
    result.reserve(file.tellg());
    file.seekg(0, std::ios::beg);

    result.assign(std::istreambuf_iterator<char>(file),
                  std::istreambuf_iterator<char>());
    return result;
}

std::string load(toolbox::fs::path path)
{
    std::ifstream ifs{path};
    return load(ifs);
}

void save(std::ofstream &file, const std::string &str)
{
    file.write(str.data(), str.size());
}

void save(fs::path path, const std::string &str)
{
    std::ofstream ofs{path};
    save(ofs, str);
}

} // namespace toolbox::text_file

#endif // TOOLBOX_TEXT_FILE_HPP<commit_msg>mark text_file functions as inline<commit_after>#ifndef TOOLBOX_TEXT_FILE_HPP
#define TOOLBOX_TEXT_FILE_HPP

#include <toolbox/cpp/filesystem.hpp>
#include <fstream>
#include <streambuf>

namespace toolbox::text_file
{

inline std::string load(std::ifstream &file)
{
    std::string result;

    file.seekg(0, std::ios::end);
    result.reserve(file.tellg());
    file.seekg(0, std::ios::beg);

    result.assign(std::istreambuf_iterator<char>(file),
                  std::istreambuf_iterator<char>());
    return result;
}

inline std::string load(toolbox::fs::path path)
{
    std::ifstream ifs{path};
    return load(ifs);
}

inline void save(std::ofstream &file, const std::string &str)
{
    file.write(str.data(), str.size());
}

inline void save(fs::path path, const std::string &str)
{
    std::ofstream ofs{path};
    save(ofs, str);
}

} // namespace toolbox::text_file

#endif // TOOLBOX_TEXT_FILE_HPP<|endoftext|>


<commit_before>/*
    Include this to include practically all of tudocomp.

    This header also contains the Doxygen documentation of the main namespaces.
*/

#ifndef _INCLUDED_TUDOCOMP_HPP
#define _INCLUDED_TUDOCOMP_HPP

/// \brief Contains the text compression and encoding framework.
///
/// This is the framework's central namespace in which text compression and
/// coding algorithms are contained, as well as utilities needed for text
/// compression and coding (e.g. I/O). Families of compressors and encoders
/// or utility groups are contained in the respective sub-namespaces. The
/// namespace \c tudocomp itself contains types important for all of the
/// framework and its communication.
namespace tdc {

/// \brief Contains I/O abstractions and utilities.
///
/// All I/O done by compressors and encoders is routed through the \ref Input
/// and \ref Output abstractions over the underlying file, memory or stream
/// I/O.
///
/// \sa
/// \ref Input for the input interface and \ref Output for the output
/// interface.
namespace io {
}

/// \brief Contains compressors and encoders that work with Lempel-Ziv-78-like
/// dictionaries.
///
/// The LZ78 family works with bottom-up dictionaries containing indexed
/// entries to achieve compression. Each entry points to a \e prefix (another
/// dictionary entry) and a follow-up symbol.
namespace lz78 {
}

/// \brief Contains compressors and encoders that work with
/// Lempel-Ziv-Storer-Szymansky-like factors.
///
/// The LZSS family works with factors representing references to positions
/// within the original text that replace parts of the same text, effectively
/// using the input text itself as a dictionary. They consist of a \e source
/// text position and a \e length.
namespace lzss {
}

/// \brief Contains compressors and encoders that work with
/// Lempel-Ziv-Welch-like dictionaries.
///
/// The LZW family works with bottom-up dictionaries containing indexed entries
/// to achieve compression. Other than \ref lz78, the dictionary entries do not
/// explicitly store the follow-up symbol. Instead, they are re-generated on
/// the fly by the decoder.
namespace lzw {
}

} //namespace tdc

// Include f'in everything!
#include <glog/logging.h>
#include <sdsl/int_vector.hpp>

#include <tudocomp/io.hpp>
#include <tudocomp/util.hpp>

#include <tudocomp/Algorithm.hpp>
#include <tudocomp/ChainCompressor.hpp>
#include <tudocomp/Compressor.hpp>
#include <tudocomp/Env.hpp>
#include <tudocomp/Registry.hpp>
#include <tudocomp/CreateAlgorithm.hpp>

#include <tudocomp/util/Counter.hpp>
#include <tudocomp/util/DecodeBuffer.hpp>

#include <tudocomp/ds/TextDS.hpp>
#include <tudocomp/ds/SuffixArray.hpp>
#include <tudocomp/ds/InverseSuffixArray.hpp>
#include <tudocomp/ds/PhiArray.hpp>
#include <tudocomp/ds/LCPArray.hpp>
#include <tudocomp/ds/uint_t.hpp>

#include <tudocomp/Range.hpp>
#include <tudocomp/coders/ASCIICoder.hpp>
#include <tudocomp/coders/ByteCoder.hpp>
#include <tudocomp/coders/BitOptimalCoder.hpp>
#include <tudocomp/coders/HuffmanCoder.hpp>
#include <tudocomp/coders/VariantCoder.hpp>
#include <tudocomp/LiteralEncoder.hpp>
#include <tudocomp/compressors/ESACompressor.hpp>
#include <tudocomp/compressors/LZ78Compressor.hpp>
#include <tudocomp/compressors/LZSSLCPCompressor.hpp>
#include <tudocomp/compressors/LZSSSlidingWindowCompressor.hpp>
#include <tudocomp/compressors/LZWCompressor.hpp>
#include <tudocomp/compressors/RunLengthEncoder.hpp>

#endif

<commit_msg>Add def.hpp include to tudocomp.hpp<commit_after>/*
    Include this to include practically all of tudocomp.

    This header also contains the Doxygen documentation of the main namespaces.
*/

#ifndef _INCLUDED_TUDOCOMP_HPP
#define _INCLUDED_TUDOCOMP_HPP

/// \brief Contains the text compression and encoding framework.
///
/// This is the framework's central namespace in which text compression and
/// coding algorithms are contained, as well as utilities needed for text
/// compression and coding (e.g. I/O). Families of compressors and encoders
/// or utility groups are contained in the respective sub-namespaces. The
/// namespace \c tudocomp itself contains types important for all of the
/// framework and its communication.
namespace tdc {

/// \brief Contains I/O abstractions and utilities.
///
/// All I/O done by compressors and encoders is routed through the \ref Input
/// and \ref Output abstractions over the underlying file, memory or stream
/// I/O.
///
/// \sa
/// \ref Input for the input interface and \ref Output for the output
/// interface.
namespace io {
}

/// \brief Contains compressors and encoders that work with Lempel-Ziv-78-like
/// dictionaries.
///
/// The LZ78 family works with bottom-up dictionaries containing indexed
/// entries to achieve compression. Each entry points to a \e prefix (another
/// dictionary entry) and a follow-up symbol.
namespace lz78 {
}

/// \brief Contains compressors and encoders that work with
/// Lempel-Ziv-Storer-Szymansky-like factors.
///
/// The LZSS family works with factors representing references to positions
/// within the original text that replace parts of the same text, effectively
/// using the input text itself as a dictionary. They consist of a \e source
/// text position and a \e length.
namespace lzss {
}

/// \brief Contains compressors and encoders that work with
/// Lempel-Ziv-Welch-like dictionaries.
///
/// The LZW family works with bottom-up dictionaries containing indexed entries
/// to achieve compression. Other than \ref lz78, the dictionary entries do not
/// explicitly store the follow-up symbol. Instead, they are re-generated on
/// the fly by the decoder.
namespace lzw {
}

} //namespace tdc

// Include f'in everything!
#include <glog/logging.h>
#include <sdsl/int_vector.hpp>

#include <tudocomp/def.hpp>
#include <tudocomp/io.hpp>
#include <tudocomp/util.hpp>

#include <tudocomp/Algorithm.hpp>
#include <tudocomp/ChainCompressor.hpp>
#include <tudocomp/Compressor.hpp>
#include <tudocomp/Env.hpp>
#include <tudocomp/Registry.hpp>
#include <tudocomp/CreateAlgorithm.hpp>

#include <tudocomp/util/Counter.hpp>
#include <tudocomp/util/DecodeBuffer.hpp>

#include <tudocomp/ds/TextDS.hpp>
#include <tudocomp/ds/SuffixArray.hpp>
#include <tudocomp/ds/InverseSuffixArray.hpp>
#include <tudocomp/ds/PhiArray.hpp>
#include <tudocomp/ds/LCPArray.hpp>
#include <tudocomp/ds/uint_t.hpp>

#include <tudocomp/Range.hpp>
#include <tudocomp/coders/ASCIICoder.hpp>
#include <tudocomp/coders/ByteCoder.hpp>
#include <tudocomp/coders/BitOptimalCoder.hpp>
#include <tudocomp/coders/HuffmanCoder.hpp>
#include <tudocomp/coders/VariantCoder.hpp>
#include <tudocomp/LiteralEncoder.hpp>
#include <tudocomp/compressors/ESACompressor.hpp>
#include <tudocomp/compressors/LZ78Compressor.hpp>
#include <tudocomp/compressors/LZSSLCPCompressor.hpp>
#include <tudocomp/compressors/LZSSSlidingWindowCompressor.hpp>
#include <tudocomp/compressors/LZWCompressor.hpp>
#include <tudocomp/compressors/RunLengthEncoder.hpp>

#endif

<|endoftext|>


<commit_before>/**
 * @file llworldview.cpp
 * @brief LLWorldView class implementation
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 *
 * Copyright (c) 2001-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llworldview.h"

#include "llviewercontrol.h"
#include "llsidetray.h"
/////////////////////////////////////////////////////
// LLFloaterView

static LLDefaultChildRegistry::Register<LLWorldView> r("world_view");

LLWorldView::LLWorldView(const Params& p)
:	LLUICtrl (p)
{
}

void LLWorldView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
	if (FALSE == gSavedSettings.getBOOL("SidebarCameraMovement") )
	{
		LLView* main_view = LLUI::getRootView()->findChild<LLView>("main_view");
		if(main_view)
		{
			width = main_view->getRect().getWidth();
		}
	}

	LLUICtrl::reshape(width, height, called_from_parent);
}
<commit_msg>gah, dos2unix this file<commit_after>/**
 * @file llworldview.cpp
 * @brief LLWorldView class implementation
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 *
 * Copyright (c) 2001-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llworldview.h"

#include "llviewercontrol.h"
#include "llsidetray.h"
/////////////////////////////////////////////////////
// LLFloaterView

static LLDefaultChildRegistry::Register<LLWorldView> r("world_view");

LLWorldView::LLWorldView(const Params& p)
:	LLUICtrl (p)
{
}

void LLWorldView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
	if (FALSE == gSavedSettings.getBOOL("SidebarCameraMovement") )
	{
		LLView* main_view = LLUI::getRootView()->findChild<LLView>("main_view");
		if(main_view)
		{
			width = main_view->getRect().getWidth();
		}
	}

	LLUICtrl::reshape(width, height, called_from_parent);
}
<|endoftext|>