<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
  * @file
  **/

#include "modules/planning/common/speed/st_boundary.h"

#include <algorithm>

#include "modules/common/log.h"

namespace apollo {
namespace planning {

using Vec2d = common::math::Vec2d;

StBoundary::StBoundary(
    const std::vector<std::pair<STPoint, STPoint>>& point_pairs) {
  CHECK(IsValid(point_pairs));

  for (size_t i = 0; i < point_pairs.size(); ++i) {
    upper_points_.emplace_back(point_pairs[i].first.t(),
                               point_pairs[i].first.s());
    lower_points_.emplace_back(point_pairs[i].second.t(),
                               point_pairs[i].second.s());
  }
  points_.reserve(upper_points_.size() + lower_points_.size());
  points_.insert(points_.end(), lower_points_.begin(), lower_points_.end());
  points_.insert(points_.end(), upper_points_.rbegin(), upper_points_.rend());

  BuildFromPoints();

  for (const auto& point : points_) {
    min_s_ = std::fmin(min_s_, point.y());
    min_t_ = std::fmin(min_t_, point.x());
    max_s_ = std::fmax(max_s_, point.y());
    max_t_ = std::fmax(max_t_, point.x());
  }
}

bool StBoundary::IsValid(
    const std::vector<std::pair<STPoint, STPoint>>& point_pairs) {
  // TODO(Liangliang): implement this function.
  return true;
}

bool StBoundary::IsPointInBoundary(const STPoint& st_point) const {
  return IsPointIn(st_point);
}

STPoint StBoundary::BottomLeftPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(lower_points_.front());
}

STPoint StBoundary::BottomRightPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(lower_points_.back());
}

STPoint StBoundary::TopRightPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(upper_points_.back());
}

STPoint StBoundary::TopLeftPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(upper_points_.front());
}

StBoundary::BoundaryType StBoundary::boundary_type() const {
  return boundary_type_;
}
void StBoundary::SetBoundaryType(const BoundaryType& boundary_type) {
  boundary_type_ = boundary_type;
}

const std::string& StBoundary::id() const { return id_; }

void StBoundary::SetId(const std::string& id) { id_ = id; }

double StBoundary::characteristic_length() const {
  return characteristic_length_;
}

void StBoundary::SetCharacteristicLength(const double characteristic_length) {
  characteristic_length_ = characteristic_length;
}

bool StBoundary::GetUnblockSRange(const double curr_time, double* s_upper,
                                  double* s_lower) const {
  const common::math::LineSegment2d segment = {Vec2d(curr_time, 0.0),
                                               Vec2d(curr_time, s_high_limit_)};
  *s_upper = s_high_limit_;
  *s_lower = 0.0;

  Vec2d p_s_first;
  Vec2d p_s_second;

  if (!GetOverlap(segment, &p_s_first, &p_s_second)) {
    ADEBUG << "curr_time[" << curr_time
           << "] is out of the coverage scope of the boundary.";
    return false;
  }
  if (boundary_type_ == BoundaryType::STOP ||
      boundary_type_ == BoundaryType::YIELD ||
      boundary_type_ == BoundaryType::FOLLOW) {
    *s_upper = std::fmin(*s_upper, std::fmin(p_s_first.y(), p_s_second.y()));
  } else if (boundary_type_ == BoundaryType::OVERTAKE) {
    // overtake
    *s_lower = std::fmax(*s_lower, std::fmax(p_s_first.y(), p_s_second.y()));
  } else {
    AERROR << "boundary_type is not supported. boundary_type: "
           << static_cast<int>(boundary_type_);
    return false;
  }
  return true;
}

bool StBoundary::GetBoundarySRange(const double curr_time, double* s_upper,
                                   double* s_lower) const {
  const common::math::LineSegment2d segment = {Vec2d(curr_time, 0.0),
                                               Vec2d(curr_time, s_high_limit_)};
  *s_upper = s_high_limit_;
  *s_lower = 0.0;

  Vec2d p_s_first;
  Vec2d p_s_second;
  if (!GetOverlap(segment, &p_s_first, &p_s_second)) {
    ADEBUG << "curr_time[" << curr_time
           << "] is out of the coverage scope of the boundary.";
    return false;
  }
  *s_upper = std::fmin(*s_upper, std::fmax(p_s_first.y(), p_s_second.y()));
  *s_lower = std::fmax(*s_lower, std::fmin(p_s_first.y(), p_s_second.y()));
  return true;
}

double StBoundary::min_s() const { return min_s_; }
double StBoundary::min_t() const { return min_t_; }
double StBoundary::max_s() const { return max_s_; }
double StBoundary::max_t() const { return max_t_; }

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: implemented IsValid function in st_boundary.cc<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
  * @file
  **/

#include "modules/planning/common/speed/st_boundary.h"

#include <algorithm>

#include "modules/common/log.h"

namespace apollo {
namespace planning {

using Vec2d = common::math::Vec2d;

StBoundary::StBoundary(
    const std::vector<std::pair<STPoint, STPoint>>& point_pairs) {
  CHECK(IsValid(point_pairs));

  for (size_t i = 0; i < point_pairs.size(); ++i) {
    lower_points_.emplace_back(point_pairs[i].first.t(),
                               point_pairs[i].first.s());
    upper_points_.emplace_back(point_pairs[i].second.t(),
                               point_pairs[i].second.s());
  }
  points_.reserve(upper_points_.size() + lower_points_.size());
  points_.insert(points_.end(), lower_points_.begin(), lower_points_.end());
  points_.insert(points_.end(), upper_points_.rbegin(), upper_points_.rend());

  BuildFromPoints();

  for (const auto& point : points_) {
    min_s_ = std::fmin(min_s_, point.y());
    min_t_ = std::fmin(min_t_, point.x());
    max_s_ = std::fmax(max_s_, point.y());
    max_t_ = std::fmax(max_t_, point.x());
  }
}

bool StBoundary::IsValid(
    const std::vector<std::pair<STPoint, STPoint>>& point_pairs) {
  if (point_pairs.size() < 2) {
    AERROR << "point_pairs.size() must > 2. current point_pairs.size() = "
           << point_pairs.size();
    return false;
  }

  constexpr double kStBoundaryEpsilon = 1e-9;
  constexpr double kMinDeltaT = 1e-6;
  for (size_t i = 0; i < point_pairs.size(); ++i) {
    const auto& curr_lower = point_pairs[i].first;
    const auto& curr_upper = point_pairs[i].second;
    if (curr_upper.s() < curr_lower.s()) {
      return false;
    }

    if (std::fabs(curr_lower.t() - curr_upper.t()) > kStBoundaryEpsilon) {
      return false;
    }

    if (i + 1 != point_pairs.size()) {
      const auto& next_lower = point_pairs[i + 1].first;
      const auto& next_upper = point_pairs[i + 1].second;
      if (std::fmax(curr_lower.t(), curr_upper.t()) + kMinDeltaT >=
          std::fmin(next_lower.t(), next_upper.t())) {
        return false;
      }
    }
  }

  return true;
}

bool StBoundary::IsPointInBoundary(const STPoint& st_point) const {
  return IsPointIn(st_point);
}

STPoint StBoundary::BottomLeftPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(lower_points_.front());
}

STPoint StBoundary::BottomRightPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(lower_points_.back());
}

STPoint StBoundary::TopRightPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(upper_points_.back());
}

STPoint StBoundary::TopLeftPoint() const {
  DCHECK(!points_.empty()) << "StBoundary has zero points.";
  return STPoint(upper_points_.front());
}

StBoundary::BoundaryType StBoundary::boundary_type() const {
  return boundary_type_;
}
void StBoundary::SetBoundaryType(const BoundaryType& boundary_type) {
  boundary_type_ = boundary_type;
}

const std::string& StBoundary::id() const { return id_; }

void StBoundary::SetId(const std::string& id) { id_ = id; }

double StBoundary::characteristic_length() const {
  return characteristic_length_;
}

void StBoundary::SetCharacteristicLength(const double characteristic_length) {
  characteristic_length_ = characteristic_length;
}

bool StBoundary::GetUnblockSRange(const double curr_time, double* s_upper,
                                  double* s_lower) const {
  const common::math::LineSegment2d segment = {Vec2d(curr_time, 0.0),
                                               Vec2d(curr_time, s_high_limit_)};
  *s_upper = s_high_limit_;
  *s_lower = 0.0;

  Vec2d p_s_first;
  Vec2d p_s_second;

  if (!GetOverlap(segment, &p_s_first, &p_s_second)) {
    ADEBUG << "curr_time[" << curr_time
           << "] is out of the coverage scope of the boundary.";
    return false;
  }
  if (boundary_type_ == BoundaryType::STOP ||
      boundary_type_ == BoundaryType::YIELD ||
      boundary_type_ == BoundaryType::FOLLOW) {
    *s_upper = std::fmin(*s_upper, std::fmin(p_s_first.y(), p_s_second.y()));
  } else if (boundary_type_ == BoundaryType::OVERTAKE) {
    // overtake
    *s_lower = std::fmax(*s_lower, std::fmax(p_s_first.y(), p_s_second.y()));
  } else {
    AERROR << "boundary_type is not supported. boundary_type: "
           << static_cast<int>(boundary_type_);
    return false;
  }
  return true;
}

bool StBoundary::GetBoundarySRange(const double curr_time, double* s_upper,
                                   double* s_lower) const {
  const common::math::LineSegment2d segment = {Vec2d(curr_time, 0.0),
                                               Vec2d(curr_time, s_high_limit_)};
  *s_upper = s_high_limit_;
  *s_lower = 0.0;

  Vec2d p_s_first;
  Vec2d p_s_second;
  if (!GetOverlap(segment, &p_s_first, &p_s_second)) {
    ADEBUG << "curr_time[" << curr_time
           << "] is out of the coverage scope of the boundary.";
    return false;
  }
  *s_upper = std::fmin(*s_upper, std::fmax(p_s_first.y(), p_s_second.y()));
  *s_lower = std::fmax(*s_lower, std::fmin(p_s_first.y(), p_s_second.y()));
  return true;
}

double StBoundary::min_s() const { return min_s_; }
double StBoundary::min_t() const { return min_t_; }
double StBoundary::max_s() const { return max_s_; }
double StBoundary::max_t() const { return max_t_; }

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before><commit_msg>change order of var in PDFExtOutDevData to suppress waring<commit_after><|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/video_coding/main/source/receiver.h"

#include <assert.h>

#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/source/media_opt_util.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/system_wrappers/interface/trace_event.h"

namespace webrtc {

enum { kMaxReceiverDelayMs = 10000 };

VCMReceiver::VCMReceiver(VCMTiming* timing,
                         Clock* clock,
                         EventFactory* event_factory,
                         int32_t vcm_id,
                         int32_t receiver_id,
                         bool master)
    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
      vcm_id_(vcm_id),
      clock_(clock),
      receiver_id_(receiver_id),
      master_(master),
      jitter_buffer_(clock_, event_factory, vcm_id, receiver_id, master),
      timing_(timing),
      render_wait_event_(event_factory->CreateEvent()),
      state_(kPassive),
      max_video_delay_ms_(kMaxVideoDelayMs) {}

VCMReceiver::~VCMReceiver() {
  render_wait_event_->Set();
  delete crit_sect_;
}

void VCMReceiver::Reset() {
  CriticalSectionScoped cs(crit_sect_);
  if (!jitter_buffer_.Running()) {
    jitter_buffer_.Start();
  } else {
    jitter_buffer_.Flush();
  }
  render_wait_event_->Reset();
  if (master_) {
    state_ = kReceiving;
  } else {
    state_ = kPassive;
  }
}

int32_t VCMReceiver::Initialize() {
  CriticalSectionScoped cs(crit_sect_);
  Reset();
  if (!master_) {
    SetNackMode(kNoNack, -1, -1);
  }
  return VCM_OK;
}

void VCMReceiver::UpdateRtt(uint32_t rtt) {
  jitter_buffer_.UpdateRtt(rtt);
}

int32_t VCMReceiver::InsertPacket(const VCMPacket& packet,
                                  uint16_t frame_width,
                                  uint16_t frame_height) {
  if (packet.frameType == kVideoFrameKey) {
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Inserting key frame packet seqnum=%u, timestamp=%u",
                 packet.seqNum, packet.timestamp);
  }

