<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <stdint.h>
#include "parse_primitives.h"
#include "v_array.h"
#include "example.h"
#include "simple_label.h"
#include "gd.h"
#include "global_data.h"
#include "memory.h"

int compare_feature(const void* p1, const void* p2) {
  feature* f1 = (feature*) p1;
  feature* f2 = (feature*) p2;
  return (f1->weight_index - f2->weight_index);
}

float collision_cleanup(v_array<feature>& feature_map) {

 int pos = 0;
 float sum_sq = 0.;

 for(uint32_t i = 1;i < feature_map.size();i++) {
    if(feature_map[i].weight_index == feature_map[pos].weight_index)
      feature_map[pos].x += feature_map[i].x;
    else {
      sum_sq += feature_map[pos].x*feature_map[pos].x;
      feature_map[++pos] = feature_map[i];
    }
  }
  sum_sq += feature_map[pos].x*feature_map[pos].x;
  feature_map.end = &(feature_map[pos]);
  feature_map.end++;
  return sum_sq;
}

struct features_and_source
{
  v_array<feature> feature_map; //map to store sparse feature vectors
  uint32_t stride_shift;
  weight* base;
};

void vec_store(features_and_source& p, float fx, float& fw) {
  feature f = {fx, (uint32_t)(&fw - p.base) >> p.stride_shift};
  p.feature_map.push_back(f);
}

namespace VW {

flat_example* flatten_example(vw& all, example *ec)
{
	flat_example* fec = (flat_example*) calloc_or_die(1,sizeof(flat_example));
	fec->ld = ec->ld;

	fec->tag_len = ec->tag.size();
	if (fec->tag_len >0)
	{
		fec->tag = ec->tag.begin;
	}

	fec->example_counter = ec->example_counter;
	fec->ft_offset = ec->ft_offset;
	fec->num_features = ec->num_features;

	features_and_source fs;
	fs.base = all.reg.weight_vector;
	fs.stride_shift = all.reg.stride_shift;
	GD::foreach_feature<features_and_source, vec_store>(all, *ec, fs);
	qsort(fs.feature_map.begin, fs.feature_map.size(), sizeof(feature), compare_feature);

	fec->feature_map_len = fs.feature_map.size();
	if (fec->feature_map_len > 0)
	{
		fec->feature_map = fs.feature_map.begin;
	}

	return fec;
}

void free_flatten_example(flat_example* fec)
{
	if (fec)
		free(fec);
}

}

example *alloc_examples(size_t label_size, size_t count=1)
{
  example* ec = (example*)calloc_or_die(count, sizeof(example));
  if (ec == NULL) return NULL;
  for (size_t i=0; i<count; i++) {
    ec[i].ld = calloc_or_die(1, label_size);
    if (ec[i].ld == NULL) {
      for (size_t j=0; j<i; j++) free(ec[j].ld);
      free(ec);
      return NULL;
    }
    ec[i].in_use = true;
    ec[i].ft_offset = 0;
    //  std::cerr << "  alloc_example.indices.begin=" << ec->indices.begin << " end=" << ec->indices.end << " // ld = " << ec->ld << "\t|| me = " << ec << std::endl;
  }
  return ec;
}

void dealloc_example(void(*delete_label)(void*), example&ec)
{
  if (delete_label) {
    delete_label(ec.ld);
  }
  ec.tag.delete_v();

  ec.topic_predictions.delete_v();

  free(ec.ld);
  for (size_t j = 0; j < 256; j++)
    {
      ec.atomics[j].delete_v();

      if (ec.audit_features[j].begin != ec.audit_features[j].end_array)
        {
          for (audit_data* temp = ec.audit_features[j].begin;
               temp != ec.audit_features[j].end; temp++)
            if (temp->alloced) {
              free(temp->space);
              free(temp->feature);
              temp->alloced = false;
            }
	  ec.audit_features[j].delete_v();
        }
    }
  ec.indices.delete_v();
}

audit_data copy_audit_data(audit_data &src) {
  audit_data dst;
  dst.space = (char*)calloc_or_die(strlen(src.space)+1, sizeof(char));
  strcpy(dst.space, src.space);
  dst.feature = (char*)calloc_or_die(strlen(src.feature)+1, sizeof(char));
  strcpy(dst.feature, src.feature);
  dst.weight_index = src.weight_index;
  dst.x = src.x;
  dst.alloced = src.alloced;
  return dst;
}

namespace VW {
void copy_example_label(example*dst, example*src, size_t label_size, void(*copy_label)(void*&,void*)) {
  if (!src->ld) {
    if (dst->ld) free(dst->ld);  // TODO: this should be a delete_label, really
    dst->ld = NULL;
  } else {
    if ((label_size == 0) && (copy_label == NULL)) {
      if (dst->ld) free(dst->ld);  // TODO: this should be a delete_label, really
      dst->ld = NULL;
    } else if (copy_label) {
      copy_label(dst->ld, src->ld);
    } else {
      //dst->ld = (void*)malloc(label_size);
      memcpy(dst->ld, src->ld, label_size);
    }
  }
}

void copy_example_data(bool audit, example* dst, example* src)
{
  //std::cerr << "copy_example_data dst = " << dst << std::endl;
  copy_array(dst->tag, src->tag);
  dst->example_counter = src->example_counter;

  copy_array(dst->indices, src->indices);
  for (size_t i=0; i<256; i++)
    copy_array(dst->atomics[i], src->atomics[i]);
  dst->ft_offset = src->ft_offset;

  if (audit)
    for (size_t i=0; i<256; i++)
      copy_array(dst->audit_features[i], src->audit_features[i], copy_audit_data);

  dst->num_features = src->num_features;
  dst->partial_prediction = src->partial_prediction;
  copy_array(dst->topic_predictions, src->topic_predictions);
  dst->loss = src->loss;
  dst->eta_round = src->eta_round;
  dst->eta_global = src->eta_global;
  dst->example_t = src->example_t;
  memcpy(dst->sum_feat_sq, src->sum_feat_sq, 256 * sizeof(float));
  dst->total_sum_feat_sq = src->total_sum_feat_sq;
  dst->revert_weight = src->revert_weight;
  dst->test_only = src->test_only;
  dst->end_pass = src->end_pass;
  dst->sorted = src->sorted;
  dst->in_use = src->in_use;}

void copy_example_data(bool audit, example* dst, example* src, size_t label_size, void(*copy_label)(void*&,void*)) {
  copy_example_data(audit, dst, src);
  copy_example_label(dst, src, label_size, copy_label);
}
}
<commit_msg>fix free_flatten_example<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <stdint.h>
#include "parse_primitives.h"
#include "v_array.h"
#include "example.h"
#include "simple_label.h"
#include "gd.h"
#include "global_data.h"
#include "memory.h"

int compare_feature(const void* p1, const void* p2) {
  feature* f1 = (feature*) p1;
  feature* f2 = (feature*) p2;
  return (f1->weight_index - f2->weight_index);
}

float collision_cleanup(v_array<feature>& feature_map) {

 int pos = 0;
 float sum_sq = 0.;

 for(uint32_t i = 1;i < feature_map.size();i++) {
    if(feature_map[i].weight_index == feature_map[pos].weight_index)
      feature_map[pos].x += feature_map[i].x;
    else {
      sum_sq += feature_map[pos].x*feature_map[pos].x;
      feature_map[++pos] = feature_map[i];
    }
  }
  sum_sq += feature_map[pos].x*feature_map[pos].x;
  feature_map.end = &(feature_map[pos]);
  feature_map.end++;
  return sum_sq;
}