  // Insert the packet into the jitter buffer. The packet can either be empty or
  // contain media at this point.
  bool retransmitted = false;
  const VCMFrameBufferEnum ret = jitter_buffer_.InsertPacket(packet,
                                                             &retransmitted);
  if (ret == kOldPacket) {
    return VCM_OK;
  } else if (ret == kFlushIndicator) {
    return VCM_FLUSH_INDICATOR;
  } else if (ret < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Error inserting packet seqnum=%u, timestamp=%u",
                 packet.seqNum, packet.timestamp);
    return VCM_JITTER_BUFFER_ERROR;
  }
  if (ret == kCompleteSession && !retransmitted) {
    // We don't want to include timestamps which have suffered from
    // retransmission here, since we compensate with extra retransmission
    // delay within the jitter estimate.
    timing_->IncomingTimestamp(packet.timestamp, clock_->TimeInMilliseconds());
  }
  if (master_) {
    // Only trace the primary receiver to make it possible to parse and plot
    // the trace file.
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Packet seqnum=%u timestamp=%u inserted at %u",
                 packet.seqNum, packet.timestamp,
                 MaskWord64ToUWord32(clock_->TimeInMilliseconds()));
  }
  return VCM_OK;
}

VCMEncodedFrame* VCMReceiver::FrameForDecoding(
    uint16_t max_wait_time_ms,
    int64_t& next_render_time_ms,
    bool render_timing,
    VCMReceiver* dual_receiver) {
  const int64_t start_time_ms = clock_->TimeInMilliseconds();
  uint32_t frame_timestamp = 0;
  // Exhaust wait time to get a complete frame for decoding.
  bool found_frame = jitter_buffer_.NextCompleteTimestamp(
      max_wait_time_ms, &frame_timestamp);

  if (!found_frame) {
    // Get an incomplete frame when enabled.
    const bool dual_receiver_enabled_and_passive = (dual_receiver != NULL &&
        dual_receiver->State() == kPassive &&
        dual_receiver->NackMode() == kNack);
    if (dual_receiver_enabled_and_passive &&
        !jitter_buffer_.CompleteSequenceWithNextFrame()) {
      // Jitter buffer state might get corrupt with this frame.
      dual_receiver->CopyJitterBufferStateFromReceiver(*this);
    }
    found_frame = jitter_buffer_.NextMaybeIncompleteTimestamp(
        &frame_timestamp);
  }

  if (!found_frame) {
    return NULL;
  }

  // We have a frame - Set timing and render timestamp.
  timing_->SetJitterDelay(jitter_buffer_.EstimatedJitterMs());
  const int64_t now_ms = clock_->TimeInMilliseconds();
  timing_->UpdateCurrentDelay(frame_timestamp);
  next_render_time_ms = timing_->RenderTimeMs(frame_timestamp, now_ms);
  // Check render timing.
  bool timing_error = false;
  // Assume that render timing errors are due to changes in the video stream.
  if (next_render_time_ms < 0) {
    timing_error = true;
  } else if (abs(next_render_time_ms - now_ms) > max_video_delay_ms_) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "This frame is out of our delay bounds, resetting jitter "
                 "buffer: %d > %d",
                 static_cast<int>(abs(next_render_time_ms - now_ms)),
                 max_video_delay_ms_);
    timing_error = true;
  } else if (static_cast<int>(timing_->TargetVideoDelay()) >
             max_video_delay_ms_) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "More than %u ms target delay. Flushing jitter buffer and"
                 "resetting timing.", max_video_delay_ms_);
    timing_error = true;
  }

  if (timing_error) {
    // Timing error => reset timing and flush the jitter buffer.
    jitter_buffer_.Flush();
    timing_->Reset();
    return NULL;
  }

  if (!render_timing) {
    // Decode frame as close as possible to the render timestamp.
    const int32_t available_wait_time = max_wait_time_ms -
        static_cast<int32_t>(clock_->TimeInMilliseconds() - start_time_ms);
    uint16_t new_max_wait_time = static_cast<uint16_t>(
        VCM_MAX(available_wait_time, 0));
    uint32_t wait_time_ms = timing_->MaxWaitingTime(
        next_render_time_ms, clock_->TimeInMilliseconds());
    if (new_max_wait_time < wait_time_ms) {
      // We're not allowed to wait until the frame is supposed to be rendered,
      // waiting as long as we're allowed to avoid busy looping, and then return
      // NULL. Next call to this function might return the frame.
      render_wait_event_->Wait(max_wait_time_ms);
      return NULL;
    }
    // Wait until it's time to render.
    render_wait_event_->Wait(wait_time_ms);
  }

  // Extract the frame from the jitter buffer and set the render time.
  VCMEncodedFrame* frame = jitter_buffer_.ExtractAndSetDecode(frame_timestamp);
  if (frame == NULL) {
    return NULL;
  }
  frame->SetRenderTime(next_render_time_ms);
  TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame->TimeStamp(),
                          "SetRenderTS", "render_time", next_render_time_ms);
  if (dual_receiver != NULL) {
    dual_receiver->UpdateState(*frame);
  }
  if (!frame->Complete()) {
    // Update stats for incomplete frames.
    bool retransmitted = false;
    const int64_t last_packet_time_ms =
        jitter_buffer_.LastPacketTime(frame, &retransmitted);
    if (last_packet_time_ms >= 0 && !retransmitted) {
      // We don't want to include timestamps which have suffered from
      // retransmission here, since we compensate with extra retransmission
      // delay within the jitter estimate.
      timing_->IncomingTimestamp(frame_timestamp, last_packet_time_ms);
    }
  }
  return frame;
}

void VCMReceiver::ReleaseFrame(VCMEncodedFrame* frame) {
  jitter_buffer_.ReleaseFrame(frame);
}

void VCMReceiver::ReceiveStatistics(uint32_t* bitrate,
                                    uint32_t* framerate) {
  assert(bitrate);
  assert(framerate);
  jitter_buffer_.IncomingRateStatistics(framerate, bitrate);
}

void VCMReceiver::ReceivedFrameCount(VCMFrameCount* frame_count) const {
  assert(frame_count);
  jitter_buffer_.FrameStatistics(&frame_count->numDeltaFrames,
                                 &frame_count->numKeyFrames);
}

uint32_t VCMReceiver::DiscardedPackets() const {
  return jitter_buffer_.num_discarded_packets();
}

void VCMReceiver::SetNackMode(VCMNackMode nackMode,
                              int low_rtt_nack_threshold_ms,
                              int high_rtt_nack_threshold_ms) {
  CriticalSectionScoped cs(crit_sect_);
  // Default to always having NACK enabled in hybrid mode.
  jitter_buffer_.SetNackMode(nackMode, low_rtt_nack_threshold_ms,
                             high_rtt_nack_threshold_ms);
  if (!master_) {
    state_ = kPassive;  // The dual decoder defaults to passive.
  }
}

void VCMReceiver::SetNackSettings(size_t max_nack_list_size,
                                  int max_packet_age_to_nack,
                                  int max_incomplete_time_ms) {
  jitter_buffer_.SetNackSettings(max_nack_list_size,
                                 max_packet_age_to_nack,
                                 max_incomplete_time_ms);
}

VCMNackMode VCMReceiver::NackMode() const {
  CriticalSectionScoped cs(crit_sect_);
  return jitter_buffer_.nack_mode();
}

VCMNackStatus VCMReceiver::NackList(uint16_t* nack_list,
                                    uint16_t size,
                                    uint16_t* nack_list_length) {
  bool request_key_frame = false;
  uint16_t* internal_nack_list = jitter_buffer_.GetNackList(
      nack_list_length, &request_key_frame);
  if (*nack_list_length > size) {
    *nack_list_length = 0;
    return kNackNeedMoreMemory;
  }
  if (internal_nack_list != NULL && *nack_list_length > 0) {
    memcpy(nack_list, internal_nack_list, *nack_list_length * sizeof(uint16_t));
  }
  if (request_key_frame) {
    return kNackKeyFrameRequest;
  }
  return kNackOk;
}

// Decide whether we should change decoder state. This should be done if the
// dual decoder has caught up with the decoder decoding with packet losses.
bool VCMReceiver::DualDecoderCaughtUp(VCMEncodedFrame* dual_frame,
                                      VCMReceiver& dual_receiver) const {
  if (dual_frame == NULL) {
    return false;
  }
  if (jitter_buffer_.LastDecodedTimestamp() == dual_frame->TimeStamp()) {
    dual_receiver.UpdateState(kWaitForPrimaryDecode);
    return true;
  }
  return false;
}

void VCMReceiver::CopyJitterBufferStateFromReceiver(
    const VCMReceiver& receiver) {
  jitter_buffer_.CopyFrom(receiver.jitter_buffer_);
}

VCMReceiverState VCMReceiver::State() const {
  CriticalSectionScoped cs(crit_sect_);
  return state_;
}

void VCMReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
  jitter_buffer_.SetDecodeErrorMode(decode_error_mode);
}

VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
  return jitter_buffer_.decode_error_mode();
}

int VCMReceiver::SetMinReceiverDelay(int desired_delay_ms) {
  CriticalSectionScoped cs(crit_sect_);
  if (desired_delay_ms < 0 || desired_delay_ms > kMaxReceiverDelayMs) {
    return -1;
  }
  max_video_delay_ms_ = desired_delay_ms + kMaxVideoDelayMs;
  // Initializing timing to the desired delay.
  timing_->set_min_playout_delay(desired_delay_ms);
  return 0;
}

int VCMReceiver::RenderBufferSizeMs() {
  uint32_t timestamp_start = 0u;
  uint32_t timestamp_end = 0u;
  // Render timestamps are computed just prior to decoding. Therefore this is
  // only an estimate based on frames' timestamps and current timing state.
  jitter_buffer_.RenderBufferSize(&timestamp_start, &timestamp_end);
  if (timestamp_start == timestamp_end) {
    return 0;
  }
  // Update timing.
  const int64_t now_ms = clock_->TimeInMilliseconds();
  timing_->SetJitterDelay(jitter_buffer_.EstimatedJitterMs());
  // Get render timestamps.
  uint32_t render_start = timing_->RenderTimeMs(timestamp_start, now_ms);
  uint32_t render_end = timing_->RenderTimeMs(timestamp_end, now_ms);
  return render_end - render_start;
}

void VCMReceiver::UpdateState(VCMReceiverState new_state) {
  CriticalSectionScoped cs(crit_sect_);
  assert(!(state_ == kPassive && new_state == kWaitForPrimaryDecode));
  state_ = new_state;
}