struct features_and_source
{
  v_array<feature> feature_map; //map to store sparse feature vectors
  uint32_t stride_shift;
  weight* base;
};

void vec_store(features_and_source& p, float fx, float& fw) {
  feature f = {fx, (uint32_t)(&fw - p.base) >> p.stride_shift};
  p.feature_map.push_back(f);
}

namespace VW {

flat_example* flatten_example(vw& all, example *ec)
{
	flat_example* fec = (flat_example*) calloc_or_die(1,sizeof(flat_example));
	fec->ld = ec->ld;

	fec->tag_len = ec->tag.size();
	if (fec->tag_len >0)
	{
		fec->tag = ec->tag.begin;
	}

	fec->example_counter = ec->example_counter;
	fec->ft_offset = ec->ft_offset;
	fec->num_features = ec->num_features;

	features_and_source fs;
	fs.base = all.reg.weight_vector;
	fs.stride_shift = all.reg.stride_shift;
	GD::foreach_feature<features_and_source, vec_store>(all, *ec, fs);
	qsort(fs.feature_map.begin, fs.feature_map.size(), sizeof(feature), compare_feature);

	fec->feature_map_len = fs.feature_map.size();
	if (fec->feature_map_len > 0)
	{
		fec->feature_map = fs.feature_map.begin;
	}

	return fec;
}

void free_flatten_example(flat_example* fec)
{  //note: The label memory should be freed by by freeing the original example.
  if (fec)
    {
      if (fec->feature_map_len > 0)
	free(fec->feature_map);
      free(fec);
    }
}

}

example *alloc_examples(size_t label_size, size_t count=1)
{
  example* ec = (example*)calloc_or_die(count, sizeof(example));
  if (ec == NULL) return NULL;
  for (size_t i=0; i<count; i++) {
    ec[i].ld = calloc_or_die(1, label_size);
    if (ec[i].ld == NULL) {
      for (size_t j=0; j<i; j++) free(ec[j].ld);
      free(ec);
      return NULL;
    }
    ec[i].in_use = true;
    ec[i].ft_offset = 0;
    //  std::cerr << "  alloc_example.indices.begin=" << ec->indices.begin << " end=" << ec->indices.end << " // ld = " << ec->ld << "\t|| me = " << ec << std::endl;
  }
  return ec;
}

void dealloc_example(void(*delete_label)(void*), example&ec)
{
  if (delete_label) {
    delete_label(ec.ld);
  }
  ec.tag.delete_v();

  ec.topic_predictions.delete_v();

  free(ec.ld);
  for (size_t j = 0; j < 256; j++)
    {
      ec.atomics[j].delete_v();

      if (ec.audit_features[j].begin != ec.audit_features[j].end_array)
        {
          for (audit_data* temp = ec.audit_features[j].begin;
               temp != ec.audit_features[j].end; temp++)
            if (temp->alloced) {
              free(temp->space);
              free(temp->feature);
              temp->alloced = false;
            }
	  ec.audit_features[j].delete_v();
        }
    }
  ec.indices.delete_v();
}

audit_data copy_audit_data(audit_data &src) {
  audit_data dst;
  dst.space = (char*)calloc_or_die(strlen(src.space)+1, sizeof(char));
  strcpy(dst.space, src.space);
  dst.feature = (char*)calloc_or_die(strlen(src.feature)+1, sizeof(char));
  strcpy(dst.feature, src.feature);
  dst.weight_index = src.weight_index;
  dst.x = src.x;
  dst.alloced = src.alloced;
  return dst;
}

namespace VW {
void copy_example_label(example*dst, example*src, size_t label_size, void(*copy_label)(void*&,void*)) {
  if (!src->ld) {
    if (dst->ld) free(dst->ld);  // TODO: this should be a delete_label, really
    dst->ld = NULL;
  } else {
    if ((label_size == 0) && (copy_label == NULL)) {
      if (dst->ld) free(dst->ld);  // TODO: this should be a delete_label, really
      dst->ld = NULL;
    } else if (copy_label) {
      copy_label(dst->ld, src->ld);
    } else {
      //dst->ld = (void*)malloc(label_size);
      memcpy(dst->ld, src->ld, label_size);
    }
  }
}

void copy_example_data(bool audit, example* dst, example* src)
{
  //std::cerr << "copy_example_data dst = " << dst << std::endl;
  copy_array(dst->tag, src->tag);
  dst->example_counter = src->example_counter;

  copy_array(dst->indices, src->indices);
  for (size_t i=0; i<256; i++)
    copy_array(dst->atomics[i], src->atomics[i]);
  dst->ft_offset = src->ft_offset;

  if (audit)
    for (size_t i=0; i<256; i++)
      copy_array(dst->audit_features[i], src->audit_features[i], copy_audit_data);

  dst->num_features = src->num_features;
  dst->partial_prediction = src->partial_prediction;
  copy_array(dst->topic_predictions, src->topic_predictions);
  dst->loss = src->loss;
  dst->eta_round = src->eta_round;
  dst->eta_global = src->eta_global;
  dst->example_t = src->example_t;
  memcpy(dst->sum_feat_sq, src->sum_feat_sq, 256 * sizeof(float));
  dst->total_sum_feat_sq = src->total_sum_feat_sq;
  dst->revert_weight = src->revert_weight;
  dst->test_only = src->test_only;
  dst->end_pass = src->end_pass;
  dst->sorted = src->sorted;
  dst->in_use = src->in_use;}

void copy_example_data(bool audit, example* dst, example* src, size_t label_size, void(*copy_label)(void*&,void*)) {
  copy_example_data(audit, dst, src);
  copy_example_label(dst, src, label_size, copy_label);
}
}
<|endoftext|>


<commit_before>/* 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/. */

#include <algorithm>
#include <sys/stat.h>
#include <cstring>
#include <zlib.h>
#include <fcntl.h>
#include <errno.h>
#include "mozilla/Assertions.h"
#include "SeekableZStream.h"
#include "Utils.h"
#include "Logging.h"

static const size_t CHUNK = 16384;

/* Generate a seekable compressed stream. */