void VCMReceiver::UpdateState(const VCMEncodedFrame& frame) {
  if (jitter_buffer_.nack_mode() == kNoNack) {
    // Dual decoder mode has not been enabled.
    return;
  }
  // Update the dual receiver state.
  if (frame.Complete() && frame.FrameType() == kVideoFrameKey) {
    UpdateState(kPassive);
  }
  if (State() == kWaitForPrimaryDecode &&
      frame.Complete() && !frame.MissingFrame()) {
    UpdateState(kPassive);
  }
  if (frame.MissingFrame() || !frame.Complete()) {
    // State was corrupted, enable dual receiver.
    UpdateState(kReceiving);
  }
}
}  // namespace webrtc
<commit_msg>Avoid recursively taking critical section.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/video_coding/main/source/receiver.h"

#include <assert.h>

#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/source/media_opt_util.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/system_wrappers/interface/trace_event.h"

namespace webrtc {

enum { kMaxReceiverDelayMs = 10000 };

VCMReceiver::VCMReceiver(VCMTiming* timing,
                         Clock* clock,
                         EventFactory* event_factory,
                         int32_t vcm_id,
                         int32_t receiver_id,
                         bool master)
    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
      vcm_id_(vcm_id),
      clock_(clock),
      receiver_id_(receiver_id),
      master_(master),
      jitter_buffer_(clock_, event_factory, vcm_id, receiver_id, master),
      timing_(timing),
      render_wait_event_(event_factory->CreateEvent()),
      state_(kPassive),
      max_video_delay_ms_(kMaxVideoDelayMs) {}

VCMReceiver::~VCMReceiver() {
  render_wait_event_->Set();
  delete crit_sect_;
}

void VCMReceiver::Reset() {
  CriticalSectionScoped cs(crit_sect_);
  if (!jitter_buffer_.Running()) {
    jitter_buffer_.Start();
  } else {
    jitter_buffer_.Flush();
  }
  render_wait_event_->Reset();
  if (master_) {
    state_ = kReceiving;
  } else {
    state_ = kPassive;
  }
}

int32_t VCMReceiver::Initialize() {
  Reset();
  CriticalSectionScoped cs(crit_sect_);
  if (!master_) {
    SetNackMode(kNoNack, -1, -1);
  }
  return VCM_OK;
}

void VCMReceiver::UpdateRtt(uint32_t rtt) {
  jitter_buffer_.UpdateRtt(rtt);
}

int32_t VCMReceiver::InsertPacket(const VCMPacket& packet,
                                  uint16_t frame_width,
                                  uint16_t frame_height) {
  if (packet.frameType == kVideoFrameKey) {
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Inserting key frame packet seqnum=%u, timestamp=%u",
                 packet.seqNum, packet.timestamp);
  }

  // Insert the packet into the jitter buffer. The packet can either be empty or
  // contain media at this point.
  bool retransmitted = false;
  const VCMFrameBufferEnum ret = jitter_buffer_.InsertPacket(packet,
                                                             &retransmitted);
  if (ret == kOldPacket) {
    return VCM_OK;
  } else if (ret == kFlushIndicator) {
    return VCM_FLUSH_INDICATOR;
  } else if (ret < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Error inserting packet seqnum=%u, timestamp=%u",
                 packet.seqNum, packet.timestamp);
    return VCM_JITTER_BUFFER_ERROR;
  }
  if (ret == kCompleteSession && !retransmitted) {
    // We don't want to include timestamps which have suffered from
    // retransmission here, since we compensate with extra retransmission
    // delay within the jitter estimate.
    timing_->IncomingTimestamp(packet.timestamp, clock_->TimeInMilliseconds());
  }
  if (master_) {
    // Only trace the primary receiver to make it possible to parse and plot
    // the trace file.
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "Packet seqnum=%u timestamp=%u inserted at %u",
                 packet.seqNum, packet.timestamp,
                 MaskWord64ToUWord32(clock_->TimeInMilliseconds()));
  }
  return VCM_OK;
}

VCMEncodedFrame* VCMReceiver::FrameForDecoding(
    uint16_t max_wait_time_ms,
    int64_t& next_render_time_ms,
    bool render_timing,
    VCMReceiver* dual_receiver) {
  const int64_t start_time_ms = clock_->TimeInMilliseconds();
  uint32_t frame_timestamp = 0;
  // Exhaust wait time to get a complete frame for decoding.
  bool found_frame = jitter_buffer_.NextCompleteTimestamp(
      max_wait_time_ms, &frame_timestamp);

  if (!found_frame) {
    // Get an incomplete frame when enabled.
    const bool dual_receiver_enabled_and_passive = (dual_receiver != NULL &&
        dual_receiver->State() == kPassive &&
        dual_receiver->NackMode() == kNack);
    if (dual_receiver_enabled_and_passive &&
        !jitter_buffer_.CompleteSequenceWithNextFrame()) {
      // Jitter buffer state might get corrupt with this frame.
      dual_receiver->CopyJitterBufferStateFromReceiver(*this);
    }
    found_frame = jitter_buffer_.NextMaybeIncompleteTimestamp(
        &frame_timestamp);
  }

  if (!found_frame) {
    return NULL;
  }

  // We have a frame - Set timing and render timestamp.
  timing_->SetJitterDelay(jitter_buffer_.EstimatedJitterMs());
  const int64_t now_ms = clock_->TimeInMilliseconds();
  timing_->UpdateCurrentDelay(frame_timestamp);
  next_render_time_ms = timing_->RenderTimeMs(frame_timestamp, now_ms);
  // Check render timing.
  bool timing_error = false;
  // Assume that render timing errors are due to changes in the video stream.
  if (next_render_time_ms < 0) {
    timing_error = true;
  } else if (abs(next_render_time_ms - now_ms) > max_video_delay_ms_) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "This frame is out of our delay bounds, resetting jitter "
                 "buffer: %d > %d",
                 static_cast<int>(abs(next_render_time_ms - now_ms)),
                 max_video_delay_ms_);
    timing_error = true;
  } else if (static_cast<int>(timing_->TargetVideoDelay()) >
             max_video_delay_ms_) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
                 VCMId(vcm_id_, receiver_id_),
                 "More than %u ms target delay. Flushing jitter buffer and"
                 "resetting timing.", max_video_delay_ms_);
    timing_error = true;
  }

  if (timing_error) {
    // Timing error => reset timing and flush the jitter buffer.
    jitter_buffer_.Flush();
    timing_->Reset();
    return NULL;
  }

  if (!render_timing) {
    // Decode frame as close as possible to the render timestamp.
    const int32_t available_wait_time = max_wait_time_ms -
        static_cast<int32_t>(clock_->TimeInMilliseconds() - start_time_ms);
    uint16_t new_max_wait_time = static_cast<uint16_t>(
        VCM_MAX(available_wait_time, 0));
    uint32_t wait_time_ms = timing_->MaxWaitingTime(
        next_render_time_ms, clock_->TimeInMilliseconds());
    if (new_max_wait_time < wait_time_ms) {
      // We're not allowed to wait until the frame is supposed to be rendered,
      // waiting as long as we're allowed to avoid busy looping, and then return
      // NULL. Next call to this function might return the frame.
      render_wait_event_->Wait(max_wait_time_ms);
      return NULL;
    }
    // Wait until it's time to render.
    render_wait_event_->Wait(wait_time_ms);
  }

  // Extract the frame from the jitter buffer and set the render time.
  VCMEncodedFrame* frame = jitter_buffer_.ExtractAndSetDecode(frame_timestamp);
  if (frame == NULL) {
    return NULL;
  }
  frame->SetRenderTime(next_render_time_ms);
  TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame->TimeStamp(),
                          "SetRenderTS", "render_time", next_render_time_ms);
  if (dual_receiver != NULL) {
    dual_receiver->UpdateState(*frame);
  }
  if (!frame->Complete()) {
    // Update stats for incomplete frames.
    bool retransmitted = false;
    const int64_t last_packet_time_ms =
        jitter_buffer_.LastPacketTime(frame, &retransmitted);
    if (last_packet_time_ms >= 0 && !retransmitted) {
      // We don't want to include timestamps which have suffered from
      // retransmission here, since we compensate with extra retransmission
      // delay within the jitter estimate.
      timing_->IncomingTimestamp(frame_timestamp, last_packet_time_ms);
    }
  }
  return frame;
}

void VCMReceiver::ReleaseFrame(VCMEncodedFrame* frame) {
  jitter_buffer_.ReleaseFrame(frame);
}

void VCMReceiver::ReceiveStatistics(uint32_t* bitrate,
                                    uint32_t* framerate) {
  assert(bitrate);
  assert(framerate);
  jitter_buffer_.IncomingRateStatistics(framerate, bitrate);
}

void VCMReceiver::ReceivedFrameCount(VCMFrameCount* frame_count) const {
  assert(frame_count);
  jitter_buffer_.FrameStatistics(&frame_count->numDeltaFrames,
                                 &frame_count->numKeyFrames);
}

uint32_t VCMReceiver::DiscardedPackets() const {
  return jitter_buffer_.num_discarded_packets();
}

void VCMReceiver::SetNackMode(VCMNackMode nackMode,
                              int low_rtt_nack_threshold_ms,
                              int high_rtt_nack_threshold_ms) {
  CriticalSectionScoped cs(crit_sect_);
  // Default to always having NACK enabled in hybrid mode.
  jitter_buffer_.SetNackMode(nackMode, low_rtt_nack_threshold_ms,
                             high_rtt_nack_threshold_ms);
  if (!master_) {
    state_ = kPassive;  // The dual decoder defaults to passive.
  }
}

void VCMReceiver::SetNackSettings(size_t max_nack_list_size,
                                  int max_packet_age_to_nack,
                                  int max_incomplete_time_ms) {
  jitter_buffer_.SetNackSettings(max_nack_list_size,
                                 max_packet_age_to_nack,
                                 max_incomplete_time_ms);
}

VCMNackMode VCMReceiver::NackMode() const {
  CriticalSectionScoped cs(crit_sect_);
  return jitter_buffer_.nack_mode();
}

VCMNackStatus VCMReceiver::NackList(uint16_t* nack_list,
                                    uint16_t size,
                                    uint16_t* nack_list_length) {
  bool request_key_frame = false;
  uint16_t* internal_nack_list = jitter_buffer_.GetNackList(
      nack_list_length, &request_key_frame);
  if (*nack_list_length > size) {
    *nack_list_length = 0;
    return kNackNeedMoreMemory;
  }
  if (internal_nack_list != NULL && *nack_list_length > 0) {
    memcpy(nack_list, internal_nack_list, *nack_list_length * sizeof(uint16_t));
  }
  if (request_key_frame) {
    return kNackKeyFrameRequest;
  }
  return kNackOk;
}

// Decide whether we should change decoder state. This should be done if the
// dual decoder has caught up with the decoder decoding with packet losses.
bool VCMReceiver::DualDecoderCaughtUp(VCMEncodedFrame* dual_frame,
                                      VCMReceiver& dual_receiver) const {
  if (dual_frame == NULL) {
    return false;
  }
  if (jitter_buffer_.LastDecodedTimestamp() == dual_frame->TimeStamp()) {
    dual_receiver.UpdateState(kWaitForPrimaryDecode);
    return true;
  }
  return false;
}

void VCMReceiver::CopyJitterBufferStateFromReceiver(
    const VCMReceiver& receiver) {
  jitter_buffer_.CopyFrom(receiver.jitter_buffer_);
}

VCMReceiverState VCMReceiver::State() const {
  CriticalSectionScoped cs(crit_sect_);
  return state_;
}

void VCMReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
  jitter_buffer_.SetDecodeErrorMode(decode_error_mode);
}

VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
  return jitter_buffer_.decode_error_mode();
}

int VCMReceiver::SetMinReceiverDelay(int desired_delay_ms) {
  CriticalSectionScoped cs(crit_sect_);
  if (desired_delay_ms < 0 || desired_delay_ms > kMaxReceiverDelayMs) {
    return -1;
  }
  max_video_delay_ms_ = desired_delay_ms + kMaxVideoDelayMs;
  // Initializing timing to the desired delay.
  timing_->set_min_playout_delay(desired_delay_ms);
  return 0;
}

int VCMReceiver::RenderBufferSizeMs() {
  uint32_t timestamp_start = 0u;
  uint32_t timestamp_end = 0u;
  // Render timestamps are computed just prior to decoding. Therefore this is
  // only an estimate based on frames' timestamps and current timing state.
  jitter_buffer_.RenderBufferSize(&timestamp_start, &timestamp_end);
  if (timestamp_start == timestamp_end) {
    return 0;
  }
  // Update timing.
  const int64_t now_ms = clock_->TimeInMilliseconds();
  timing_->SetJitterDelay(jitter_buffer_.EstimatedJitterMs());
  // Get render timestamps.
  uint32_t render_start = timing_->RenderTimeMs(timestamp_start, now_ms);
  uint32_t render_end = timing_->RenderTimeMs(timestamp_end, now_ms);
  return render_end - render_start;
}

void VCMReceiver::UpdateState(VCMReceiverState new_state) {
  CriticalSectionScoped cs(crit_sect_);
  assert(!(state_ == kPassive && new_state == kWaitForPrimaryDecode));
  state_ = new_state;
}

void VCMReceiver::UpdateState(const VCMEncodedFrame& frame) {
  if (jitter_buffer_.nack_mode() == kNoNack) {
    // Dual decoder mode has not been enabled.
    return;
  }
  // Update the dual receiver state.
  if (frame.Complete() && frame.FrameType() == kVideoFrameKey) {
    UpdateState(kPassive);
  }
  if (State() == kWaitForPrimaryDecode &&
      frame.Complete() && !frame.MissingFrame()) {
    UpdateState(kPassive);
  }
  if (frame.MissingFrame() || !frame.Complete()) {
    // State was corrupted, enable dual receiver.
    UpdateState(kReceiving);
  }
}
}  // namespace webrtc
<|endoftext|>


<commit_before>/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 *
 *  Data Differential YATL (i.e. libtest)  library
 *
 *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *
 *      * Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *      * Redistributions in binary form must reproduce the above
 *  copyright notice, this list of conditions and the following disclaimer
 *  in the documentation and/or other materials provided with the
 *  distribution.
 *
 *      * The names of its contributors may not be used to endorse or
 *  promote products derived from this software without specific prior
 *  written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <config.h>
#include <libtest/common.h>

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fnmatch.h>
#include <iostream>
#include <memory>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <signal.h>

#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif

using namespace libtest;

static void stats_print(Framework *frame)
{
  if (frame->failed() == 0 and frame->success() == 0)
  {
    return;
  }

  Outn();
  Out << "Collections\t\t\t\t\t" << frame->total();
  Out << "\tFailed\t\t\t\t\t" << frame->failed();
  Out << "\tSkipped\t\t\t\t\t" << frame->skipped();
  Out << "\tSucceeded\t\t\t\t" << frame->success();
  Outn();
  Out << "Tests\t\t\t\t\t" << frame->sum_total();
  Out << "\tFailed\t\t\t\t" << frame->sum_failed();
  Out << "\tSkipped\t\t\t\t" << frame->sum_skipped();
  Out << "\tSucceeded\t\t\t" << frame->sum_success();
}

#include <getopt.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  bool opt_massive= false;
  unsigned long int opt_repeat= 1; // Run all tests once
  bool opt_quiet= false;
  std::string collection_to_run;
  std::string wildcard;

  /*
    Valgrind does not currently work reliably, or sometimes at all, on OSX
    - Fri Jun 15 11:24:07 EDT 2012
  */
#if defined(TARGET_OS_OSX) && TARGET_OS_OSX
  if (valgrind_is_caller())
  {
    return EXIT_SKIP;
  }
#endif

  // Options parsing
  {
    enum long_option_t {
      OPT_LIBYATL_VERSION,
      OPT_LIBYATL_MATCH_COLLECTION,
      OPT_LIBYATL_MASSIVE,
      OPT_LIBYATL_QUIET,
      OPT_LIBYATL_MATCH_WILDCARD,
      OPT_LIBYATL_REPEAT
    };

    static struct option long_options[]=
    {
      { "version", no_argument, NULL, OPT_LIBYATL_VERSION },
      { "quiet", no_argument, NULL, OPT_LIBYATL_QUIET },
      { "repeat", no_argument, NULL, OPT_LIBYATL_REPEAT },
      { "collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION },
      { "wildcard", required_argument, NULL, OPT_LIBYATL_MATCH_WILDCARD },
      { "massive", no_argument, NULL, OPT_LIBYATL_MASSIVE },
      { 0, 0, 0, 0 }
    };

    int option_index= 0;
    while (1)
    {
      int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
      if (option_rv == -1)
      {
        break;
      }

      switch (option_rv)
      {
      case OPT_LIBYATL_VERSION:
        break;

      case OPT_LIBYATL_QUIET:
        opt_quiet= true;
        break;

      case OPT_LIBYATL_REPEAT:
        opt_repeat= strtoul(optarg, (char **) NULL, 10);
        break;

      case OPT_LIBYATL_MATCH_COLLECTION:
        collection_to_run= optarg;
        break;

      case OPT_LIBYATL_MATCH_WILDCARD:
        wildcard= optarg;
        break;

      case OPT_LIBYATL_MASSIVE:
        opt_massive= true;
        break;

      case '?':
        /* getopt_long already printed an error message. */
        Error << "unknown option to getopt_long()";
        exit(EXIT_FAILURE);

      default:
        break;
      }
    }
  }

  srandom((unsigned int)time(NULL));

  if (bool(getenv("YATL_REPEAT")) and (strtoul(getenv("YATL_REPEAT"), (char **) NULL, 10) > 1))
  {
    opt_repeat= strtoul(getenv("YATL_REPEAT"), (char **) NULL, 10);
  }

  if ((bool(getenv("YATL_QUIET")) and (strcmp(getenv("YATL_QUIET"), "0") == 0)) or opt_quiet)
  {
    opt_quiet= true;
  }
  else if (getenv("JENKINS_URL"))
  {
    if (bool(getenv("YATL_QUIET")) and (strcmp(getenv("YATL_QUIET"), "1") == 0))
    { }
    else
    {
      opt_quiet= true;
    }
  }

  if (opt_quiet)
  {
    close(STDOUT_FILENO);
  }

  char buffer[1024];
  if (getenv("LIBTEST_TMP"))
  {
    snprintf(buffer, sizeof(buffer), "%s", getenv("LIBTEST_TMP"));
  }
  else
  {
    snprintf(buffer, sizeof(buffer), "%s", LIBTEST_TEMP);
  }

  if (chdir(buffer) == -1)
  {
    char getcwd_buffer[1024];
    char *dir= getcwd(getcwd_buffer, sizeof(getcwd_buffer));

    Error << "Unable to chdir() from " << dir << " to " << buffer << " errno:" << strerror(errno);
    return EXIT_FAILURE;
  }

  if (libtest::libtool() == NULL)
  {
    Error << "Failed to locate libtool";
    return EXIT_FAILURE;
  }

  if (getenv("YATL_COLLECTION_TO_RUN"))
  {
    if (strlen(getenv("YATL_COLLECTION_TO_RUN")))
    {
      collection_to_run= getenv("YATL_COLLECTION_TO_RUN");
    }
  }

  if (collection_to_run.compare("none") == 0)
  {
    return EXIT_SUCCESS;
  }

  if (collection_to_run.empty() == false)
  {
    Out << "Only testing " <<  collection_to_run;
  }

  int exit_code;

  try
  {
    do
    {
      exit_code= EXIT_SUCCESS;
      fatal_assert(sigignore(SIGPIPE) == 0);

      libtest::SignalThread signal;
      if (signal.setup() == false)
      {
        Error << "Failed to setup signals";
        return EXIT_FAILURE;
      }

      std::auto_ptr<Framework> frame(new Framework(signal, collection_to_run, wildcard));

      // Run create(), bail on error.
      {
        switch (frame->create())
        {
        case TEST_SUCCESS:
          break;

        case TEST_SKIPPED:
          return EXIT_SKIP;

        case TEST_FAILURE:
          return EXIT_FAILURE;
        }
      }

      frame->exec();

      if (signal.is_shutdown() == false)
      {
        signal.set_shutdown(SHUTDOWN_GRACEFUL);
      }

      shutdown_t status= signal.get_shutdown();
      if (status == SHUTDOWN_FORCED)
      {
        Out << "Tests were aborted.";
        exit_code= EXIT_FAILURE;
      }
      else if (frame->failed())
      {
        Out << "Some test failed.";
        exit_code= EXIT_FAILURE;
      }
      else if (frame->skipped() and frame->failed() and frame->success())
      {
        Out << "Some tests were skipped.";
      }
      else if (frame->success() and (frame->failed() == 0))
      {
        Out << "All tests completed successfully.";
      }

      stats_print(frame.get());

      Outn(); // Generate a blank to break up the messages if make check/test has been run
    } while (exit_code == EXIT_SUCCESS and --opt_repeat);
  }
  catch (libtest::fatal& e)
  {
    std::cerr << e.what() << std::endl;
    exit_code= EXIT_FAILURE;
  }
  catch (libtest::disconnected& e)
  {
    std::cerr << "Unhandled disconnection occurred:" << e.what() << std::endl;
    exit_code= EXIT_FAILURE;
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
    exit_code= EXIT_FAILURE;
  }
  catch (...)
  {
    std::cerr << "Unknown exception halted execution." << std::endl;
    exit_code= EXIT_FAILURE;
  }

  return exit_code;
}
<commit_msg>Additional info on exit_code from main libtest.<commit_after>/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 *
 *  Data Differential YATL (i.e. libtest)  library
 *
 *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *
 *      * Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *      * Redistributions in binary form must reproduce the above
 *  copyright notice, this list of conditions and the following disclaimer
 *  in the documentation and/or other materials provided with the
 *  distribution.
 *
 *      * The names of its contributors may not be used to endorse or
 *  promote products derived from this software without specific prior
 *  written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <config.h>
#include <libtest/common.h>

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fnmatch.h>
#include <iostream>
#include <memory>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <signal.h>

#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif

using namespace libtest;

static void stats_print(Framework *frame)
{
  if (frame->failed() == 0 and frame->success() == 0)
  {
    return;
  }

  Outn();
  Out << "Collections\t\t\t\t\t" << frame->total();
  Out << "\tFailed\t\t\t\t\t" << frame->failed();
  Out << "\tSkipped\t\t\t\t\t" << frame->skipped();
  Out << "\tSucceeded\t\t\t\t" << frame->success();
  Outn();
  Out << "Tests\t\t\t\t\t" << frame->sum_total();
  Out << "\tFailed\t\t\t\t" << frame->sum_failed();
  Out << "\tSkipped\t\t\t\t" << frame->sum_skipped();
  Out << "\tSucceeded\t\t\t" << frame->sum_success();
}

#include <getopt.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  bool opt_massive= false;
  unsigned long int opt_repeat= 1; // Run all tests once
  bool opt_quiet= false;
  std::string collection_to_run;
  std::string wildcard;

  /*
    Valgrind does not currently work reliably, or sometimes at all, on OSX
    - Fri Jun 15 11:24:07 EDT 2012
  */
#if defined(TARGET_OS_OSX) && TARGET_OS_OSX
  if (valgrind_is_caller())
  {
    return EXIT_SKIP;
  }