int main(int argc, char* argv[])
{
  if (argc != 3 || !argv[1] || !argv[2] || (strcmp(argv[1], argv[2]) == 0)) {
    log("usage: %s file_to_compress out_file", argv[0]);
    return 1;
  }

  AutoCloseFD origFd = open(argv[1], O_RDONLY);
  if (origFd == -1) {
    log("Couldn't open %s: %s", argv[1], strerror(errno));
    return 1;
  }

  struct stat st;
  int ret = fstat(origFd, &st);
  if (ret == -1) {
    log("Couldn't seek %s: %s", argv[1], strerror(errno));
    return 1;
  }

  size_t origSize = st.st_size;
  log("Size = %lu", origSize);
  if (origSize == 0) {
    log("Won't compress %s: it's empty", argv[1]);
    return 1;
  }

  /* Mmap the original file */
  MappedPtr origBuf;
  origBuf.Assign(mmap(NULL, origSize, PROT_READ, MAP_PRIVATE, origFd, 0), origSize);
  if (origBuf == MAP_FAILED) {
    log("Couldn't mmap %s: %s", argv[1], strerror(errno));
    return 1;
  }

  /* Create the compressed file */
  AutoCloseFD outFd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (outFd == -1) {
    log("Couldn't open %s: %s", argv[2], strerror(errno));
    return 1;
  }

  /* Expected total number of chunks */
  size_t nChunks = ((origSize + CHUNK - 1) / CHUNK);

  /* The first chunk is going to be stored after the header and the offset
   * table */
  size_t offset = sizeof(SeekableZStreamHeader) + nChunks * sizeof(uint32_t);

  /* Give enough room for the header and the offset table, and map them */
  ret = posix_fallocate(outFd, 0, offset);
  MOZ_ASSERT(ret == 0);
  MappedPtr headerMap;
  headerMap.Assign(mmap(NULL, offset, PROT_READ | PROT_WRITE, MAP_SHARED,
                        outFd, 0), offset);
  if (headerMap == MAP_FAILED) {
    log("Couldn't mmap %s: %s", argv[1], strerror(errno));
    return 1;
  }

  SeekableZStreamHeader *header = new (headerMap) SeekableZStreamHeader;
  le_uint32 *entry = reinterpret_cast<le_uint32 *>(&header[1]);

  /* Initialize header */
  header->chunkSize = CHUNK;
  header->totalSize = offset;

  /* Seek at the end of the output file, where we're going to append
   * compressed streams */
  lseek(outFd, offset, SEEK_SET);

  /* Initialize zlib structure */
  z_stream zStream;
  memset(&zStream, 0, sizeof(zStream));

  /* Compression buffer */
  AutoDeleteArray<Bytef> outBuf = new Bytef[CHUNK * 2];

  Bytef *origData = static_cast<Bytef*>(origBuf);
  size_t avail = 0;
  while (origSize) {
    avail = std::min(origSize, CHUNK);

    /* Compress chunk */
    ret = deflateInit(&zStream, 9);
    MOZ_ASSERT(ret == Z_OK);
    zStream.avail_in = avail;
    zStream.next_in = origData;
    zStream.avail_out = CHUNK * 2;
    zStream.next_out = outBuf;
    ret = deflate(&zStream, Z_FINISH);
    MOZ_ASSERT(ret == Z_STREAM_END);
    ret = deflateEnd(&zStream);
    MOZ_ASSERT(ret == Z_OK);
    MOZ_ASSERT(zStream.avail_out > 0);

    /* Write chunk */
    size_t len = write(outFd, outBuf, 2 * CHUNK - zStream.avail_out);
    MOZ_ASSERT(len == 2 * CHUNK - zStream.avail_out);

    /* Adjust headers */
    header->totalSize += len;
    *entry++ = offset;
    header->nChunks++;

    /* Prepare for next iteration */
    origSize -= avail;
    origData += avail;
    offset += len;
  }
  header->lastChunkSize = avail;

  MOZ_ASSERT(header->nChunks == nChunks);
  log("Compressed size is %lu", offset);

  return 0;
}
<commit_msg>Bug 729596 - Use ftruncate in szip instead of posix_fallocate. r=taras<commit_after>/* 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/. */

#include <algorithm>
#include <sys/stat.h>
#include <cstring>
#include <zlib.h>
#include <fcntl.h>
#include <errno.h>
#include "mozilla/Assertions.h"
#include "SeekableZStream.h"
#include "Utils.h"
#include "Logging.h"

static const size_t CHUNK = 16384;

/* Generate a seekable compressed stream. */

int main(int argc, char* argv[])
{
  if (argc != 3 || !argv[1] || !argv[2] || (strcmp(argv[1], argv[2]) == 0)) {
    log("usage: %s file_to_compress out_file", argv[0]);
    return 1;
  }

  AutoCloseFD origFd = open(argv[1], O_RDONLY);
  if (origFd == -1) {
    log("Couldn't open %s: %s", argv[1], strerror(errno));
    return 1;
  }

  struct stat st;
  int ret = fstat(origFd, &st);
  if (ret == -1) {
    log("Couldn't seek %s: %s", argv[1], strerror(errno));
    return 1;
  }

  size_t origSize = st.st_size;
  log("Size = %lu", origSize);
  if (origSize == 0) {
    log("Won't compress %s: it's empty", argv[1]);
    return 1;
  }

  /* Mmap the original file */
  MappedPtr origBuf;
  origBuf.Assign(mmap(NULL, origSize, PROT_READ, MAP_PRIVATE, origFd, 0), origSize);
  if (origBuf == MAP_FAILED) {
    log("Couldn't mmap %s: %s", argv[1], strerror(errno));
    return 1;
  }

  /* Create the compressed file */
  AutoCloseFD outFd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (outFd == -1) {
    log("Couldn't open %s: %s", argv[2], strerror(errno));
    return 1;
  }

  /* Expected total number of chunks */
  size_t nChunks = ((origSize + CHUNK - 1) / CHUNK);

  /* The first chunk is going to be stored after the header and the offset
   * table */
  size_t offset = sizeof(SeekableZStreamHeader) + nChunks * sizeof(uint32_t);

  /* Give enough room for the header and the offset table, and map them */
  ret = ftruncate(outFd, offset);
  MOZ_ASSERT(ret == 0);
  MappedPtr headerMap;
  headerMap.Assign(mmap(NULL, offset, PROT_READ | PROT_WRITE, MAP_SHARED,
                        outFd, 0), offset);
  if (headerMap == MAP_FAILED) {
    log("Couldn't mmap %s: %s", argv[1], strerror(errno));
    return 1;
  }

  SeekableZStreamHeader *header = new (headerMap) SeekableZStreamHeader;
  le_uint32 *entry = reinterpret_cast<le_uint32 *>(&header[1]);

  /* Initialize header */
  header->chunkSize = CHUNK;
  header->totalSize = offset;

  /* Seek at the end of the output file, where we're going to append
   * compressed streams */
  lseek(outFd, offset, SEEK_SET);

  /* Initialize zlib structure */
  z_stream zStream;
  memset(&zStream, 0, sizeof(zStream));

  /* Compression buffer */
  AutoDeleteArray<Bytef> outBuf = new Bytef[CHUNK * 2];

  Bytef *origData = static_cast<Bytef*>(origBuf);
  size_t avail = 0;
  while (origSize) {
    avail = std::min(origSize, CHUNK);

    /* Compress chunk */
    ret = deflateInit(&zStream, 9);
    MOZ_ASSERT(ret == Z_OK);
    zStream.avail_in = avail;
    zStream.next_in = origData;
    zStream.avail_out = CHUNK * 2;
    zStream.next_out = outBuf;
    ret = deflate(&zStream, Z_FINISH);
    MOZ_ASSERT(ret == Z_STREAM_END);
    ret = deflateEnd(&zStream);
    MOZ_ASSERT(ret == Z_OK);
    MOZ_ASSERT(zStream.avail_out > 0);

    /* Write chunk */
    size_t len = write(outFd, outBuf, 2 * CHUNK - zStream.avail_out);
    MOZ_ASSERT(len == 2 * CHUNK - zStream.avail_out);

    /* Adjust headers */
    header->totalSize += len;
    *entry++ = offset;
    header->nChunks++;

    /* Prepare for next iteration */
    origSize -= avail;
    origData += avail;
    offset += len;
  }
  header->lastChunkSize = avail;

  MOZ_ASSERT(header->nChunks == nChunks);
  log("Compressed size is %lu", offset);

  return 0;
}
<|endoftext|>


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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3006
#endif  // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

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

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

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 2004540 by chui@ocl-promo-incrementor on 2019/09/26 03:00:40<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3007
#endif  // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

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

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

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include "test/config/utility.h"

#include "envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.pb.h"
#include "envoy/http/codec.h"

#include "common/common/assert.h"
#include "common/protobuf/utility.h"