#endif

  // Options parsing
  {
    enum long_option_t {
      OPT_LIBYATL_VERSION,
      OPT_LIBYATL_MATCH_COLLECTION,
      OPT_LIBYATL_MASSIVE,
      OPT_LIBYATL_QUIET,
      OPT_LIBYATL_MATCH_WILDCARD,
      OPT_LIBYATL_REPEAT
    };

    static struct option long_options[]=
    {
      { "version", no_argument, NULL, OPT_LIBYATL_VERSION },
      { "quiet", no_argument, NULL, OPT_LIBYATL_QUIET },
      { "repeat", no_argument, NULL, OPT_LIBYATL_REPEAT },
      { "collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION },
      { "wildcard", required_argument, NULL, OPT_LIBYATL_MATCH_WILDCARD },
      { "massive", no_argument, NULL, OPT_LIBYATL_MASSIVE },
      { 0, 0, 0, 0 }
    };

    int option_index= 0;
    while (1)
    {
      int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
      if (option_rv == -1)
      {
        break;
      }

      switch (option_rv)
      {
      case OPT_LIBYATL_VERSION:
        break;

      case OPT_LIBYATL_QUIET:
        opt_quiet= true;
        break;

      case OPT_LIBYATL_REPEAT:
        opt_repeat= strtoul(optarg, (char **) NULL, 10);
        break;

      case OPT_LIBYATL_MATCH_COLLECTION:
        collection_to_run= optarg;
        break;

      case OPT_LIBYATL_MATCH_WILDCARD:
        wildcard= optarg;
        break;

      case OPT_LIBYATL_MASSIVE:
        opt_massive= true;
        break;

      case '?':
        /* getopt_long already printed an error message. */
        Error << "unknown option to getopt_long()";
        exit(EXIT_FAILURE);

      default:
        break;
      }
    }
  }

  srandom((unsigned int)time(NULL));

  if (bool(getenv("YATL_REPEAT")) and (strtoul(getenv("YATL_REPEAT"), (char **) NULL, 10) > 1))
  {
    opt_repeat= strtoul(getenv("YATL_REPEAT"), (char **) NULL, 10);
  }

  if ((bool(getenv("YATL_QUIET")) and (strcmp(getenv("YATL_QUIET"), "0") == 0)) or opt_quiet)
  {
    opt_quiet= true;
  }
  else if (getenv("JENKINS_URL"))
  {
    if (bool(getenv("YATL_QUIET")) and (strcmp(getenv("YATL_QUIET"), "1") == 0))
    { }
    else
    {
      opt_quiet= true;
    }
  }

  if (opt_quiet)
  {
    close(STDOUT_FILENO);
  }

  char buffer[1024];
  if (getenv("LIBTEST_TMP"))
  {
    snprintf(buffer, sizeof(buffer), "%s", getenv("LIBTEST_TMP"));
  }
  else
  {
    snprintf(buffer, sizeof(buffer), "%s", LIBTEST_TEMP);
  }

  if (chdir(buffer) == -1)
  {
    char getcwd_buffer[1024];
    char *dir= getcwd(getcwd_buffer, sizeof(getcwd_buffer));

    Error << "Unable to chdir() from " << dir << " to " << buffer << " errno:" << strerror(errno);
    return EXIT_FAILURE;
  }

  if (libtest::libtool() == NULL)
  {
    Error << "Failed to locate libtool";
    return EXIT_FAILURE;
  }

  if (getenv("YATL_COLLECTION_TO_RUN"))
  {
    if (strlen(getenv("YATL_COLLECTION_TO_RUN")))
    {
      collection_to_run= getenv("YATL_COLLECTION_TO_RUN");
    }
  }

  if (collection_to_run.compare("none") == 0)
  {
    return EXIT_SUCCESS;
  }

  if (collection_to_run.empty() == false)
  {
    Out << "Only testing " <<  collection_to_run;
  }

  int exit_code;

  try
  {
    do
    {
      exit_code= EXIT_SUCCESS;
      fatal_assert(sigignore(SIGPIPE) == 0);

      libtest::SignalThread signal;
      if (signal.setup() == false)
      {
        Error << "Failed to setup signals";
        return EXIT_FAILURE;
      }

      std::auto_ptr<Framework> frame(new Framework(signal, collection_to_run, wildcard));

      // Run create(), bail on error.
      {
        switch (frame->create())
        {
        case TEST_SUCCESS:
          break;

        case TEST_SKIPPED:
          return EXIT_SKIP;

        case TEST_FAILURE:
          std::cerr << "frame->create()" << std::endl;
          return EXIT_FAILURE;
        }
      }

      frame->exec();

      if (signal.is_shutdown() == false)
      {
        signal.set_shutdown(SHUTDOWN_GRACEFUL);
      }

      shutdown_t status= signal.get_shutdown();
      if (status == SHUTDOWN_FORCED)
      {
        Out << "Tests were aborted.";
        exit_code= EXIT_FAILURE;
      }
      else if (frame->failed())
      {
        Out << "Some test failed.";
        exit_code= EXIT_FAILURE;
      }
      else if (frame->skipped() and frame->failed() and frame->success())
      {
        Out << "Some tests were skipped.";
      }
      else if (frame->success() and (frame->failed() == 0))
      {
        Out << "All tests completed successfully.";
      }

      stats_print(frame.get());

      Outn(); // Generate a blank to break up the messages if make check/test has been run
    } while (exit_code == EXIT_SUCCESS and --opt_repeat);
  }
  catch (libtest::fatal& e)
  {
    std::cerr << "FATAL:" << e.what() << std::endl;
    exit_code= EXIT_FAILURE;
  }
  catch (libtest::disconnected& e)
  {
    std::cerr << "Unhandled disconnection occurred:" << e.what() << std::endl;
    exit_code= EXIT_FAILURE;
  }
  catch (std::exception& e)
  {
    std::cerr << "std::exception:" << e.what() << std::endl;
    exit_code= EXIT_FAILURE;
  }
  catch (...)
  {
    std::cerr << "Unknown exception halted execution." << std::endl;
    exit_code= EXIT_FAILURE;
  }

  return exit_code;
}
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include <functional>
#include <memory>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>

#include "cpu_nop_elimination.hpp"
#include "ngraph/op/convert.hpp"
#include "ngraph/op/pad.hpp"
#include "ngraph/op/sum.hpp"

#define TI(x) std::type_index(typeid(x))

#define HANDLER_DECL(x)                                                                            \
    static bool x(const std::shared_ptr<ngraph::Function>& function,                               \
                  const std::shared_ptr<ngraph::Node>& node)

HANDLER_DECL(eliminate_pad)
{
    auto pad = std::dynamic_pointer_cast<ngraph::op::Pad>(node);
    if (pad->get_input_shape(0) == pad->get_output_shape(0))
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

HANDLER_DECL(eliminate_sum)
{
    auto sum = std::dynamic_pointer_cast<ngraph::op::Sum>(node);
    if (sum->get_reduction_axes().empty())
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

HANDLER_DECL(eliminate_convert)
{
    auto convert = std::dynamic_pointer_cast<ngraph::op::Convert>(node);
    if (convert->get_convert_element_type() == convert->get_input_op(0)->get_element_type())
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

static const std::unordered_map<std::type_index,
                                std::function<bool(const std::shared_ptr<ngraph::Function>&,
                                                   const std::shared_ptr<ngraph::Node>&)>>
    dispatcher{{TI(ngraph::op::Pad), &eliminate_pad},
               {TI(ngraph::op::Sum), &eliminate_sum},
               {TI(ngraph::op::Convert), &eliminate_convert}};

bool ngraph::runtime::cpu::pass::CPUNopElimination::run_on_function(
    std::shared_ptr<ngraph::Function> function)
{
    bool clobbered = false;

    for (const auto& n : function->get_ops())
    {
        // Work around a warning [-Wpotentially-evaluated-expression]
        const Node& node = *n;
        auto handler = dispatcher.find(TI(node));
        if (handler != dispatcher.end())
        {
            clobbered = handler->second(function, n) || clobbered;
        }
    }

    return clobbered;
}
<commit_msg>CPU: Eliminate slices (#849)<commit_after>/*******************************************************************************
* Copyright 2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include <functional>
#include <memory>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>

#include "cpu_nop_elimination.hpp"
#include "ngraph/op/convert.hpp"
#include "ngraph/op/pad.hpp"
#include "ngraph/op/slice.hpp"
#include "ngraph/op/sum.hpp"

#define TI(x) std::type_index(typeid(x))

#define HANDLER_DECL(x)                                                                            \
    static bool x(const std::shared_ptr<ngraph::Function>& function,                               \
                  const std::shared_ptr<ngraph::Node>& node)

HANDLER_DECL(eliminate_pad)
{
    auto pad = std::dynamic_pointer_cast<ngraph::op::Pad>(node);
    if (pad->get_input_shape(0) == pad->get_output_shape(0))
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

HANDLER_DECL(eliminate_sum)
{
    auto sum = std::dynamic_pointer_cast<ngraph::op::Sum>(node);
    if (sum->get_reduction_axes().empty())
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

HANDLER_DECL(eliminate_convert)
{
    auto convert = std::dynamic_pointer_cast<ngraph::op::Convert>(node);
    if (convert->get_convert_element_type() == convert->get_input_op(0)->get_element_type())
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

HANDLER_DECL(eliminate_slice)
{
    auto slice = std::dynamic_pointer_cast<ngraph::op::Slice>(node);
    if (slice->get_input_shape(0) == slice->get_output_shape(0))
    {
        function->replace_node(node, node->get_input_op(0));
        return true;
    }
    return false;
}

static const std::unordered_map<std::type_index,
                                std::function<bool(const std::shared_ptr<ngraph::Function>&,
                                                   const std::shared_ptr<ngraph::Node>&)>>
    dispatcher{{TI(ngraph::op::Pad), &eliminate_pad},
               {TI(ngraph::op::Sum), &eliminate_sum},
               {TI(ngraph::op::Convert), &eliminate_convert},
               {TI(ngraph::op::Slice), &eliminate_slice}};

bool ngraph::runtime::cpu::pass::CPUNopElimination::run_on_function(
    std::shared_ptr<ngraph::Function> function)
{
    bool clobbered = false;

    for (const auto& n : function->get_ops())
    {
        // Work around a warning [-Wpotentially-evaluated-expression]
        const Node& node = *n;
        auto handler = dispatcher.find(TI(node));
        if (handler != dispatcher.end())
        {
            clobbered = handler->second(function, n) || clobbered;
        }
    }

    return clobbered;
}
<|endoftext|>


<commit_before>#include "WorldMapGenerator.h"

#include <utility>
#include <list>
#include <tuple>

#include "../maths/mathshelper.h"

using namespace arma;
using namespace maths;
using namespace img;

// MODULES ( dplacer ?)

WorldMapGeneratorModule::WorldMapGeneratorModule(WorldMapGenerator * parent) :
	_parent(parent) {

}

cube & WorldMapGeneratorModule::reliefMap(WorldMap & map) const {
	return map._reliefMap;
}

std::mt19937 & WorldMapGeneratorModule::rng() const {
	return _parent->_rng;
}

// -----
ReliefMapGenerator::ReliefMapGenerator(WorldMapGenerator * parent) :
	WorldMapGeneratorModule(parent) {

}

// -----
const float CustomWorldRMGenerator::PIXEL_UNIT = 100;

CustomWorldRMGenerator::CustomWorldRMGenerator(WorldMapGenerator * parent) :
	ReliefMapGenerator(parent) {

}

void CustomWorldRMGenerator::generate(WorldMap & map) const {
	cube relief = reliefMap(map);

	// Nombre de biomes  gnrer.
	uint32_t size = relief.n_rows * relief.n_cols;
	uint32_t biomeCount = (uint32_t)(_biomeDensity * (float) size / PIXEL_UNIT);

	// -> Cration de la grille pour le placement des points de manire alatoire,
	// mais avec une distance minimum.

	// Calcul des dimensions de la grille
	float minDistance = PIXEL_UNIT / 2.0 * sqrt(_biomeDensity);

	uint32_t sliceCount = (uint32_t)((float)relief.n_rows / minDistance);
	float sliceSize = (float)relief.n_rows / (float)sliceCount;

	uint32_t caseCount = (uint32_t)((float)relief.n_cols / minDistance);
	float caseSize = (float)relief.n_cols / (float)caseCount;

	// Prparation de la grille
	typedef std::tuple<float, float, float, float> point; // pour plus de lisibilit
	std::vector<std::vector<point>> pointsMap; pointsMap.reserve(sliceCount);
	std::vector<std::pair<uint32_t, uint32_t>> grid; grid.reserve(size);

	for (int x = 0; x < sliceCount; x++) {
		pointsMap.emplace_back();

		auto slice = pointsMap[x];
		slice.reserve(caseCount);

		for (int y = 0; y < caseCount; y++) {
			grid.emplace_back(x, y);
			slice.emplace_back(-1, -1, 0, 0);
		}
	}

	// Gnration des points
	std::uniform_real_distribution<double> rand(0.0, 1.0);

	for (int i = 0; i < biomeCount; i++) {
		// Gnration des coordonnes des points
		uint32_t randIndex = (uint32_t)(rand(rng()) * grid.size());
		std::pair<uint32_t, uint32_t> randPoint = grid.at(randIndex);
		grid.erase(grid.begin() + randIndex);

		uint32_t x = randPoint.first;
		uint32_t y = randPoint.second;

		// Calcul des limites dans lesquelles on peut avoir un point
		double limNegX = 0;
		double limPosX = sliceSize;
		double limNegY = 0;
		double limPosY = caseSize;

		if (x > 0) {
			auto negXCase = pointsMap[x - 1][y];

			if (std::get<0>(negXCase) > 0) {
				limNegX = std::get<0>(negXCase);
			}
		}
		if (x < sliceCount - 1) {
			auto posXCase = pointsMap[x + 1][y];

			if (std::get<0>(posXCase) > 0) {
				limPosX = std::get<0>(posXCase);
			}
		}
		if (y > 0) {
			auto negYCase = pointsMap[x][y - 1];

			if (std::get<1>(negYCase) > 0) {
				limNegY = std::get<1>(negYCase);
			}
		}
		if (y < caseCount - 1) {
			auto posYCase = pointsMap[x][y + 1];

			if (std::get<1>(posYCase) > 0) {
				limPosY = std::get<1>(posYCase);
			}
		}

		//  partir des limites on peut dterminer la position random du point
		double randX = rand(rng());
		double randY = rand(rng());

		pointsMap[x][y] = std::make_tuple<float, float, float, float>(
			randX * (limPosX - limNegX) + limNegX + x * sliceSize,
			randY * (limPosY - limNegY) + limNegY + y * caseSize,
			0, 0);

		// ET VOILA !
		// Maintenant est-ce qu'on trouve les valeurs ici, ou est-ce qu'on attend ?
		// Est-ce qu'on spare cet algorithme du reste ?
		// Tant de question sans rponse...
	}

	// -> Interpolation des valeurs des points pour reconstituer une map

}

// WorldMapGenerator

WorldMapGenerator::WorldMapGenerator(uint32_t sizeX, uint32_t sizeY) :
	_sizeX(sizeX), _sizeY(sizeY),
	_reliefMap(nullptr) {

}

WorldMapGenerator::~WorldMapGenerator() {

}

std::unique_ptr<WorldMap> WorldMapGenerator::generate() {
	std::unique_ptr<WorldMap> map = std::make_unique<WorldMap>(_sizeX, _sizeY);

	if (_reliefMap != nullptr) _reliefMap->generate(*map);

	return map;
}
<commit_msg>Reflexions supplémentaires sur la manière de mener le problème.<commit_after>#include "WorldMapGenerator.h"

#include <utility>
#include <list>
#include <tuple>

#include "../maths/mathshelper.h"

using namespace arma;
using namespace maths;
using namespace img;

// MODULES ( dplacer ?)

WorldMapGeneratorModule::WorldMapGeneratorModule(WorldMapGenerator * parent) :
	_parent(parent) {

}

cube & WorldMapGeneratorModule::reliefMap(WorldMap & map) const {
	return map._reliefMap;
}

std::mt19937 & WorldMapGeneratorModule::rng() const {
	return _parent->_rng;
}

// -----
ReliefMapGenerator::ReliefMapGenerator(WorldMapGenerator * parent) :
	WorldMapGeneratorModule(parent) {

}

// -----
const float CustomWorldRMGenerator::PIXEL_UNIT = 100;

CustomWorldRMGenerator::CustomWorldRMGenerator(WorldMapGenerator * parent) :
	ReliefMapGenerator(parent) {

}

void CustomWorldRMGenerator::generate(WorldMap & map) const {
	cube relief = reliefMap(map);

	// Nombre de biomes  gnrer.
	uint32_t size = relief.n_rows * relief.n_cols;
	uint32_t biomeCount = (uint32_t)(_biomeDensity * (float) size / PIXEL_UNIT);

	// -> Cration de la grille pour le placement des points de manire alatoire,
	// mais avec une distance minimum.

	// Calcul des dimensions de la grille
	float minDistance = PIXEL_UNIT / 2.0 * sqrt(_biomeDensity);

	uint32_t sliceCount = (uint32_t)((float)relief.n_rows / minDistance);
	float sliceSize = (float)relief.n_rows / (float)sliceCount;

	uint32_t caseCount = (uint32_t)((float)relief.n_cols / minDistance);
	float caseSize = (float)relief.n_cols / (float)caseCount;

	// Prparation de la grille
	typedef std::tuple<float, float, float, float> point; // pour plus de lisibilit
	std::vector<std::vector<point>> pointsMap; pointsMap.reserve(sliceCount);
	std::vector<std::pair<uint32_t, uint32_t>> grid; grid.reserve(size);

	for (int x = 0; x < sliceCount; x++) {
		pointsMap.emplace_back();

		auto slice = pointsMap[x];
		slice.reserve(caseCount);

		for (int y = 0; y < caseCount; y++) {
			grid.emplace_back(x, y);
			slice.emplace_back(-1, -1, 0, 0);
		}
	}

	// Gnration des points
	std::uniform_real_distribution<double> rand(0.0, 1.0);

	for (int i = 0; i < biomeCount; i++) {
		// Gnration des coordonnes des points
		uint32_t randIndex = (uint32_t)(rand(rng()) * grid.size());
		std::pair<uint32_t, uint32_t> randPoint = grid.at(randIndex);
		grid.erase(grid.begin() + randIndex);

		uint32_t x = randPoint.first;
		uint32_t y = randPoint.second;

		// Calcul des limites dans lesquelles on peut avoir un point
		double limNegX = 0;
		double limPosX = sliceSize;
		double limNegY = 0;
		double limPosY = caseSize;

		if (x > 0) {
			auto negXCase = pointsMap[x - 1][y];

			if (std::get<0>(negXCase) > 0) {
				limNegX = std::get<0>(negXCase);
			}
		}
		if (x < sliceCount - 1) {
			auto posXCase = pointsMap[x + 1][y];

			if (std::get<0>(posXCase) > 0) {
				limPosX = std::get<0>(posXCase);
			}
		}
		if (y > 0) {
			auto negYCase = pointsMap[x][y - 1];

			if (std::get<1>(negYCase) > 0) {
				limNegY = std::get<1>(negYCase);
			}
		}
		if (y < caseCount - 1) {
			auto posYCase = pointsMap[x][y + 1];

			if (std::get<1>(posYCase) > 0) {
				limPosY = std::get<1>(posYCase);
			}
		}

		//  partir des limites on peut dterminer la position random du point
		double randX = rand(rng());
		double randY = rand(rng());

		float elevation = 0;
		float diff = 0;

		pointsMap[x][y] = std::tuple<float, float, float, float>(
			(float)(randX * (limPosX - limNegX) + limNegX + x * sliceSize),
			(float)(randY * (limPosY - limNegY) + limNegY + y * caseSize),
			elevation, diff);

		// ET VOILA !
		// Maintenant est-ce qu'on trouve les valeurs ici, ou est-ce qu'on attend ?
		// Est-ce qu'on spare cet algorithme du reste ?
		// Tant de question sans rponse...
	}

	// -> Interpolation des valeurs des points pour reconstituer une map
	// https://en.wikipedia.org/wiki/Inverse_distance_weighting
}

// WorldMapGenerator

WorldMapGenerator::WorldMapGenerator(uint32_t sizeX, uint32_t sizeY) :
	_sizeX(sizeX), _sizeY(sizeY),
	_reliefMap(nullptr) {

}

WorldMapGenerator::~WorldMapGenerator() {

}

std::unique_ptr<WorldMap> WorldMapGenerator::generate() {
	std::unique_ptr<WorldMap> map = std::make_unique<WorldMap>(_sizeX, _sizeY);

	if (_reliefMap != nullptr) _reliefMap->generate(*map);

	return map;
}
<|endoftext|>


<commit_before>#include <k52/optimization/params/double_parameters_array.h>

#include <stdexcept>

namespace k52
{
namespace optimization
{

DoubleParametersArray::DoubleParametersArray(double min_value,
                                             double max_value,
                                             double desired_precision,
                                             size_t number_of_parameters)
    : sample_parameter_ (new DoubleParameter(min_value, min_value, max_value, desired_precision)),
      values_(number_of_parameters)
{
    SetConstChromosomeSize(CountTotalChromosomeSize());
}

DoubleParametersArray* DoubleParametersArray::Clone() const
{
    DoubleParametersArray* clone = new DoubleParametersArray();
    clone->values_ = values_;

    clone->sample_parameter_ = sample_parameter_ != NULL ?
        DoubleParameter::shared_ptr( sample_parameter_->Clone() ) :
        DoubleParameter::shared_ptr();

    clone->SetConstChromosomeSize(CountTotalChromosomeSize());

    return clone;
}

bool DoubleParametersArray::CheckConstraints() const
{
    for(size_t i=0; i<values_.size(); i++)
    {
        //TODO
        //copypaste from DoubleParameter
        if(values_[i] < get_min_value() || values_[i] > get_max_value())
        {
            return false;
        }
    }
    return true;
}

void DoubleParametersArray::SetChromosome(std::vector<bool>::iterator from, std::vector<bool>::iterator to) const
{
    //TODO
    //copypaste from CompositeDiscreteParameters
    size_t chromosome_size = to - from;

    this->CheckForConstChromosomeSize(chromosome_size);

    std::vector<bool>::iterator current_from = from;
    size_t parameter_chromosome_size = sample_parameter_->GetChromosomeSize();

    for(size_t i = 0; i < values_.size(); i++)
    {
        std::vector<bool>::iterator current_to = current_from + parameter_chromosome_size;

        sample_parameter_->SetValue(values_[i]);

        sample_parameter_->SetChromosome(current_from, current_to);

        current_from = current_to;
    }
}

void DoubleParametersArray::SetFromChromosome(std::vector<bool>::const_iterator from, std::vector<bool>::const_iterator to)
{
    //TODO
    //copypaste from CompositeDiscreteParameters
    size_t chromosome_size = to - from;

    this->CheckForConstChromosomeSize(chromosome_size);

    std::vector<bool>::const_iterator current_from = from;
    size_t parameter_chromosome_size = sample_parameter_->GetChromosomeSize();

    for(size_t i = 0; i < values_.size(); i++)
    {
        std::vector<bool>::const_iterator current_to = current_from + parameter_chromosome_size;

        sample_parameter_->SetFromChromosome(current_from, current_to);

        values_[i] = sample_parameter_->GetValue();

        current_from = current_to;
    }
}

std::vector<double> DoubleParametersArray::GetValues() const
{
    return values_;
}

double DoubleParametersArray::get_max_value() const
{
    return sample_parameter_->get_max_value();
}

double DoubleParametersArray::get_min_value() const
{
    return sample_parameter_->get_min_value();
}

size_t DoubleParametersArray::get_number_of_parameters() const
{
    return values_.size();
}

double DoubleParametersArray::get_actual_precision() const
{
    return sample_parameter_->get_actual_precision();
}

DoubleParametersArray::DoubleParametersArray() {}

size_t DoubleParametersArray::CountTotalChromosomeSize() const
{
    return sample_parameter_->GetChromosomeSize() * values_.size();
}

}/* namespace optimization */
}/* namespace k52 */
<commit_msg>CheckConstaraints implemented using sample double parameter<commit_after>#include <k52/optimization/params/double_parameters_array.h>

#include <stdexcept>

namespace k52
{
namespace optimization
{

DoubleParametersArray::DoubleParametersArray(double min_value,
                                             double max_value,
                                             double desired_precision,
                                             size_t number_of_parameters)
    : sample_parameter_ (new DoubleParameter(min_value, min_value, max_value, desired_precision)),
      values_(number_of_parameters)
{
    SetConstChromosomeSize(CountTotalChromosomeSize());
}

DoubleParametersArray* DoubleParametersArray::Clone() const
{
    DoubleParametersArray* clone = new DoubleParametersArray();
    clone->values_ = values_;

    clone->sample_parameter_ = sample_parameter_ != NULL ?
        DoubleParameter::shared_ptr( sample_parameter_->Clone() ) :
        DoubleParameter::shared_ptr();

    clone->SetConstChromosomeSize(CountTotalChromosomeSize());

    return clone;
}

bool DoubleParametersArray::CheckConstraints() const
{
    for(size_t i=0; i<values_.size(); i++)
    {
        sample_parameter_->SetValue(values_[i]);
        if(!sample_parameter_->CheckConstraints())
        {
            return false;
        }
    }
    return true;
}

void DoubleParametersArray::SetChromosome(std::vector<bool>::iterator from, std::vector<bool>::iterator to) const
{
    //TODO
    //copypaste from CompositeDiscreteParameters
    size_t chromosome_size = to - from;

    this->CheckForConstChromosomeSize(chromosome_size);

    std::vector<bool>::iterator current_from = from;
    size_t parameter_chromosome_size = sample_parameter_->GetChromosomeSize();

    for(size_t i = 0; i < values_.size(); i++)
    {
        std::vector<bool>::iterator current_to = current_from + parameter_chromosome_size;

        sample_parameter_->SetValue(values_[i]);

        sample_parameter_->SetChromosome(current_from, current_to);

        current_from = current_to;
    }
}

void DoubleParametersArray::SetFromChromosome(std::vector<bool>::const_iterator from, std::vector<bool>::const_iterator to)
{
    //TODO
    //copypaste from CompositeDiscreteParameters
    size_t chromosome_size = to - from;

    this->CheckForConstChromosomeSize(chromosome_size);

    std::vector<bool>::const_iterator current_from = from;
    size_t parameter_chromosome_size = sample_parameter_->GetChromosomeSize();

    for(size_t i = 0; i < values_.size(); i++)
    {
        std::vector<bool>::const_iterator current_to = current_from + parameter_chromosome_size;

        sample_parameter_->SetFromChromosome(current_from, current_to);

        values_[i] = sample_parameter_->GetValue();

        current_from = current_to;
    }
}

std::vector<double> DoubleParametersArray::GetValues() const
{
    return values_;
}

double DoubleParametersArray::get_max_value() const
{
    return sample_parameter_->get_max_value();
}

double DoubleParametersArray::get_min_value() const
{
    return sample_parameter_->get_min_value();
}

size_t DoubleParametersArray::get_number_of_parameters() const
{
    return values_.size();
}

double DoubleParametersArray::get_actual_precision() const
{
    return sample_parameter_->get_actual_precision();
}

DoubleParametersArray::DoubleParametersArray() {}

size_t DoubleParametersArray::CountTotalChromosomeSize() const
{
    return sample_parameter_->GetChromosomeSize() * values_.size();
}

}/* namespace optimization */
}/* namespace k52 */
<|endoftext|>


<commit_before>//         $Id$
//
// You received this file as part of MCA2
// Modular Controller Architecture Version 2
//
//Copyright (C) Forschungszentrum Informatik Karlsruhe
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// this is a -*- C++ -*- file
//----------------------------------------------------------------------
//----------------------------------------------------------------------

#ifndef __XrdWin32_h__
#define __XrdWin32_h__

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <time.h>
#include <direct.h>
#include <sys/types.h>
#include <Winsock2.h>

#ifndef POLLIN
#define POLLIN          0x0001    /* There is data to read */
#define POLLPRI         0x0002    /* There is urgent data to read */
#define POLLOUT         0x0004    /* Writing now will not block */
#define POLLERR         0x0008    /* Error condition */
#define POLLHUP         0x0010    /* Hung up */
#define POLLNVAL        0x0020    /* Invalid request: fd not open */
#define POLLRDNORM      0x0001
#define POLLWRNORM      0x0002
#define POLLRDBAND      0x0000

struct pollfd {
   unsigned int fd;
   short events;
   short revents;
};
#endif

#define EMSGSIZE        WSAEMSGSIZE
#define EAFNOSUPPORT    WSAEAFNOSUPPORT
#define EWOULDBLOCK     WSAEWOULDBLOCK
#define ECONNRESET      WSAECONNRESET
#define EINPROGRESS     WSAEINPROGRESS
#define ENOBUFS         WSAENOBUFS
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
#define ECONNREFUSED    WSAECONNREFUSED
#define EBADFD          WSAENOTSOCK
#define EOPNOTSUPP      WSAEOPNOTSUPP
#define ENETUNREACH     WSAENETUNREACH
#define EHOSTUNREACH    WSAEHOSTUNREACH
#define EHOSTDOWN       WSAEHOSTDOWN
#define EISCONN         WSAEISCONN
#define ECONNRESET      WSAECONNRESET
#define ECONNABORTED    WSAECONNABORTED
#define ESHUTDOWN       WSAESHUTDOWN
#ifndef ETIMEDOUT
#define ETIMEDOUT       WSAETIMEDOUT
#endif
#define ETXTBSY         26

#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
#define WIFEXITED(w)   (((w) & 0xff) == 0)
#define WTERMSIG(w)     ((w) & 0x7f)
#define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))

#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&(S_IFMT)) == (S_IFDIR))
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m)&(S_IFMT)) == (S_IFREG))
#endif
#ifndef S_IXUSR
#define S_IXUSR 00100
#endif
#ifndef S_IRGRP
#define S_IRGRP 00040
#endif
#ifndef S_IXGRP
#define S_IXGRP 00010
#endif
#ifndef S_IROTH
#define S_IROTH 00004
#endif
#ifndef S_IXOTH
#define S_IXOTH 00001
#endif
#ifndef S_IRUSR
#define S_IRUSR S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR S_IWRITE
#endif
#ifndef S_IWGRP
#define S_IWGRP 000020
#endif
#ifndef S_IWOTH
#define S_IWOTH 000002
#endif
#ifndef S_IRWXU
#define S_IRWXU 0000700
#endif
#ifndef S_IRWXG
#define S_IRWXG 0000070
#endif

#ifndef S_ISFIFO
# ifndef S_IFIFO
#  define S_IFIFO 0010000
# endif
# define S_ISFIFO(m)	((m & S_IFMT) == S_IFIFO)
#endif

#ifndef S_IFSOCK
#define S_IFSOCK   0140000
#endif

#define _SC_PAGESIZE 1

#define F_GETFL      1
#define F_SETFL      2
#define F_GETFD      4
#define F_SETFD      8

#define FD_CLOEXEC   1
#define O_NDELAY     2
#define O_NONBLOCK   4

#define X_OK 1
#define W_OK 2
#define R_OK 4

#define RTLD_NOW 0x0001

#ifndef STDIN_FILENO
#define STDIN_FILENO    0
#define STDOUT_FILENO   1
#define STDERR_FILENO   2
#endif

#ifndef fsync
#define fsync(a) _commit(a)
#endif

#ifndef socklen_t
#define socklen_t int
#endif

#ifndef SOCKLEN_t
#define SOCKLEN_t int
#endif

#ifndef snprintf
#define snprintf _snprintf
#endif

#ifndef caddr_t
typedef char* caddr_t;
#endif

#ifndef pid_t
typedef int pid_t;
#endif

#ifndef mode_t
typedef unsigned int mode_t;
#endif

#ifndef uint16_t
typedef unsigned short uint16_t;
#endif

struct timezone {
   int tz_minuteswest; /* minutes west of Greenwich */
   int tz_dsttime;     /* type of dst correction */
};

inline int poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
   unsigned int max_fd = 0;
   unsigned int i;

   fd_set *open_fds, *read_fds, *write_fds, *except_fds;
   struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };

   for (i = 0; i < nfds; ++i) {
      if (fds[i].fd > max_fd) {
         max_fd = fds[i].fd;
      }
   }

   size_t fds_size = (max_fd + 1) * sizeof (fd_set);

   open_fds = (fd_set *) malloc (fds_size);
   read_fds = (fd_set *) malloc (fds_size);
   write_fds = (fd_set *) malloc (fds_size);
   except_fds = (fd_set *) malloc (fds_size);

   if (!open_fds || !read_fds || !write_fds || !except_fds) {
      return -1;
   }

   FD_ZERO(open_fds) ;
   FD_ZERO(read_fds) ;
   FD_ZERO(write_fds) ;
   FD_ZERO(except_fds) ;

   for ( i = 0; i < nfds; ++i) {
      FD_SET (fds[i].fd, open_fds);
      if (fds[i].events & POLLIN)
         FD_SET (fds[i].fd, read_fds);
      if (fds[i].events & POLLOUT)
         FD_SET (fds[i].fd, write_fds);
      if (fds[i].events & POLLPRI)
         FD_SET (fds[i].fd, except_fds);
   }

//  Sleep(1);
   int ret = select(max_fd + 1, read_fds, write_fds, except_fds, timeout < 0 ? NULL : &tv);

   for (i = 0; i < nfds; ++i) {
      if (!FD_ISSET (fds[i].fd, open_fds))
         fds[i].revents = POLLNVAL;
      else if (ret < 0)
         fds[i].revents = POLLERR;
      else {
         fds[i].revents = 0;
         if (FD_ISSET (fds[i].fd, read_fds))
            fds[i].revents |= POLLIN;
         if (FD_ISSET (fds[i].fd, write_fds))
            fds[i].revents |= POLLOUT;
         if (FD_ISSET (fds[i].fd, except_fds))
            fds[i].revents |= POLLPRI;
      }
   }

   free(open_fds);
   free(read_fds);
   free(write_fds);
   free(except_fds);

   return ret;
}

struct iovec {
   u_long    iov_len;
   char FAR *iov_base;
};

inline int lrint(double n) { return (int)n; };

extern void gethostbyname_r(const char *inetName, struct hostent *hent, char *buff,
                            int buffsize, struct hostent **hp, int *rc);
extern void gethostbyaddr_r(char *addr, size_t len, int type, struct hostent *hent, char *buff,
                            size_t buffsize, struct hostent **hp, int *rc);
extern int getservbyname_r(const char *servname, const char *servtype, struct servent *sent,
                           char *buff, size_t buffsize, struct servent **sp);
extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
extern void *dlopen(const char *libPath, int opt);
extern BOOL dlclose(void *lib);
extern void *dlsym(void *libHandle, const char *pname);
extern char *dlerror();
extern pid_t fork();
extern const char *inet_ntop(int af, const void *src, char *dst, size_t size);
extern int sysconf(int what);
extern int fcntl(int fd, int cmd, long arg);
extern int close(int fd);
extern int writev(int sock, const struct iovec iov[], int nvecs);
extern int posix_memalign (void **memptr, size_t alignment, size_t size);
extern char *index(const char *str, int c);
extern char *cuserid(char * s);

#ifndef localtime_r
#define localtime_r( _clock, _result ) \
        ( *(_result) = *localtime( (_clock) ), \
          (_result) )
#endif

#define pipe(a) _pipe(a, 256, O_BINARY)
#define rindex strrchr
#define sleep(s) Sleep(s*1000)

#define strtoll(a, b, c) _strtoi64(a, b, c)
#define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) | (unsigned int)ntohl(((int)(x >> 32))))
#define htonll(x) ntohll(x)
#define random() rand()

#define usleep(x) Sleep(x / 1000)
#define lstat(a, b) stat(a, b)
#define memalign(a, b) _aligned_malloc(b, a)
struct sockaddr_un { unsigned short sun_family; char sun_path[128]; };
#define setpgid(x,y)
#define fsync(a) _commit(a)
#define ssize_t SSIZE_T

#endif // __XrdWin32_h__

<commit_msg>From Bertrand: fix warnings in MSVC2010<commit_after>//         $Id$
//
// You received this file as part of MCA2
// Modular Controller Architecture Version 2
//
//Copyright (C) Forschungszentrum Informatik Karlsruhe
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// this is a -*- C++ -*- file
//----------------------------------------------------------------------
//----------------------------------------------------------------------

#ifndef __XrdWin32_h__
#define __XrdWin32_h__

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <time.h>
#include <direct.h>
#include <sys/types.h>
#include <Winsock2.h>

#ifndef POLLIN
#define POLLIN          0x0001    /* There is data to read */
#define POLLPRI         0x0002    /* There is urgent data to read */
#define POLLOUT         0x0004    /* Writing now will not block */
#define POLLERR         0x0008    /* Error condition */
#define POLLHUP         0x0010    /* Hung up */
#define POLLNVAL        0x0020    /* Invalid request: fd not open */
#define POLLRDNORM      0x0001
#define POLLWRNORM      0x0002
#define POLLRDBAND      0x0000

struct pollfd {
   unsigned int fd;
   short events;
   short revents;
};
#endif

#ifndef EMSGSIZE
#define EMSGSIZE        WSAEMSGSIZE
#endif
#ifndef EAFNOSUPPORT
#define EAFNOSUPPORT    WSAEAFNOSUPPORT
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK     WSAEWOULDBLOCK
#endif
#ifndef ECONNRESET
#define ECONNRESET      WSAECONNRESET
#endif
#ifndef EINPROGRESS
#define EINPROGRESS     WSAEINPROGRESS
#endif
#ifndef ENOBUFS
#define ENOBUFS         WSAENOBUFS
#endif
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
#endif
#ifndef ECONNREFUSED
#define ECONNREFUSED    WSAECONNREFUSED
#endif
#ifndef EBADFD
#define EBADFD          WSAENOTSOCK
#endif
#ifndef EOPNOTSUPP
#define EOPNOTSUPP      WSAEOPNOTSUPP
#endif
#ifndef ENETUNREACH
#define ENETUNREACH     WSAENETUNREACH
#endif
#ifndef EHOSTUNREACH
#define EHOSTUNREACH    WSAEHOSTUNREACH
#endif
#ifndef EHOSTDOWN
#define EHOSTDOWN       WSAEHOSTDOWN
#endif
#ifndef EISCONN
#define EISCONN         WSAEISCONN
#endif
#ifndef ECONNRESET
#define ECONNRESET      WSAECONNRESET
#endif
#ifndef ECONNABORTED
#define ECONNABORTED    WSAECONNABORTED
#endif
#ifndef ESHUTDOWN
#define ESHUTDOWN       WSAESHUTDOWN
#endif
#ifndef ETIMEDOUT
#define ETIMEDOUT       WSAETIMEDOUT
#endif
#ifndef ETXTBSY
#define ETXTBSY         26
#endif

#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
#define WIFEXITED(w)   (((w) & 0xff) == 0)
#define WTERMSIG(w)     ((w) & 0x7f)
#define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))

#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&(S_IFMT)) == (S_IFDIR))
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m)&(S_IFMT)) == (S_IFREG))
#endif
#ifndef S_IXUSR
#define S_IXUSR 00100
#endif
#ifndef S_IRGRP
#define S_IRGRP 00040
#endif
#ifndef S_IXGRP
#define S_IXGRP 00010
#endif
#ifndef S_IROTH
#define S_IROTH 00004
#endif
#ifndef S_IXOTH
#define S_IXOTH 00001
#endif
#ifndef S_IRUSR
#define S_IRUSR S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR S_IWRITE
#endif
#ifndef S_IWGRP
#define S_IWGRP 000020
#endif
#ifndef S_IWOTH
#define S_IWOTH 000002
#endif
#ifndef S_IRWXU
#define S_IRWXU 0000700
#endif
#ifndef S_IRWXG
#define S_IRWXG 0000070
#endif