#include "test/test_common/environment.h"
#include "test/test_common/network_utility.h"

namespace Envoy {

const std::string ConfigHelper::BASE_CONFIG = R"EOF(
admin:
  access_log_path: /dev/null
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 0
static_resources:
  clusters:
    name: cluster_0
    hosts:
      socket_address:
        address: 127.0.0.1
        port_value: 0
  listeners:
    name: listener_0
    address:
      socket_address:
        address: 127.0.0.1
        port_value: 0
)EOF";

const std::string ConfigHelper::TCP_PROXY_CONFIG = BASE_CONFIG + R"EOF(
    filter_chains:
      filters:
        name: envoy.tcp_proxy
        config:
          stat_prefix: tcp_stats
          cluster: cluster_0
)EOF";

const std::string ConfigHelper::HTTP_PROXY_CONFIG = BASE_CONFIG + R"EOF(
    filter_chains:
      filters:
        name: envoy.http_connection_manager
        config:
          stat_prefix: config_test
          http_filters:
            name: envoy.router
          codec_type: HTTP1
          route_config:
            virtual_hosts:
              name: integration
              routes:
                route:
                  cluster: cluster_0
                match:
                  prefix: "/"
              domains: "*"
            name: route_config_0
)EOF";

const std::string ConfigHelper::DEFAULT_BUFFER_FILTER =
    R"EOF(
name: envoy.buffer
config:
    max_request_bytes : 5242880
    max_request_time : 120s
)EOF";

const std::string ConfigHelper::DEFAULT_HEALTH_CHECK_FILTER =
    R"EOF(
name: envoy.health_check
config:
    pass_through_mode: false
    endpoint: /healthcheck
)EOF";

const std::string ConfigHelper::DEFAULT_SQUASH_FILTER =
    R"EOF(
name: envoy.squash
config:
  cluster: squash
  attachment_template:
    spec:
      attachment:
        env: "{{ SQUASH_ENV_TEST }}"
      match_request: true
  attachment_timeout:
    seconds: 1
    nanos: 0
  attachment_poll_period:
    seconds: 2
    nanos: 0
  request_timeout:
    seconds: 1
    nanos: 0
)EOF";

ConfigHelper::ConfigHelper(const Network::Address::IpVersion version, const std::string& config) {
  RELEASE_ASSERT(!finalized_);
  std::string filename = TestEnvironment::writeStringToFileForTest("basic_config.yaml", config);
  MessageUtil::loadFromFile(filename, bootstrap_);

  // Fix up all the socket addresses with the correct version.
  auto* admin = bootstrap_.mutable_admin();
  auto* admin_socket_addr = admin->mutable_address()->mutable_socket_address();
  admin_socket_addr->set_address(Network::Test::getLoopbackAddressString(version));

  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < static_resources->listeners_size(); ++i) {
    auto* listener = static_resources->mutable_listeners(i);
    auto* listener_socket_addr = listener->mutable_address()->mutable_socket_address();
    listener_socket_addr->set_address(Network::Test::getLoopbackAddressString(version));
  }

  for (int i = 0; i < static_resources->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    auto host_socket_addr = cluster->mutable_hosts(0)->mutable_socket_address();
    host_socket_addr->set_address(Network::Test::getLoopbackAddressString(version));
  }
}

void ConfigHelper::finalize(const std::vector<uint32_t>& ports) {
  RELEASE_ASSERT(!finalized_);
  for (auto config_modifier : config_modifiers_) {
    config_modifier(bootstrap_);
  }

  uint32_t port_idx = 0;
  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    for (int j = 0; j < cluster->hosts_size(); ++j) {
      if (cluster->mutable_hosts(j)->has_socket_address()) {
        auto* host_socket_addr = cluster->mutable_hosts(j)->mutable_socket_address();
        RELEASE_ASSERT(ports.size() >= port_idx);
        host_socket_addr->set_port_value(ports[port_idx++]);
      }
    }
  }
  ASSERT(port_idx == ports.size());

  if (!connect_timeout_set_) {
#ifdef __APPLE__
    // Set a high default connect timeout. Under heavy load (and in particular in CI), macOS
    // connections can take inordinately long to complete.
    setConnectTimeout(std::chrono::seconds(30));
#else
    // Set a default connect timeout.
    setConnectTimeout(std::chrono::seconds(5));
#endif
  }

  finalized_ = true;
}

void ConfigHelper::setSourceAddress(const std::string& address_string) {
  RELEASE_ASSERT(!finalized_);
  bootstrap_.mutable_cluster_manager()
      ->mutable_upstream_bind_config()
      ->mutable_source_address()
      ->set_address(address_string);
  // We don't have the ability to bind to specific ports yet.
  bootstrap_.mutable_cluster_manager()
      ->mutable_upstream_bind_config()
      ->mutable_source_address()
      ->set_port_value(0);
}

void ConfigHelper::setDefaultHostAndRoute(const std::string& domains, const std::string& prefix) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  loadHttpConnectionManager(hcm_config);

  auto* virtual_host = hcm_config.mutable_route_config()->mutable_virtual_hosts(0);
  virtual_host->set_domains(0, domains);
  virtual_host->mutable_routes(0)->mutable_match()->set_prefix(prefix);

  storeHttpConnectionManager(hcm_config);
}

void ConfigHelper::setBufferLimits(uint32_t upstream_buffer_limit,
                                   uint32_t downstream_buffer_limit) {
  RELEASE_ASSERT(!finalized_);
  RELEASE_ASSERT(bootstrap_.mutable_static_resources()->listeners_size() == 1);
  auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0);
  listener->mutable_per_connection_buffer_limit_bytes()->set_value(downstream_buffer_limit);

  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    cluster->mutable_per_connection_buffer_limit_bytes()->set_value(upstream_buffer_limit);
  }

  auto filter = getFilterFromListener();
  if (filter->name() == "envoy.http_connection_manager") {
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
    loadHttpConnectionManager(hcm_config);
    if (hcm_config.codec_type() ==
        envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager::HTTP2) {
      const uint32_t size =
          std::max(downstream_buffer_limit, Http::Http2Settings::MIN_INITIAL_STREAM_WINDOW_SIZE);
      auto* options = hcm_config.mutable_http2_protocol_options();
      options->mutable_initial_stream_window_size()->set_value(size);
      storeHttpConnectionManager(hcm_config);
    }
  }
}

void ConfigHelper::setConnectTimeout(std::chrono::milliseconds timeout) {
  RELEASE_ASSERT(!finalized_);

  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    auto* connect_timeout = cluster->mutable_connect_timeout();
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(timeout);
    connect_timeout->set_seconds(seconds.count());
    connect_timeout->set_nanos(
        std::chrono::duration_cast<std::chrono::nanoseconds>(timeout - seconds).count());
  }
  connect_timeout_set_ = true;
}

void ConfigHelper::addRoute(const std::string& domains, const std::string& prefix,
                            const std::string& cluster, bool validate_clusters,
                            envoy::api::v2::route::RouteAction::ClusterNotFoundResponseCode code,
                            envoy::api::v2::route::VirtualHost::TlsRequirementType type) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  loadHttpConnectionManager(hcm_config);

  auto* route_config = hcm_config.mutable_route_config();
  route_config->mutable_validate_clusters()->set_value(validate_clusters);
  auto* virtual_host = route_config->add_virtual_hosts();
  virtual_host->set_name(domains);
  virtual_host->add_domains(domains);
  virtual_host->add_routes()->mutable_match()->set_prefix(prefix);
  virtual_host->mutable_routes(0)->mutable_route()->set_cluster(cluster);
  virtual_host->mutable_routes(0)->mutable_route()->set_cluster_not_found_response_code(code);
  virtual_host->set_require_tls(type);

  storeHttpConnectionManager(hcm_config);
}