#ifndef S_ISFIFO
# ifndef S_IFIFO
#  define S_IFIFO 0010000
# endif
# define S_ISFIFO(m)	((m & S_IFMT) == S_IFIFO)
#endif

#ifndef S_IFSOCK
#define S_IFSOCK   0140000
#endif

#define _SC_PAGESIZE 1

#define F_GETFL      1
#define F_SETFL      2
#define F_GETFD      4
#define F_SETFD      8

#define FD_CLOEXEC   1
#define O_NDELAY     2
#define O_NONBLOCK   4

#define X_OK 1
#define W_OK 2
#define R_OK 4

#define RTLD_NOW 0x0001

#ifndef STDIN_FILENO
#define STDIN_FILENO    0
#define STDOUT_FILENO   1
#define STDERR_FILENO   2
#endif

#ifndef fsync
#define fsync(a) _commit(a)
#endif

#ifndef socklen_t
#define socklen_t int
#endif

#ifndef SOCKLEN_t
#define SOCKLEN_t int
#endif

#ifndef snprintf
#define snprintf _snprintf
#endif

#ifndef caddr_t
typedef char* caddr_t;
#endif

#ifndef pid_t
typedef int pid_t;
#endif

#ifndef mode_t
typedef unsigned int mode_t;
#endif