void ConfigHelper::addFilter(const std::string& config) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  loadHttpConnectionManager(hcm_config);

  auto* filter_list_back = hcm_config.add_http_filters();
  const std::string json = Json::Factory::loadFromYamlString(config)->asJsonString();
  MessageUtil::loadFromJson(json, *filter_list_back);

  // Now move it to the front.
  for (int i = hcm_config.http_filters_size() - 1; i > 0; --i) {
    hcm_config.mutable_http_filters()->SwapElements(i, i - 1);
  }
  storeHttpConnectionManager(hcm_config);
}

void ConfigHelper::setClientCodec(
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager::CodecType
        type) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  if (loadHttpConnectionManager(hcm_config)) {
    hcm_config.set_codec_type(type);
    storeHttpConnectionManager(hcm_config);
  }
}

void ConfigHelper::addSslConfig() {
  RELEASE_ASSERT(!finalized_);

  auto* filter_chain =
      bootstrap_.mutable_static_resources()->mutable_listeners(0)->mutable_filter_chains(0);

  auto* common_tls_context = filter_chain->mutable_tls_context()->mutable_common_tls_context();
  common_tls_context->add_alpn_protocols("h2");
  common_tls_context->add_alpn_protocols("http/1.1");
  common_tls_context->mutable_deprecated_v1()->set_alt_alpn_protocols("http/1.1");

  auto* validation_context = common_tls_context->mutable_validation_context();
  validation_context->mutable_trusted_ca()->set_filename(
      TestEnvironment::runfilesPath("test/config/integration/certs/cacert.pem"));
  validation_context->add_verify_certificate_hash("9E:D6:53:36:49:26:9C:69:4F:71:7E:87:29:A1:C8:B5:"
                                                  "50:06:FD:51:01:3C:0E:0D:42:94:91:6E:00:D7:EA:"
                                                  "04");

  auto* tls_certificate = common_tls_context->add_tls_certificates();
  tls_certificate->mutable_certificate_chain()->set_filename(
      TestEnvironment::runfilesPath("/test/config/integration/certs/servercert.pem"));
  tls_certificate->mutable_private_key()->set_filename(
      TestEnvironment::runfilesPath("/test/config/integration/certs/serverkey.pem"));
}

void ConfigHelper::renameListener(const std::string& name) {
  auto* static_resources = bootstrap_.mutable_static_resources();
  if (static_resources->listeners_size() > 0) {
    static_resources->mutable_listeners(0)->set_name(name);
  }
}

envoy::api::v2::listener::Filter* ConfigHelper::getFilterFromListener() {
  RELEASE_ASSERT(!finalized_);
  if (bootstrap_.mutable_static_resources()->listeners_size() == 0) {
    return nullptr;
  }
  auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0);
  if (listener->filter_chains_size() == 0) {
    return nullptr;
  }
  auto* filter_chain = listener->mutable_filter_chains(0);
  if (filter_chain->filters_size() == 0) {
    return nullptr;
  }
  return filter_chain->mutable_filters(0);
}

bool ConfigHelper::loadHttpConnectionManager(
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager& hcm) {
  RELEASE_ASSERT(!finalized_);
  auto* hcm_filter = getFilterFromListener();
  if (hcm_filter) {
    MessageUtil::jsonConvert(*hcm_filter->mutable_config(), hcm);
    return true;
  }
  return false;
}

void ConfigHelper::storeHttpConnectionManager(
    const envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager& hcm) {
  RELEASE_ASSERT(!finalized_);
  auto* hcm_config_struct = getFilterFromListener()->mutable_config();

  MessageUtil::jsonConvert(hcm, *hcm_config_struct);
}

void ConfigHelper::addConfigModifier(ConfigModifierFunction function) {
  RELEASE_ASSERT(!finalized_);
  config_modifiers_.push_back(std::move(function));
}

void ConfigHelper::addConfigModifier(HttpModifierFunction function) {
  addConfigModifier([function, this](envoy::config::bootstrap::v2::Bootstrap&) -> void {
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
    loadHttpConnectionManager(hcm_config);
    function(hcm_config);
    storeHttpConnectionManager(hcm_config);
  });
}

} // namespace Envoy
<commit_msg>test: Prevent access past the end of hosts array. (#2677)<commit_after>#include "test/config/utility.h"

#include "envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.pb.h"
#include "envoy/http/codec.h"

#include "common/common/assert.h"
#include "common/protobuf/utility.h"

#include "test/test_common/environment.h"
#include "test/test_common/network_utility.h"

namespace Envoy {

const std::string ConfigHelper::BASE_CONFIG = R"EOF(
admin:
  access_log_path: /dev/null
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 0
static_resources:
  clusters:
    name: cluster_0
    hosts:
      socket_address:
        address: 127.0.0.1
        port_value: 0
  listeners:
    name: listener_0
    address:
      socket_address:
        address: 127.0.0.1
        port_value: 0
)EOF";

const std::string ConfigHelper::TCP_PROXY_CONFIG = BASE_CONFIG + R"EOF(
    filter_chains:
      filters:
        name: envoy.tcp_proxy
        config:
          stat_prefix: tcp_stats
          cluster: cluster_0
)EOF";

const std::string ConfigHelper::HTTP_PROXY_CONFIG = BASE_CONFIG + R"EOF(
    filter_chains:
      filters:
        name: envoy.http_connection_manager
        config:
          stat_prefix: config_test
          http_filters:
            name: envoy.router
          codec_type: HTTP1
          route_config:
            virtual_hosts:
              name: integration
              routes:
                route:
                  cluster: cluster_0
                match:
                  prefix: "/"
              domains: "*"
            name: route_config_0
)EOF";

const std::string ConfigHelper::DEFAULT_BUFFER_FILTER =
    R"EOF(
name: envoy.buffer
config:
    max_request_bytes : 5242880
    max_request_time : 120s
)EOF";

const std::string ConfigHelper::DEFAULT_HEALTH_CHECK_FILTER =
    R"EOF(
name: envoy.health_check
config:
    pass_through_mode: false
    endpoint: /healthcheck
)EOF";

const std::string ConfigHelper::DEFAULT_SQUASH_FILTER =
    R"EOF(
name: envoy.squash
config:
  cluster: squash
  attachment_template:
    spec:
      attachment:
        env: "{{ SQUASH_ENV_TEST }}"
      match_request: true
  attachment_timeout:
    seconds: 1
    nanos: 0
  attachment_poll_period:
    seconds: 2
    nanos: 0
  request_timeout:
    seconds: 1
    nanos: 0
)EOF";

ConfigHelper::ConfigHelper(const Network::Address::IpVersion version, const std::string& config) {
  RELEASE_ASSERT(!finalized_);
  std::string filename = TestEnvironment::writeStringToFileForTest("basic_config.yaml", config);
  MessageUtil::loadFromFile(filename, bootstrap_);

  // Fix up all the socket addresses with the correct version.
  auto* admin = bootstrap_.mutable_admin();
  auto* admin_socket_addr = admin->mutable_address()->mutable_socket_address();
  admin_socket_addr->set_address(Network::Test::getLoopbackAddressString(version));

  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < static_resources->listeners_size(); ++i) {
    auto* listener = static_resources->mutable_listeners(i);
    auto* listener_socket_addr = listener->mutable_address()->mutable_socket_address();
    listener_socket_addr->set_address(Network::Test::getLoopbackAddressString(version));
  }

  for (int i = 0; i < static_resources->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    auto host_socket_addr = cluster->mutable_hosts(0)->mutable_socket_address();
    host_socket_addr->set_address(Network::Test::getLoopbackAddressString(version));
  }
}

void ConfigHelper::finalize(const std::vector<uint32_t>& ports) {
  RELEASE_ASSERT(!finalized_);
  for (auto config_modifier : config_modifiers_) {
    config_modifier(bootstrap_);
  }

  uint32_t port_idx = 0;
  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    for (int j = 0; j < cluster->hosts_size(); ++j) {
      if (cluster->mutable_hosts(j)->has_socket_address()) {
        auto* host_socket_addr = cluster->mutable_hosts(j)->mutable_socket_address();
        RELEASE_ASSERT(ports.size() > port_idx);
        host_socket_addr->set_port_value(ports[port_idx++]);
      }
    }
  }
  ASSERT(port_idx == ports.size());

  if (!connect_timeout_set_) {
#ifdef __APPLE__
    // Set a high default connect timeout. Under heavy load (and in particular in CI), macOS
    // connections can take inordinately long to complete.
    setConnectTimeout(std::chrono::seconds(30));
#else
    // Set a default connect timeout.
    setConnectTimeout(std::chrono::seconds(5));
#endif
  }

  finalized_ = true;
}

void ConfigHelper::setSourceAddress(const std::string& address_string) {
  RELEASE_ASSERT(!finalized_);
  bootstrap_.mutable_cluster_manager()
      ->mutable_upstream_bind_config()
      ->mutable_source_address()
      ->set_address(address_string);
  // We don't have the ability to bind to specific ports yet.
  bootstrap_.mutable_cluster_manager()
      ->mutable_upstream_bind_config()
      ->mutable_source_address()
      ->set_port_value(0);
}

void ConfigHelper::setDefaultHostAndRoute(const std::string& domains, const std::string& prefix) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  loadHttpConnectionManager(hcm_config);

  auto* virtual_host = hcm_config.mutable_route_config()->mutable_virtual_hosts(0);
  virtual_host->set_domains(0, domains);
  virtual_host->mutable_routes(0)->mutable_match()->set_prefix(prefix);

  storeHttpConnectionManager(hcm_config);
}

void ConfigHelper::setBufferLimits(uint32_t upstream_buffer_limit,
                                   uint32_t downstream_buffer_limit) {
  RELEASE_ASSERT(!finalized_);
  RELEASE_ASSERT(bootstrap_.mutable_static_resources()->listeners_size() == 1);
  auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0);
  listener->mutable_per_connection_buffer_limit_bytes()->set_value(downstream_buffer_limit);

  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    cluster->mutable_per_connection_buffer_limit_bytes()->set_value(upstream_buffer_limit);
  }

  auto filter = getFilterFromListener();
  if (filter->name() == "envoy.http_connection_manager") {
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
    loadHttpConnectionManager(hcm_config);
    if (hcm_config.codec_type() ==
        envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager::HTTP2) {
      const uint32_t size =
          std::max(downstream_buffer_limit, Http::Http2Settings::MIN_INITIAL_STREAM_WINDOW_SIZE);
      auto* options = hcm_config.mutable_http2_protocol_options();
      options->mutable_initial_stream_window_size()->set_value(size);
      storeHttpConnectionManager(hcm_config);
    }
  }
}

void ConfigHelper::setConnectTimeout(std::chrono::milliseconds timeout) {
  RELEASE_ASSERT(!finalized_);

  auto* static_resources = bootstrap_.mutable_static_resources();
  for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) {
    auto* cluster = static_resources->mutable_clusters(i);
    auto* connect_timeout = cluster->mutable_connect_timeout();
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(timeout);
    connect_timeout->set_seconds(seconds.count());
    connect_timeout->set_nanos(
        std::chrono::duration_cast<std::chrono::nanoseconds>(timeout - seconds).count());
  }
  connect_timeout_set_ = true;
}

void ConfigHelper::addRoute(const std::string& domains, const std::string& prefix,
                            const std::string& cluster, bool validate_clusters,
                            envoy::api::v2::route::RouteAction::ClusterNotFoundResponseCode code,
                            envoy::api::v2::route::VirtualHost::TlsRequirementType type) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  loadHttpConnectionManager(hcm_config);

  auto* route_config = hcm_config.mutable_route_config();
  route_config->mutable_validate_clusters()->set_value(validate_clusters);
  auto* virtual_host = route_config->add_virtual_hosts();
  virtual_host->set_name(domains);
  virtual_host->add_domains(domains);
  virtual_host->add_routes()->mutable_match()->set_prefix(prefix);
  virtual_host->mutable_routes(0)->mutable_route()->set_cluster(cluster);
  virtual_host->mutable_routes(0)->mutable_route()->set_cluster_not_found_response_code(code);
  virtual_host->set_require_tls(type);

  storeHttpConnectionManager(hcm_config);
}

void ConfigHelper::addFilter(const std::string& config) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  loadHttpConnectionManager(hcm_config);

  auto* filter_list_back = hcm_config.add_http_filters();
  const std::string json = Json::Factory::loadFromYamlString(config)->asJsonString();
  MessageUtil::loadFromJson(json, *filter_list_back);

  // Now move it to the front.
  for (int i = hcm_config.http_filters_size() - 1; i > 0; --i) {
    hcm_config.mutable_http_filters()->SwapElements(i, i - 1);
  }
  storeHttpConnectionManager(hcm_config);
}

void ConfigHelper::setClientCodec(
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager::CodecType
        type) {
  RELEASE_ASSERT(!finalized_);
  envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
  if (loadHttpConnectionManager(hcm_config)) {
    hcm_config.set_codec_type(type);
    storeHttpConnectionManager(hcm_config);
  }
}

void ConfigHelper::addSslConfig() {
  RELEASE_ASSERT(!finalized_);

  auto* filter_chain =
      bootstrap_.mutable_static_resources()->mutable_listeners(0)->mutable_filter_chains(0);

  auto* common_tls_context = filter_chain->mutable_tls_context()->mutable_common_tls_context();
  common_tls_context->add_alpn_protocols("h2");
  common_tls_context->add_alpn_protocols("http/1.1");
  common_tls_context->mutable_deprecated_v1()->set_alt_alpn_protocols("http/1.1");

  auto* validation_context = common_tls_context->mutable_validation_context();
  validation_context->mutable_trusted_ca()->set_filename(
      TestEnvironment::runfilesPath("test/config/integration/certs/cacert.pem"));
  validation_context->add_verify_certificate_hash("9E:D6:53:36:49:26:9C:69:4F:71:7E:87:29:A1:C8:B5:"
                                                  "50:06:FD:51:01:3C:0E:0D:42:94:91:6E:00:D7:EA:"
                                                  "04");

  auto* tls_certificate = common_tls_context->add_tls_certificates();
  tls_certificate->mutable_certificate_chain()->set_filename(
      TestEnvironment::runfilesPath("/test/config/integration/certs/servercert.pem"));
  tls_certificate->mutable_private_key()->set_filename(
      TestEnvironment::runfilesPath("/test/config/integration/certs/serverkey.pem"));
}