#ifndef uint16_t
typedef unsigned short uint16_t;
#endif

struct timezone {
   int tz_minuteswest; /* minutes west of Greenwich */
   int tz_dsttime;     /* type of dst correction */
};

inline int poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
   unsigned int max_fd = 0;
   unsigned int i;

   fd_set *open_fds, *read_fds, *write_fds, *except_fds;
   struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };

   for (i = 0; i < nfds; ++i) {
      if (fds[i].fd > max_fd) {
         max_fd = fds[i].fd;
      }
   }

   size_t fds_size = (max_fd + 1) * sizeof (fd_set);

   open_fds = (fd_set *) malloc (fds_size);
   read_fds = (fd_set *) malloc (fds_size);
   write_fds = (fd_set *) malloc (fds_size);
   except_fds = (fd_set *) malloc (fds_size);

   if (!open_fds || !read_fds || !write_fds || !except_fds) {
      return -1;
   }

   FD_ZERO(open_fds) ;
   FD_ZERO(read_fds) ;
   FD_ZERO(write_fds) ;
   FD_ZERO(except_fds) ;

   for ( i = 0; i < nfds; ++i) {
      FD_SET (fds[i].fd, open_fds);
      if (fds[i].events & POLLIN)
         FD_SET (fds[i].fd, read_fds);
      if (fds[i].events & POLLOUT)
         FD_SET (fds[i].fd, write_fds);
      if (fds[i].events & POLLPRI)
         FD_SET (fds[i].fd, except_fds);
   }

//  Sleep(1);
   int ret = select(max_fd + 1, read_fds, write_fds, except_fds, timeout < 0 ? NULL : &tv);

   for (i = 0; i < nfds; ++i) {
      if (!FD_ISSET (fds[i].fd, open_fds))
         fds[i].revents = POLLNVAL;
      else if (ret < 0)
         fds[i].revents = POLLERR;
      else {
         fds[i].revents = 0;
         if (FD_ISSET (fds[i].fd, read_fds))
            fds[i].revents |= POLLIN;
         if (FD_ISSET (fds[i].fd, write_fds))
            fds[i].revents |= POLLOUT;
         if (FD_ISSET (fds[i].fd, except_fds))
            fds[i].revents |= POLLPRI;
      }
   }

   free(open_fds);
   free(read_fds);
   free(write_fds);
   free(except_fds);

   return ret;
}

struct iovec {
   u_long    iov_len;
   char FAR *iov_base;
};

inline int lrint(double n) { return (int)n; };

extern void gethostbyname_r(const char *inetName, struct hostent *hent, char *buff,
                            int buffsize, struct hostent **hp, int *rc);
extern void gethostbyaddr_r(char *addr, size_t len, int type, struct hostent *hent, char *buff,
                            size_t buffsize, struct hostent **hp, int *rc);
extern int getservbyname_r(const char *servname, const char *servtype, struct servent *sent,
                           char *buff, size_t buffsize, struct servent **sp);
extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
extern void *dlopen(const char *libPath, int opt);
extern BOOL dlclose(void *lib);
extern void *dlsym(void *libHandle, const char *pname);
extern char *dlerror();
extern pid_t fork();
extern const char *inet_ntop(int af, const void *src, char *dst, size_t size);
extern int sysconf(int what);
extern int fcntl(int fd, int cmd, long arg);
extern int close(int fd);
extern int writev(int sock, const struct iovec iov[], int nvecs);
extern int posix_memalign (void **memptr, size_t alignment, size_t size);
extern char *index(const char *str, int c);
extern char *cuserid(char * s);

#ifndef localtime_r
#define localtime_r( _clock, _result ) \
        ( *(_result) = *localtime( (_clock) ), \
          (_result) )
#endif

#define pipe(a) _pipe(a, 256, O_BINARY)
#define rindex strrchr
#define sleep(s) Sleep(s*1000)

#define strtoll(a, b, c) _strtoi64(a, b, c)
#define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) | (unsigned int)ntohl(((int)(x >> 32))))
#define htonll(x) ntohll(x)
#define random() rand()

#define usleep(x) Sleep(x / 1000)
#define lstat(a, b) stat(a, b)
#define memalign(a, b) _aligned_malloc(b, a)
struct sockaddr_un { unsigned short sun_family; char sun_path[128]; };
#define setpgid(x,y)
#define fsync(a) _commit(a)
#define ssize_t SSIZE_T

#endif // __XrdWin32_h__

<|endoftext|>