void ConfigHelper::renameListener(const std::string& name) {
  auto* static_resources = bootstrap_.mutable_static_resources();
  if (static_resources->listeners_size() > 0) {
    static_resources->mutable_listeners(0)->set_name(name);
  }
}

envoy::api::v2::listener::Filter* ConfigHelper::getFilterFromListener() {
  RELEASE_ASSERT(!finalized_);
  if (bootstrap_.mutable_static_resources()->listeners_size() == 0) {
    return nullptr;
  }
  auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0);
  if (listener->filter_chains_size() == 0) {
    return nullptr;
  }
  auto* filter_chain = listener->mutable_filter_chains(0);
  if (filter_chain->filters_size() == 0) {
    return nullptr;
  }
  return filter_chain->mutable_filters(0);
}

bool ConfigHelper::loadHttpConnectionManager(
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager& hcm) {
  RELEASE_ASSERT(!finalized_);
  auto* hcm_filter = getFilterFromListener();
  if (hcm_filter) {
    MessageUtil::jsonConvert(*hcm_filter->mutable_config(), hcm);
    return true;
  }
  return false;
}

void ConfigHelper::storeHttpConnectionManager(
    const envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager& hcm) {
  RELEASE_ASSERT(!finalized_);
  auto* hcm_config_struct = getFilterFromListener()->mutable_config();

  MessageUtil::jsonConvert(hcm, *hcm_config_struct);
}

void ConfigHelper::addConfigModifier(ConfigModifierFunction function) {
  RELEASE_ASSERT(!finalized_);
  config_modifiers_.push_back(std::move(function));
}

void ConfigHelper::addConfigModifier(HttpModifierFunction function) {
  addConfigModifier([function, this](envoy::config::bootstrap::v2::Bootstrap&) -> void {
    envoy::config::filter::network::http_connection_manager::v2::HttpConnectionManager hcm_config;
    loadHttpConnectionManager(hcm_config);
    function(hcm_config);
    storeHttpConnectionManager(hcm_config);
  });
}

} // namespace Envoy
<|endoftext|>


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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1581
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1582
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

#endif // VERSIONS_HPP_
<|endoftext|>


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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1910
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1911
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

#endif // VERSIONS_HPP_
<|endoftext|>


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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2191
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2192
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

#endif // VERSIONS_HPP_
<|endoftext|>


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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1744
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1745
#endif // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

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

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

#endif // VERSIONS_HPP_
<|endoftext|>


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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2619
#endif  // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

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

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2620
#endif  // AMD_PLATFORM_BUILD_NUMBER

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

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

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

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

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <errno.h>
#include <sys/time.h>

#include "vm/thread.h"

#include "vm/assert.h"

namespace dart {

#define VALIDATE_PTHREAD_RESULT(result) \
  if (result != 0) { \
    FATAL2("pthread error: %d (%s)", result, strerror(result)); \
  }

static void ComputeTimeSpec(struct timespec* ts, int64_t millis) {
  struct timeval time;
  struct timeval delta;
  // Convert the millis to a timeval delta.
  int64_t secs = millis / 1000;
  int64_t micros = (millis - (secs * 1000)) * 1000;
  delta.tv_sec = secs;
  delta.tv_usec = micros;
  // Get the current time and add the delta. Convert the result to a timespec.
  int result = gettimeofday(&time, NULL);
  ASSERT(result == 0);
  timeradd(&time, &delta, &time);
  TIMEVAL_TO_TIMESPEC(&time, ts);
}

class ThreadStartData {
 public:
  ThreadStartData(Thread::ThreadStartFunction function,
                  uword parameter,
                  Thread* thread)
      : function_(function), parameter_(parameter), thread_(thread) {}

  Thread::ThreadStartFunction function() const { return function_; }
  uword parameter() const { return parameter_; }
  Thread* thread() const { return thread_; }

 private:
  Thread::ThreadStartFunction function_;
  uword parameter_;
  Thread* thread_;

  DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
};

// Dispatch to the thread start function provided by the caller. This trampoline
// is used to ensure that the thread is properly destroyed if the thread just
// exits.
static void* ThreadStart(void* data_ptr) {
  ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);

  Thread::ThreadStartFunction function = data->function();
  uword parameter = data->parameter();
  Thread* thread = data->thread();
  delete data;

  // Call the supplied thread start function handing it its parameters.
  function(parameter);

  // When the function returns here, make sure that the thread is deleted.
  delete thread;

  return NULL;
}

Thread::Thread(ThreadStartFunction function, uword parameter) {
  pthread_attr_t attr;
  int result = pthread_attr_init(&attr);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_attr_setstacksize(&attr, 32 * KB);
  VALIDATE_PTHREAD_RESULT(result);

  ThreadStartData* data = new ThreadStartData(function, parameter, this);

  pthread_t tid;
  result = pthread_create(&tid,
                          &attr,
                          ThreadStart,
                          data);
  VALIDATE_PTHREAD_RESULT(result);

  data_.tid_ = tid;

  result = pthread_attr_destroy(&attr);
  VALIDATE_PTHREAD_RESULT(result);
}

Thread::~Thread() {
}

Mutex::Mutex() {
  pthread_mutexattr_t attr;
  int result = pthread_mutexattr_init(&attr);
  VALIDATE_PTHREAD_RESULT(result);

#if defined(DEBUG)
  result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
  VALIDATE_PTHREAD_RESULT(result);
#endif  // defined(DEBUG)

  result = pthread_mutex_init(data_.mutex(), &attr);
  // Verify that creating a pthread_mutex succeeded.
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_mutexattr_destroy(&attr);
  VALIDATE_PTHREAD_RESULT(result);
}

Mutex::~Mutex() {
  int result = pthread_mutex_destroy(data_.mutex());
  // Verify that the pthread_mutex was destroyed.
  VALIDATE_PTHREAD_RESULT(result);
}

void Mutex::Lock() {
  int result = pthread_mutex_lock(data_.mutex());
  // Specifically check for dead lock to help debugging.
  ASSERT(result != EDEADLK);
  ASSERT(result == 0);  // Verify no other errors.
  // TODO(iposva): Do we need to track lock owners?
}

bool Mutex::TryLock() {
  int result = pthread_mutex_trylock(data_.mutex());
  // Return false if the lock is busy and locking failed.
  if (result == EBUSY) {
    return false;
  }
  ASSERT(result == 0);  // Verify no other errors.
  // TODO(iposva): Do we need to track lock owners?
  return true;
}

void Mutex::Unlock() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_mutex_unlock(data_.mutex());
  // Specifically check for wrong thread unlocking to aid debugging.
  ASSERT(result != EPERM);
  ASSERT(result == 0);  // Verify no other errors.
}

Monitor::Monitor() {
  pthread_mutexattr_t attr;
  int result = pthread_mutexattr_init(&attr);
  VALIDATE_PTHREAD_RESULT(result);

#if defined(DEBUG)
  result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
  VALIDATE_PTHREAD_RESULT(result);
#endif  // defined(DEBUG)

  result = pthread_mutex_init(data_.mutex(), &attr);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_mutexattr_destroy(&attr);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_cond_init(data_.cond(), NULL);
  VALIDATE_PTHREAD_RESULT(result);
}

Monitor::~Monitor() {
  int result = pthread_mutex_destroy(data_.mutex());
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_cond_destroy(data_.cond());
  VALIDATE_PTHREAD_RESULT(result);
}

void Monitor::Enter() {
  int result = pthread_mutex_lock(data_.mutex());
  VALIDATE_PTHREAD_RESULT(result);
  // TODO(iposva): Do we need to track lock owners?
}

void Monitor::Exit() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_mutex_unlock(data_.mutex());
  VALIDATE_PTHREAD_RESULT(result);
}

Monitor::WaitResult Monitor::Wait(int64_t millis) {
  // TODO(iposva): Do we need to track lock owners?
  Monitor::WaitResult retval = kNotified;
  if (millis == 0) {
    // Wait forever.
    int result = pthread_cond_wait(data_.cond(), data_.mutex());
    VALIDATE_PTHREAD_RESULT(result);
  } else {
    struct timespec ts;
    ComputeTimeSpec(&ts, millis);
    int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts);
    ASSERT((result == 0) || (result == ETIMEDOUT));
    if (result == ETIMEDOUT) {
      retval = kTimedOut;
    }
  }
  return retval;
}

void Monitor::Notify() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_cond_signal(data_.cond());
  VALIDATE_PTHREAD_RESULT(result);
}

void Monitor::NotifyAll() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_cond_broadcast(data_.cond());
  VALIDATE_PTHREAD_RESULT(result);
}

}  // namespace dart
<commit_msg>Bump stack size for pure Dart isolates. Review URL: http://codereview.chromium.org//8495007<commit_after>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <errno.h>
#include <sys/time.h>

#include "vm/thread.h"

#include "vm/assert.h"

namespace dart {

#define VALIDATE_PTHREAD_RESULT(result) \
  if (result != 0) { \
    FATAL2("pthread error: %d (%s)", result, strerror(result)); \
  }

static void ComputeTimeSpec(struct timespec* ts, int64_t millis) {
  struct timeval time;
  struct timeval delta;
  // Convert the millis to a timeval delta.
  int64_t secs = millis / 1000;
  int64_t micros = (millis - (secs * 1000)) * 1000;
  delta.tv_sec = secs;
  delta.tv_usec = micros;
  // Get the current time and add the delta. Convert the result to a timespec.
  int result = gettimeofday(&time, NULL);
  ASSERT(result == 0);
  timeradd(&time, &delta, &time);
  TIMEVAL_TO_TIMESPEC(&time, ts);
}

class ThreadStartData {
 public:
  ThreadStartData(Thread::ThreadStartFunction function,
                  uword parameter,
                  Thread* thread)
      : function_(function), parameter_(parameter), thread_(thread) {}

  Thread::ThreadStartFunction function() const { return function_; }
  uword parameter() const { return parameter_; }
  Thread* thread() const { return thread_; }

 private:
  Thread::ThreadStartFunction function_;
  uword parameter_;
  Thread* thread_;

  DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
};

// Dispatch to the thread start function provided by the caller. This trampoline
// is used to ensure that the thread is properly destroyed if the thread just
// exits.
static void* ThreadStart(void* data_ptr) {
  ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);

  Thread::ThreadStartFunction function = data->function();
  uword parameter = data->parameter();
  Thread* thread = data->thread();
  delete data;

  // Call the supplied thread start function handing it its parameters.
  function(parameter);

  // When the function returns here, make sure that the thread is deleted.
  delete thread;

  return NULL;
}

Thread::Thread(ThreadStartFunction function, uword parameter) {
  pthread_attr_t attr;
  int result = pthread_attr_init(&attr);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_attr_setstacksize(&attr, 1024 * KB);
  VALIDATE_PTHREAD_RESULT(result);

  ThreadStartData* data = new ThreadStartData(function, parameter, this);

  pthread_t tid;
  result = pthread_create(&tid,
                          &attr,
                          ThreadStart,
                          data);
  VALIDATE_PTHREAD_RESULT(result);

  data_.tid_ = tid;

  result = pthread_attr_destroy(&attr);
  VALIDATE_PTHREAD_RESULT(result);
}

Thread::~Thread() {
}

Mutex::Mutex() {
  pthread_mutexattr_t attr;
  int result = pthread_mutexattr_init(&attr);
  VALIDATE_PTHREAD_RESULT(result);

#if defined(DEBUG)
  result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
  VALIDATE_PTHREAD_RESULT(result);
#endif  // defined(DEBUG)

  result = pthread_mutex_init(data_.mutex(), &attr);
  // Verify that creating a pthread_mutex succeeded.
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_mutexattr_destroy(&attr);
  VALIDATE_PTHREAD_RESULT(result);
}

Mutex::~Mutex() {
  int result = pthread_mutex_destroy(data_.mutex());
  // Verify that the pthread_mutex was destroyed.
  VALIDATE_PTHREAD_RESULT(result);
}

void Mutex::Lock() {
  int result = pthread_mutex_lock(data_.mutex());
  // Specifically check for dead lock to help debugging.
  ASSERT(result != EDEADLK);
  ASSERT(result == 0);  // Verify no other errors.
  // TODO(iposva): Do we need to track lock owners?
}

bool Mutex::TryLock() {
  int result = pthread_mutex_trylock(data_.mutex());
  // Return false if the lock is busy and locking failed.
  if (result == EBUSY) {
    return false;
  }
  ASSERT(result == 0);  // Verify no other errors.
  // TODO(iposva): Do we need to track lock owners?
  return true;
}

void Mutex::Unlock() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_mutex_unlock(data_.mutex());
  // Specifically check for wrong thread unlocking to aid debugging.
  ASSERT(result != EPERM);
  ASSERT(result == 0);  // Verify no other errors.
}

Monitor::Monitor() {
  pthread_mutexattr_t attr;
  int result = pthread_mutexattr_init(&attr);
  VALIDATE_PTHREAD_RESULT(result);

#if defined(DEBUG)
  result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
  VALIDATE_PTHREAD_RESULT(result);
#endif  // defined(DEBUG)

  result = pthread_mutex_init(data_.mutex(), &attr);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_mutexattr_destroy(&attr);
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_cond_init(data_.cond(), NULL);
  VALIDATE_PTHREAD_RESULT(result);
}

Monitor::~Monitor() {
  int result = pthread_mutex_destroy(data_.mutex());
  VALIDATE_PTHREAD_RESULT(result);

  result = pthread_cond_destroy(data_.cond());
  VALIDATE_PTHREAD_RESULT(result);
}

void Monitor::Enter() {
  int result = pthread_mutex_lock(data_.mutex());
  VALIDATE_PTHREAD_RESULT(result);
  // TODO(iposva): Do we need to track lock owners?
}

void Monitor::Exit() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_mutex_unlock(data_.mutex());
  VALIDATE_PTHREAD_RESULT(result);
}

Monitor::WaitResult Monitor::Wait(int64_t millis) {
  // TODO(iposva): Do we need to track lock owners?
  Monitor::WaitResult retval = kNotified;
  if (millis == 0) {
    // Wait forever.
    int result = pthread_cond_wait(data_.cond(), data_.mutex());
    VALIDATE_PTHREAD_RESULT(result);
  } else {
    struct timespec ts;
    ComputeTimeSpec(&ts, millis);
    int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts);
    ASSERT((result == 0) || (result == ETIMEDOUT));
    if (result == ETIMEDOUT) {
      retval = kTimedOut;
    }
  }
  return retval;
}

void Monitor::Notify() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_cond_signal(data_.cond());
  VALIDATE_PTHREAD_RESULT(result);
}

void Monitor::NotifyAll() {
  // TODO(iposva): Do we need to track lock owners?
  int result = pthread_cond_broadcast(data_.cond());
  VALIDATE_PTHREAD_RESULT(result);
}

}  // namespace dart
<|endoftext|>