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

#ifndef QUEUE_HH_
#define QUEUE_HH_

#include "circular_buffer.hh"
#include "future.hh"
#include <queue>
#include <experimental/optional>

template <typename T>
class queue {
    std::queue<T, circular_buffer<T>> _q;
    size_t _max;
    std::experimental::optional<promise<>> _not_empty;
    std::experimental::optional<promise<>> _not_full;
    std::exception_ptr _ex = nullptr;
private:
    void notify_not_empty();
    void notify_not_full();
public:
    explicit queue(size_t size);

    // Push an item.
    //
    // Returns false if the queue was full and the item was not pushed.
    bool push(T&& a);

    // pops an item.
    T pop();

    // Consumes items from the queue, passing them to @func, until @func
    // returns false or the queue it empty
    //
    // Returns false if func returned false.
    template <typename Func>
    bool consume(Func&& func);

    // Returns true when the queue is empty.
    bool empty() const;

    // Returns true when the queue is full.
    bool full() const;

    // Returns a future<> that becomes available when pop() or consume()
    // can be called.
    future<> not_empty();

    // Returns a future<> that becomes available when push() can be called.
    future<> not_full();

    // Pops element now or when ther is some. Returns a future that becomes
    // available when some element is available.
    future<T> pop_eventually();

    // Pushes the element now or when there is room. Returns a future<> which
    // resolves when data was pushed.
    future<> push_eventually(T&& data);

    size_t size() const { return _q.size(); }

    size_t max_size() const { return _max; }

    // Destroy any items in the queue, and pass the provided exception to any
    // waiting readers or writers.
    void abort(std::exception_ptr ex) {
        while (!_q.empty()) {
            _q.pop();
        }
        _ex = ex;
        if (_not_full) {
            _not_full->set_exception(ex);
            _not_full= std::experimental::nullopt;
        }
        if (_not_empty) {
            _not_empty->set_exception(std::move(ex));
            _not_empty = std::experimental::nullopt;
        }
    }
};

template <typename T>
inline
queue<T>::queue(size_t size)
    : _max(size) {
}

template <typename T>
inline
void queue<T>::notify_not_empty() {
    if (_not_empty) {
        _not_empty->set_value();
        _not_empty = std::experimental::optional<promise<>>();
    }
}

template <typename T>
inline
void queue<T>::notify_not_full() {
    if (_not_full) {
        _not_full->set_value();
        _not_full = std::experimental::optional<promise<>>();
    }
}

template <typename T>
inline
bool queue<T>::push(T&& data) {
    if (_q.size() < _max) {
        _q.push(std::move(data));
        notify_not_empty();
        return true;
    } else {
        return false;
    }
}

template <typename T>
inline
T queue<T>::pop() {
    if (_q.size() == _max) {
        notify_not_full();
    }
    T data = std::move(_q.front());
    _q.pop();
    return data;
}

template <typename T>
inline
future<T> queue<T>::pop_eventually() {
    if (empty()) {
        return not_empty().then([this] {
            if (_ex) {
                return make_exception_future<T>(_ex);
            } else {
                return make_ready_future<T>(pop());
            }
        });
    } else {
        return make_ready_future<T>(pop());
    }
}

template <typename T>
inline
future<> queue<T>::push_eventually(T&& data) {
    if (full()) {
        return not_full().then([this, data = std::move(data)] () mutable {
            _q.push(std::move(data));
            notify_not_empty();
        });
    } else {
        _q.push(std::move(data));
        notify_not_empty();
        return make_ready_future<>();
    }
}

template <typename T>
template <typename Func>
inline
bool queue<T>::consume(Func&& func) {
    if (_q.size() == _max) {
        notify_not_full();
    }
    bool running = true;
    while (!_q.empty() && running) {
        running = func(std::move(_q.front()));
        _q.pop();
    }
    return running;
}

template <typename T>
inline
bool queue<T>::empty() const {
    return _q.empty();
}

template <typename T>
inline
bool queue<T>::full() const {
    return _q.size() == _max;
}

template <typename T>
inline
future<> queue<T>::not_empty() {
    if (!empty()) {
        return make_ready_future<>();
    } else {
        _not_empty = promise<>();
        return _not_empty->get_future();
    }
}

template <typename T>
inline
future<> queue<T>::not_full() {
    if (!full()) {
        return make_ready_future<>();
    } else {
        _not_full = promise<>();
        return _not_full->get_future();
    }
}

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

#ifndef QUEUE_HH_
#define QUEUE_HH_

#include "circular_buffer.hh"
#include "future.hh"
#include <queue>
#include <experimental/optional>

template <typename T>
class queue {
    std::queue<T, circular_buffer<T>> _q;
    size_t _max;
    std::experimental::optional<promise<>> _not_empty;
    std::experimental::optional<promise<>> _not_full;
    std::exception_ptr _ex = nullptr;
private:
    void notify_not_empty();
    void notify_not_full();
public:
    explicit queue(size_t size);

    // Push an item.
    //
    // Returns false if the queue was full and the item was not pushed.
    bool push(T&& a);

    // pops an item.
    T pop();

    // Consumes items from the queue, passing them to @func, until @func
    // returns false or the queue it empty
    //
    // Returns false if func returned false.
    template <typename Func>
    bool consume(Func&& func);

    // Returns true when the queue is empty.
    bool empty() const;

    // Returns true when the queue is full.
    bool full() const;

    // Returns a future<> that becomes available when pop() or consume()
    // can be called.
    future<> not_empty();

    // Returns a future<> that becomes available when push() can be called.
    future<> not_full();

    // Pops element now or when ther is some. Returns a future that becomes
    // available when some element is available.
    future<T> pop_eventually();

    future<> push_eventually(T&& data);

    size_t size() const { return _q.size(); }

    size_t max_size() const { return _max; }

    // Pushes the element now or when there is room. Returns a future<> which
    // resolves when data was pushed.
    // Set the maximum size to a new value. If the queue's max size is reduced,
    // items already in the queue will not be expunged and the queue will be temporarily
    // bigger than its max_size.
    void set_max_size(size_t max) {
        _max = max;
        if (!full()) {
            notify_not_full();
        }
    }

    // Destroy any items in the queue, and pass the provided exception to any
    // waiting readers or writers.
    void abort(std::exception_ptr ex) {
        while (!_q.empty()) {
            _q.pop();
        }
        _ex = ex;
        if (_not_full) {
            _not_full->set_exception(ex);
            _not_full= std::experimental::nullopt;
        }
        if (_not_empty) {
            _not_empty->set_exception(std::move(ex));
            _not_empty = std::experimental::nullopt;
        }
    }
};

template <typename T>
inline
queue<T>::queue(size_t size)
    : _max(size) {
}

template <typename T>
inline
void queue<T>::notify_not_empty() {
    if (_not_empty) {
        _not_empty->set_value();
        _not_empty = std::experimental::optional<promise<>>();
    }
}

template <typename T>
inline
void queue<T>::notify_not_full() {
    if (_not_full) {
        _not_full->set_value();
        _not_full = std::experimental::optional<promise<>>();
    }
}

template <typename T>
inline
bool queue<T>::push(T&& data) {
    if (_q.size() < _max) {
        _q.push(std::move(data));
        notify_not_empty();
        return true;
    } else {
        return false;
    }
}

template <typename T>
inline
T queue<T>::pop() {
    if (_q.size() == _max) {
        notify_not_full();
    }
    T data = std::move(_q.front());
    _q.pop();
    return data;
}

template <typename T>
inline
future<T> queue<T>::pop_eventually() {
    if (empty()) {
        return not_empty().then([this] {
            if (_ex) {
                return make_exception_future<T>(_ex);
            } else {
                return make_ready_future<T>(pop());
            }
        });
    } else {
        return make_ready_future<T>(pop());
    }
}

template <typename T>
inline
future<> queue<T>::push_eventually(T&& data) {
    if (full()) {
        return not_full().then([this, data = std::move(data)] () mutable {
            _q.push(std::move(data));
            notify_not_empty();
        });
    } else {
        _q.push(std::move(data));
        notify_not_empty();
        return make_ready_future<>();
    }
}

template <typename T>
template <typename Func>
inline
bool queue<T>::consume(Func&& func) {
    bool running = true;
    while (!_q.empty() && running) {
        running = func(std::move(_q.front()));
        _q.pop();
    }
    if (!full()) {
        notify_not_full();
    }
    return running;
}

template <typename T>
inline
bool queue<T>::empty() const {
    return _q.empty();
}

template <typename T>
inline
bool queue<T>::full() const {
    return _q.size() >= _max;
}

template <typename T>
inline
future<> queue<T>::not_empty() {
    if (!empty()) {
        return make_ready_future<>();
    } else {
        _not_empty = promise<>();
        return _not_empty->get_future();
    }
}

template <typename T>
inline
future<> queue<T>::not_full() {
    if (!full()) {
        return make_ready_future<>();
    } else {
        _not_full = promise<>();
        return _not_full->get_future();
    }
}

#endif /* QUEUE_HH_ */
<|endoftext|>


<commit_before>/*
 * Copyright 2017 Google LLC
 *
 * 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 "app/src/thread.h"

#include "app/src/mutex.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#define EXPECT_THROW_ERROR_CODE(statement, error_code) \
    EXPECT_THROW({\
        try { \
          GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
        } \
        catch(const std::system_error &exception) {\
            EXPECT_EQ(error_code, exception.code());\
            throw;\
        }\
    }, std::system_error)

namespace {

using ::testing::Eq;

// Simple thread safe wrapper around a value T.
template <typename T>
class ThreadSafe {
 public:
  explicit ThreadSafe(T value) : value_(value) {}

  T get() const {
    firebase::MutexLock lock(const_cast<firebase::Mutex&>(mtx_));
    return value_;
  }

  void set(const T& value) {
    firebase::MutexLock lock(mtx_);
    value_ = value;
  }

 private:
  T value_;
  firebase::Mutex mtx_;
};

TEST(ThreadTest, ThreadExecutesAndJoinWaitsForItToFinish) {
  ThreadSafe<bool> value(false);

  firebase::Thread thread([](ThreadSafe<bool>* value) { value->set(true); },
                          &value);
  thread.Join();

  ASSERT_THAT(value.get(), Eq(true));
}

TEST(ThreadTest, ThreadIsNotJoinableAfterJoin) {
  firebase::Thread thread([] {});
  ASSERT_THAT(thread.Joinable(), Eq(true));

  thread.Join();
  ASSERT_THAT(thread.Joinable(), Eq(false));
}

TEST(ThreadTest, ThreadIsNotJoinableAfterDetach) {
  firebase::Thread thread([] {});
  ASSERT_THAT(thread.Joinable(), Eq(true));

  thread.Detach();
  ASSERT_THAT(thread.Joinable(), Eq(false));
}

TEST(ThreadTest, ThreadShouldNotBeJoinableAfterBeingMoveAssignedOutOf) {
  firebase::Thread source([] {});
  firebase::Thread target;

  ASSERT_THAT(source.Joinable(), Eq(true));

  // cast due to lack of std::move in STLPort
  target = static_cast<firebase::Thread&&>(source);
  ASSERT_THAT(source.Joinable(), Eq(false));
  ASSERT_THAT(target.Joinable(), Eq(true));
  target.Join();
}

TEST(ThreadTest, ThreadShouldNotBeJoinableAfterBeingMoveFrom) {
  firebase::Thread source([] {});

  ASSERT_THAT(source.Joinable(), Eq(true));

  // cast due to lack of std::move in STLPort
  firebase::Thread target(static_cast<firebase::Thread&&>(source));
  ASSERT_THAT(source.Joinable(), Eq(false));
  ASSERT_THAT(target.Joinable(), Eq(true));
  target.Join();
}

TEST(ThreadDeathTest, MovingIntoRunningThreadShouldAbort) {
  ASSERT_DEATH(
      {
        firebase::Thread thread([] {});

        thread = firebase::Thread();
      },
      "");
}

TEST(ThreadDeathTest, JoinEmptyThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread;
        thread.Join();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, JoinThreadMultipleTimesShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Join();
        thread.Join();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, JoinDetachedThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Detach();
        thread.Join();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, DetachJoinedThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Join();
        thread.Detach();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, DetachEmptyThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread;

        thread.Detach();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, DetachThreadMultipleTimesShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Detach();
        thread.Detach();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, WhenJoinableThreadIsDestructedShouldAbort) {
  ASSERT_DEATH({ firebase::Thread thread([] {}); }, "");
}

TEST(ThreadTest, ThreadIsEqualToItself) {
  firebase::Thread::Id thread_id = firebase::Thread::CurrentId();
  ASSERT_THAT(firebase::Thread::IsCurrentThread(thread_id), Eq(true));
}

TEST(ThreadTest, ThreadIsNotEqualToDifferentThread) {
  ThreadSafe<firebase::Thread::Id> value(firebase::Thread::CurrentId());

  firebase::Thread thread(
      [](ThreadSafe<firebase::Thread::Id>* value) {
        value->set(firebase::Thread::CurrentId());
      },
      &value);
  thread.Join();

  ASSERT_THAT(firebase::Thread::IsCurrentThread(value.get()), Eq(false));
}

}  // namespace
<commit_msg>fixed formatting<commit_after>/*
 * Copyright 2017 Google LLC
 *
 * 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 "app/src/thread.h"

#include "app/src/mutex.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#define EXPECT_THROW_ERROR_CODE(statement, error_code)               \
  EXPECT_THROW(                                                      \
      {                                                              \
        try {                                                        \
          GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
        } catch (const std::system_error& exception) {               \
          EXPECT_EQ(error_code, exception.code());                   \
          throw;                                                     \
        }                                                            \
      },                                                             \
      std::system_error)

namespace {

using ::testing::Eq;

// Simple thread safe wrapper around a value T.
template <typename T>
class ThreadSafe {
 public:
  explicit ThreadSafe(T value) : value_(value) {}

  T get() const {
    firebase::MutexLock lock(const_cast<firebase::Mutex&>(mtx_));
    return value_;
  }

  void set(const T& value) {
    firebase::MutexLock lock(mtx_);
    value_ = value;
  }

 private:
  T value_;
  firebase::Mutex mtx_;
};

TEST(ThreadTest, ThreadExecutesAndJoinWaitsForItToFinish) {
  ThreadSafe<bool> value(false);

  firebase::Thread thread([](ThreadSafe<bool>* value) { value->set(true); },
                          &value);
  thread.Join();

  ASSERT_THAT(value.get(), Eq(true));
}

TEST(ThreadTest, ThreadIsNotJoinableAfterJoin) {
  firebase::Thread thread([] {});
  ASSERT_THAT(thread.Joinable(), Eq(true));

  thread.Join();
  ASSERT_THAT(thread.Joinable(), Eq(false));
}

TEST(ThreadTest, ThreadIsNotJoinableAfterDetach) {
  firebase::Thread thread([] {});
  ASSERT_THAT(thread.Joinable(), Eq(true));

  thread.Detach();
  ASSERT_THAT(thread.Joinable(), Eq(false));
}

TEST(ThreadTest, ThreadShouldNotBeJoinableAfterBeingMoveAssignedOutOf) {
  firebase::Thread source([] {});
  firebase::Thread target;

  ASSERT_THAT(source.Joinable(), Eq(true));

  // cast due to lack of std::move in STLPort
  target = static_cast<firebase::Thread&&>(source);
  ASSERT_THAT(source.Joinable(), Eq(false));
  ASSERT_THAT(target.Joinable(), Eq(true));
  target.Join();
}

TEST(ThreadTest, ThreadShouldNotBeJoinableAfterBeingMoveFrom) {
  firebase::Thread source([] {});

  ASSERT_THAT(source.Joinable(), Eq(true));

  // cast due to lack of std::move in STLPort
  firebase::Thread target(static_cast<firebase::Thread&&>(source));
  ASSERT_THAT(source.Joinable(), Eq(false));
  ASSERT_THAT(target.Joinable(), Eq(true));
  target.Join();
}

TEST(ThreadDeathTest, MovingIntoRunningThreadShouldAbort) {
  ASSERT_DEATH(
      {
        firebase::Thread thread([] {});

        thread = firebase::Thread();
      },
      "");
}

TEST(ThreadDeathTest, JoinEmptyThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread;
        thread.Join();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, JoinThreadMultipleTimesShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Join();
        thread.Join();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, JoinDetachedThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Detach();
        thread.Join();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, DetachJoinedThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Join();
        thread.Detach();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, DetachEmptyThreadShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread;

        thread.Detach();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, DetachThreadMultipleTimesShouldAbort) {
  EXPECT_THROW_ERROR_CODE(
      {
        firebase::Thread thread([] {});

        thread.Detach();
        thread.Detach();
      },
      std::errc::invalid_argument);
}

TEST(ThreadDeathTest, WhenJoinableThreadIsDestructedShouldAbort) {
  ASSERT_DEATH({ firebase::Thread thread([] {}); }, "");
}

TEST(ThreadTest, ThreadIsEqualToItself) {
  firebase::Thread::Id thread_id = firebase::Thread::CurrentId();
  ASSERT_THAT(firebase::Thread::IsCurrentThread(thread_id), Eq(true));
}

TEST(ThreadTest, ThreadIsNotEqualToDifferentThread) {
  ThreadSafe<firebase::Thread::Id> value(firebase::Thread::CurrentId());

  firebase::Thread thread(
      [](ThreadSafe<firebase::Thread::Id>* value) {
        value->set(firebase::Thread::CurrentId());
      },
      &value);
  thread.Join();

  ASSERT_THAT(firebase::Thread::IsCurrentThread(value.get()), Eq(false));
}

}  // namespace
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#define LOG_THIS BX_CPU_THIS_PTR

  Bit16u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp16(Bit16u addr)
{
  Bit16u ret16;

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM () || (CPL>BX_CPU_THIS_PTR get_IOPL ()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
      // BX_INFO(("cpu_inp16: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return(0);
      }
    }

  ret16 = BX_INP(addr, 2);
  return( ret16 );
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp16(Bit16u addr, Bit16u value)
{
  /* If CPL <= IOPL, then all IO addresses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
      // BX_INFO(("cpu_outp16: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return;
      }
    }

  BX_OUTP(addr, value, 2);
}

  Bit32u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp32(Bit16u addr)
{
  Bit32u ret32;

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
      // BX_INFO(("cpu_inp32: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return(0);
      }
    }

  ret32 = BX_INP(addr, 4);
  return( ret32 );
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp32(Bit16u addr, Bit32u value)
{
  /* If CPL <= IOPL, then all IO addresses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
      // BX_INFO(("cpu_outp32: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return;
      }
    }

  BX_OUTP(addr, value, 4);
}

  Bit8u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp8(Bit16u addr)
{
  Bit8u ret8;

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
      // BX_INFO(("cpu_inp8: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return(0);
      }
    }

  ret8 = BX_INP(addr, 1);
  return( ret8 );
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp8(Bit16u addr, Bit8u value)
{
  /* If CPL <= IOPL, then all IO addresses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
      // BX_INFO(("cpu_outp8: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return;
      }
    }

  BX_OUTP(addr, value, 1);
}

  bx_bool
BX_CPU_C::allow_io(Bit16u addr, unsigned len)
{
  Bit16u io_base, permission16;
  unsigned bit_index, i;

  if (BX_CPU_THIS_PTR tr.cache.valid==0 || BX_CPU_THIS_PTR tr.cache.type!=9) {
    BX_INFO(("allow_io(): TR doesn't point to a valid 32bit TSS"));
    return(0);
    }

  if (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled < 103) {
    BX_PANIC(("allow_io(): TR.limit < 103"));
    }

  access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102, 2, 0, BX_READ,
                         &io_base);
  if (io_base <= 103) {
BX_INFO(("PE is %u", BX_CPU_THIS_PTR cr0.pe));
BX_INFO(("VM is %u", BX_CPU_THIS_PTR getB_VM ()));
BX_INFO(("CPL is %u", CPL));
BX_INFO(("IOPL is %u", BX_CPU_THIS_PTR get_IOPL ()));
BX_INFO(("addr is %u", addr));
BX_INFO(("len is %u", len));
    BX_PANIC(("allow_io(): TR:io_base <= 103"));
    }

  if ( (Bit16s) (addr/8) > (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled - io_base)) {
    BX_INFO(("allow_io(): IO adr %x outside TSS IO permission map (max port=%x) #GP(0)",
      addr, 8*(BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled - io_base) ));
    return(0);
   }

  access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + io_base + addr/8,
                   2, 0, BX_READ, &permission16);

  bit_index = addr & 0x07;
  permission16 >>= bit_index;
  for (i=0; i<len; i++) {
    if (permission16 & 0x01)
      return(0);
    permission16 >>= 1;
    }

  return(1);
}
<commit_msg>- fix sign comparison whenchecking io address in the tss io bitmap<commit_after>/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#define LOG_THIS BX_CPU_THIS_PTR

  Bit16u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp16(Bit16u addr)
{
  Bit16u ret16;

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM () || (CPL>BX_CPU_THIS_PTR get_IOPL ()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
      // BX_INFO(("cpu_inp16: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return(0);
      }
    }

  ret16 = BX_INP(addr, 2);
  return( ret16 );
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp16(Bit16u addr, Bit16u value)
{
  /* If CPL <= IOPL, then all IO addresses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
      // BX_INFO(("cpu_outp16: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return;
      }
    }

  BX_OUTP(addr, value, 2);
}

  Bit32u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp32(Bit16u addr)
{
  Bit32u ret32;

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
      // BX_INFO(("cpu_inp32: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return(0);
      }
    }

  ret32 = BX_INP(addr, 4);
  return( ret32 );
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp32(Bit16u addr, Bit32u value)
{
  /* If CPL <= IOPL, then all IO addresses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
      // BX_INFO(("cpu_outp32: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return;
      }
    }

  BX_OUTP(addr, value, 4);
}

  Bit8u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp8(Bit16u addr)
{
  Bit8u ret8;

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
      // BX_INFO(("cpu_inp8: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return(0);
      }
    }

  ret8 = BX_INP(addr, 1);
  return( ret8 );
}

  void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp8(Bit16u addr, Bit8u value)
{
  /* If CPL <= IOPL, then all IO addresses are accessible.
   * Otherwise, must check the IO permission map on >286.
   * On the 286, there is no IO permissions map */

  if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
    if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
      // BX_INFO(("cpu_outp8: GP0()!"));
      exception(BX_GP_EXCEPTION, 0, 0);
      return;
      }
    }

  BX_OUTP(addr, value, 1);
}

  bx_bool
BX_CPU_C::allow_io(Bit16u addr, unsigned len)
{
  Bit16u io_base, permission16;
  unsigned bit_index, i;

  if (BX_CPU_THIS_PTR tr.cache.valid==0 || BX_CPU_THIS_PTR tr.cache.type!=9) {
    BX_INFO(("allow_io(): TR doesn't point to a valid 32bit TSS"));
    return(0);
    }

  if (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled < 103) {
    BX_PANIC(("allow_io(): TR.limit < 103"));
    }

  access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102, 2, 0, BX_READ,
                         &io_base);
  if (io_base <= 103) {
BX_INFO(("PE is %u", BX_CPU_THIS_PTR cr0.pe));
BX_INFO(("VM is %u", BX_CPU_THIS_PTR getB_VM ()));
BX_INFO(("CPL is %u", CPL));
BX_INFO(("IOPL is %u", BX_CPU_THIS_PTR get_IOPL ()));
BX_INFO(("addr is %u", addr));
BX_INFO(("len is %u", len));
    BX_PANIC(("allow_io(): TR:io_base (%u) <= 103",io_base));
    return(0);
    }

  if ( (Bit32s) (addr/8) >= (Bit32s) (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled - io_base)) {
    BX_INFO(("allow_io(): IO addr %x (len %d) outside TSS IO permission map (base=%x, limit=%x) #GP(0)",
      addr, len, io_base, BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled));
    return(0);
   }

  access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + io_base + addr/8,
                   2, 0, BX_READ, &permission16);

  bit_index = addr & 0x07;
  permission16 >>= bit_index;
  for (i=0; i<len; i++) {
    if (permission16 & 0x01)
      return(0);
    permission16 >>= 1;
    }

  return(1);
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <sys/time.h>

//const int NX=1024, NY= 1024, N_TIME=1024;
const int NX=512, NY= 512, N_TIME=512;
const int X_MASK = NX-1, Y_MASK = NY-1;

const int NS=1;
const int NT=64;
const int T_MASK = NT-1;
const int NG=NT/NS/2; // 32
const int NTO=NX/NT; // 16
const int NF=NX/NT*NG; // 16*32 = 512

using namespace std;

double dens[NY][NX];
double dens_next[NY][NX];
double dens_std[NY][NX];
double dens_pitch[NY][NX];
/*
double second()
{
  struct timeval tm;
  double t ;

  static int base_sec = 0,base_usec = 0;

  gettimeofday(&tm, NULL);

  if(base_sec == 0 && base_usec == 0)
    {
      base_sec = tm.tv_sec;
      base_usec = tm.tv_usec;
      t = 0.0;
  } else {
    t = (double) (tm.tv_sec-base_sec) +
      ((double) (tm.tv_usec-base_usec))/1.0e6 ;
  }

  return t ;
}*/

static double second(){
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return double(tv.tv_sec) + 1.e-6*double(tv.tv_usec);
}

void init() {
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      int p1=x, p2=y, fac=1, sum=0;
      int pat[4] = {0,1,2,-3};
      while(p1!=0 || p2!=0) {
        sum += fac * pat[(p1&1)*2+(p2&1)];
        fac *= 2;p1>>=1; p2>>=1;
      }
      dens[y][x]=sum;
    }
  }
}

void dump(const char *fn) {
  ofstream ofs(fn);
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      ofs << x << " " << y << " " << dens[y][x] << endl;
    }
    ofs << endl;
  }
}

#define dens_at(y,x) dens[(y)&Y_MASK][(x)&X_MASK]

void proceed(){
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      dens_next[y][x]=0.5*dens[y][x]+
        0.125*((dens_at(y,x-1)+dens_at(y,x+1))
               +(dens_at(y-1,x)+dens_at(y+1,x)));
    }
  }
  swap(dens, dens_next);
}

double pad[NT+2*NS][NT+2*NS];

double yslabs[NTO][NTO][NF][NT][2] = {0};
double xslabs[NTO][NTO][NF][NT][2] = {0};
double sticks[NTO][NTO][NT][4] = {0};
double pads[NTO][NTO][NT][NT] = {0};

#define dens_at_pitch(y,x) pad[(y)][(x)]

void proceed_region
( double yslab[NF][NT][2],
  double xslab[NF][NT][2],
  double stick[NF][4],
  double pad_input[NT][NT],
  double yslab_next[NF][NT][2],
  double xslab_next[NF][NT][2],
  double stick_next[NF][4],
  double pad_next[NT][NT]
) {
    for(int y=0;y<NT;++y) {
      for(int x=0;x<NT;++x) {
        pad[y][x] = pad_input[y][x];
      }
    }

  for(int t=0; t<NF; ++t){
    for (int i=0;i<NT;++i) {
      pad[i][NT] = yslab[t][i][0];
      pad[i][NT+1] = yslab[t][i][1];
      pad[NT][i] = xslab[t][i][0];
      pad[NT+1][i] = xslab[t][i][1];
    }
    pad[NT][NT]=stick[t][0];
    pad[NT][NT+1]=stick[t][1];
    pad[NT+1][NT]=stick[t][2];
    pad[NT+1][NT+1]=stick[t][3];

    for(int y=1;y<=NT;++y) {
      for(int x=1;x<=NT;++x) {
        pad[y-1][x-1] =
          0.5*dens_at_pitch(y,x);
        0.125*((dens_at_pitch(y,x-1)+dens_at_pitch(y,x+1))
               +(dens_at_pitch(y-1,x)+dens_at_pitch(y+1,x)));
      }
    }

    for (int i=0;i<NT;++i) {
      yslab_next[t][i][0] = pad[i][0]  ;
      yslab_next[t][i][1] = pad[i][1]  ;
      xslab_next[t][i][0] = pad[0][i]  ;
      xslab_next[t][i][1] = pad[1][i]  ;
    }
    stick_next[t][0] = pad[0][0];
    stick_next[t][1] = pad[0][1];
    stick_next[t][2] = pad[1][0];
    stick_next[t][3] = pad[1][1];
  }
  for(int y=0;y<NT;++y) {
    for(int x=0;x<NT;++x) {
      pad_next[y][x] = pad[y][x];
    }
  }

}

void compute_pitch() {
  for (int large_t=0; large_t < N_TIME/NF; ++large_t) {
    for (int y5=NTO;y5>=0; --y5) {
      for (int x5=NTO;x5>=0; --x5) {
        int x4=(x5-1) & NTO;
        int y4=(y5-1) & NTO;
        proceed_region(yslabs[y5][x5], xslabs[y5][x5], sticks[y5][x5],pads[y5][x5],
                       yslabs[y4][x5], xslabs[y5][x4], sticks[y4][x4],pads[y5][x5]);
      }
    }
  }
}

int main(){
  cout << "yslabs " << (NTO)*(NTO)*(NF)*(NT)*(2) << endl;
  cout << "xslabs " << (NTO)*(NTO)*(NF)*(NT)*(2) << endl;
  cout << "sticks " << (NTO)*(NTO)*(NT)*(4) << endl;
  cout << "pads   " << (NTO)*(NTO)*(NT+2*NS)*(NT+2*NS) << endl;

  init();
  double wct0 = second();
  for(int t=0; t<N_TIME; ++t){
    proceed();
  }
  double wct1 = second();

  double flops = double(NX*NY)*N_TIME*6.0/(wct1-wct0);
  cerr << flops << " FLOP/s" << endl;

  dump("test.txt");

  init();
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      pads[y/NT][x/NT][y&T_MASK][x&T_MASK] = dens[y][x];
    }
  }

  wct0 = second();
  compute_pitch();
  wct1 = second();

  flops = double(NX*NY)*N_TIME*6.0/(wct1-wct0);
  cerr << flops << " FLOP/s" << endl;
  flops = double(N_TIME/NF)*NTO*NTO*NF*NT*NT*6.0/(wct1-wct0);
  cerr << flops << " FLOP/s" << endl;
  init();
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      dens[y][x] = pads[y/NT][x/NT][y&T_MASK][x&T_MASK];
    }
  }
  dump("test-pitch.txt");

}
<commit_msg>change resolution<commit_after>#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <sys/time.h>

//const int NX=1024, NY= 1024, N_TIME=1024;
const int NX=512, NY= 512, N_TIME=512;
const int X_MASK = NX-1, Y_MASK = NY-1;

const int NS=1;
const int NT=64;
const int T_MASK = NT-1;
const int NG=NT/NS/2; // 32
const int NTO=NX/NT; // 16
const int NF=NX/NT*NG; // 16*32 = 512

using namespace std;

double dens[NY][NX];
double dens_next[NY][NX];
double dens_std[NY][NX];
double dens_pitch[NY][NX];
/*
double second()
{
  struct timeval tm;
  double t ;

  static int base_sec = 0,base_usec = 0;

  gettimeofday(&tm, NULL);

  if(base_sec == 0 && base_usec == 0)
    {
      base_sec = tm.tv_sec;
      base_usec = tm.tv_usec;
      t = 0.0;
  } else {
    t = (double) (tm.tv_sec-base_sec) +
      ((double) (tm.tv_usec-base_usec))/1.0e6 ;
  }

  return t ;
}*/

static double second(){
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return double(tv.tv_sec) + 1.e-6*double(tv.tv_usec);
}

void init() {
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      int p1=x, p2=y, fac=1, sum=0;
      int pat[4] = {0,1,2,-3};
      while(p1!=0 || p2!=0) {
        sum += fac * pat[(p1&1)*2+(p2&1)];
        fac *= 2;p1>>=1; p2>>=1;
      }
      dens[y][x]=sum;
    }
  }
}

void dump(const char *fn) {
  ofstream ofs(fn);
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      ofs << x << " " << y << " " << dens[y][x] << endl;
    }
    ofs << endl;
  }
}

#define dens_at(y,x) dens[(y)&Y_MASK][(x)&X_MASK]

void proceed(){
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      dens_next[y][x]=0.5*dens[y][x]+
        0.125*((dens_at(y,x-1)+dens_at(y,x+1))
               +(dens_at(y-1,x)+dens_at(y+1,x)));
    }
  }
  swap(dens, dens_next);
}

double pad[NT+2*NS][NT+2*NS];

double yslabs[NTO][NTO][NF][NT][2] = {0};
double xslabs[NTO][NTO][NF][NT][2] = {0};
double sticks[NTO][NTO][NT][4] = {0};
double pads[NTO][NTO][NT][NT] = {0};

#define dens_at_pitch(y,x) pad[(y)][(x)]

void proceed_region
( double yslab[NF][NT][2],
  double xslab[NF][NT][2],
  double stick[NF][4],
  double pad_input[NT][NT],
  double yslab_next[NF][NT][2],
  double xslab_next[NF][NT][2],
  double stick_next[NF][4],
  double pad_next[NT][NT]
) {
    for(int y=0;y<NT;++y) {
      for(int x=0;x<NT;++x) {
        pad[y][x] = pad_input[y][x];
      }
    }

  for(int t=0; t<NF; ++t){
    for (int i=0;i<NT;++i) {
      pad[i][NT] = yslab[t][i][0];
      pad[i][NT+1] = yslab[t][i][1];
      pad[NT][i] = xslab[t][i][0];
      pad[NT+1][i] = xslab[t][i][1];
    }
    pad[NT][NT]=stick[t][0];
    pad[NT][NT+1]=stick[t][1];
    pad[NT+1][NT]=stick[t][2];
    pad[NT+1][NT+1]=stick[t][3];

    for(int y=1;y<=NT;++y) {
      for(int x=1;x<=NT;++x) {
        pad[y-1][x-1] =
          0.5*dens_at_pitch(y,x);
        0.125*((dens_at_pitch(y,x-1)+dens_at_pitch(y,x+1))
               +(dens_at_pitch(y-1,x)+dens_at_pitch(y+1,x)));
      }
    }

    for (int i=0;i<NT;++i) {
      yslab_next[t][i][0] = pad[i][0]  ;
      yslab_next[t][i][1] = pad[i][1]  ;
      xslab_next[t][i][0] = pad[0][i]  ;
      xslab_next[t][i][1] = pad[1][i]  ;
    }
    stick_next[t][0] = pad[0][0];
    stick_next[t][1] = pad[0][1];
    stick_next[t][2] = pad[1][0];
    stick_next[t][3] = pad[1][1];
  }
  for(int y=0;y<NT;++y) {
    for(int x=0;x<NT;++x) {
      pad_next[y][x] = pad[y][x];
    }
  }

}

void compute_pitch() {
  for (int large_t=0; large_t < N_TIME/NF; ++large_t) {
    for (int y5=NTO;y5>=0; --y5) {
      for (int x5=NTO;x5>=0; --x5) {
        int x4=(x5-1) & NTO;
        int y4=(y5-1) & NTO;
        proceed_region(yslabs[y5][x5], xslabs[y5][x5], sticks[y5][x5],pads[y5][x5],
                       yslabs[y4][x5], xslabs[y5][x4], sticks[y4][x4],pads[y5][x5]);
      }
    }
  }
}

int main(){
  cout << "yslabs " << (NTO)*(NTO)*(NF)*(NT)*(2) << endl;
  cout << "xslabs " << (NTO)*(NTO)*(NF)*(NT)*(2) << endl;
  cout << "sticks " << (NTO)*(NTO)*(NT)*(4) << endl;
  cout << "pads   " << (NTO)*(NTO)*(NT+2*NS)*(NT+2*NS) << endl;

  init();
  dump("t0.txt");
  double wct0 = second();
  for(int t=0; t<N_TIME; ++t){
    proceed();
  }
  double wct1 = second();

  double flops = double(NX*NY)*N_TIME*6.0/(wct1-wct0);
  cerr << flops << " FLOP/s" << endl;

  dump("test.txt");

  init();
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      pads[y/NT][x/NT][y&T_MASK][x&T_MASK] = dens[y][x];
    }
  }

  wct0 = second();
  compute_pitch();
  wct1 = second();

  flops = double(NX*NY)*N_TIME*6.0/(wct1-wct0);
  cerr << flops << " FLOP/s" << endl;
  flops = double(N_TIME/NF)*NTO*NTO*NF*NT*NT*6.0/(wct1-wct0);
  cerr << flops << " FLOP/s" << endl;
  init();
  for (int y=0;y<NY; ++y) {
    for (int x=0; x<NX; ++x) {
      dens[y][x] = pads[y/NT][x/NT][y&T_MASK][x&T_MASK];
    }
  }
  dump("test-pitch.txt");

}
<|endoftext|>


<commit_before>#include "datalayer.h"
#include <fstream>
#include <algorithm>

using namespace std;

//The Default filename from which to load and save to.
const string DEFAULT_FILENAME = "science.txt";

//Default constructor.
DataLayer::DataLayer()
{
    loadFromFile();
}

//Loads from the Default file.
//The File we expect to load from has a header, which will be ignored
//when reading from it. Then reads in the people by name, gender, birth
//year, death year (Alive for living persons).
void DataLayer::loadFromFile()
{

    Persons p;
    ifstream in;

    in.open(DEFAULT_FILENAME);
    if (in.fail())
    {
        //If it fails to load, the programme will still run
        //with a notification that it couldn't load.
        //The User could still for example load from a certain directory
        //or add people manually.
    }
    else
    {
    in.seekg(100);

    while(in >> p)
    {
        people.push_back(p);
    }
    in.close();
    }
 }

//Very similar to loadFromFile().
//The input string is the directory from which the file should be loaded.
//If it cannot open the selected file, will return false.
//Otherwise, it will read in the people the same way loadFromFile() does.
//If you have a list, you may want to check whether it has the header.
bool DataLayer::loadFromOtherFile(string input)
{

    Persons p;
    ifstream in;

    in.open(input);

    if (in.fail())
    {
        in.close();
        return false;
    }
    else
    {
        in.seekg(100);

        while(in >> p)
        {
            people.push_back(p);
        }
        in.close();

        saveToFile();

        return true;
    }
 }

//The Default saving function.
//Writes a header, and then the people by
//name, gender, birthyear, deathyear (alive for living persons).
void DataLayer::saveToFile()
{
    ofstream out;
    out.open(DEFAULT_FILENAME);

    out.width(26);
    out << left << "Name";
    out <<  "\tGender\tBorn\tDied" << endl;
    out << "_____________________________________________________" << endl;

    out.seekp(100);
    for (size_t i = 0; i < people.size(); i++)
    {
        out.width(26);
        out << left << people[i].getName() << ";\t" << people[i].getGender() << "\t" << people[i].getBirthYear() << "\t";
        if(people[i].getAlive())
        {
            out << "Alive\n";
        }
        else
        {
            out << people[i].getDeathYear() << endl;
        }
    }

    out.close();
}

//Similar to the saveToFile() function.
//The difference lies in the input string, which gives the
//directory in which to save.
//returns true, if successful, and false, if opening the file fails.
bool DataLayer::saveToOtherFile(string input)
{
    ofstream out;
    out.open(input);

    if (out.fail())
    {
        return false;
    }
    else
    {
        out.width(26);
        out << left << "Name";
        out <<  "\tGender\tBorn\tDied" << endl;
        out << "_____________________________________________________" << endl;

        out.seekp(100);
        for (size_t i = 0; i < people.size(); i++)
        {
            out.width(26);
            out << left << people[i].getName() << ";\t" << people[i].getGender() << "\t" << people[i].getBirthYear() << "\t";
            if(people[i].getAlive())
            {
                out << "Alive\n";
            }
            else
            {
                out << people[i].getDeathYear() << endl;
            }
        }

        out.close();
        return true;
    }
}

//Returns a vector containing the people.
vector<Persons> DataLayer::getVector()
{
    return people;
}

//Sets the vector to the given value.
void DataLayer::setVector(vector <Persons> p)
{
    people = p;
}

//Adds the given person to the vector.
//Note the autosave.
void DataLayer::addPerson(const Persons& p)
{
    people.push_back(p);
    saveToFile();
}

//Deletes the person in place n in the vector.
//Note the autosave.
void DataLayer::deletePerson(int n)
{
    people.erase(people.begin() + n);
    saveToFile();
}
<commit_msg>les ekki lengur inn default constructor personur<commit_after>#include "datalayer.h"
#include <fstream>
#include <algorithm>

using namespace std;

//The Default filename from which to load and save to.
const string DEFAULT_FILENAME = "science.txt";

//Default constructor.
DataLayer::DataLayer()
{
    loadFromFile();
}

//Loads from the Default file.
//The File we expect to load from has a header, which will be ignored
//when reading from it. Then reads in the people by name, gender, birth
//year, death year (Alive for living persons).
void DataLayer::loadFromFile()
{

    Persons p;
    ifstream in;

    in.open(DEFAULT_FILENAME);
    if (in.fail())
    {
        //If it fails to load, the programme will still run
        //with a notification that it couldn't load.
        //The User could still for example load from a certain directory
        //or add people manually.
    }
    else
    {
    in.seekg(100);

    while(in >> p)
    {
        people.push_back(p);
    }
    in.close();
    }
 }

//Very similar to loadFromFile().
//The input string is the directory from which the file should be loaded.
//If it cannot open the selected file, will return false.
//Otherwise, it will read in the people the same way loadFromFile() does.
//If you have a list, you may want to check whether it has the header.
bool DataLayer::loadFromOtherFile(string input)
{

    Persons p;
    ifstream in;

    in.open(input);

    if (in.fail())
    {
        in.close();
        return false;
    }
    else
    {
        in.seekg(100);

        while(in >> p)
        {
            Persons compare;
            if (!(p == compare))
            {
                people.push_back(p);
            }
        }
        in.close();

        saveToFile();

        return true;
    }
 }

//The Default saving function.
//Writes a header, and then the people by
//name, gender, birthyear, deathyear (alive for living persons).
void DataLayer::saveToFile()
{
    ofstream out;
    out.open(DEFAULT_FILENAME);

    out.width(26);
    out << left << "Name";
    out <<  "\tGender\tBorn\tDied" << endl;
    out << "_____________________________________________________" << endl;

    out.seekp(100);
    for (size_t i = 0; i < people.size(); i++)
    {
        out.width(26);
        out << left << people[i].getName() << ";\t" << people[i].getGender() << "\t" << people[i].getBirthYear() << "\t";
        if(people[i].getAlive())
        {
            out << "Alive\n";
        }
        else
        {
            out << people[i].getDeathYear() << endl;
        }
    }

    out.close();
}

//Similar to the saveToFile() function.
//The difference lies in the input string, which gives the
//directory in which to save.
//returns true, if successful, and false, if opening the file fails.
bool DataLayer::saveToOtherFile(string input)
{
    ofstream out;
    out.open(input);

    if (out.fail())
    {
        return false;
    }
    else
    {
        out.width(26);
        out << left << "Name";
        out <<  "\tGender\tBorn\tDied" << endl;
        out << "_____________________________________________________" << endl;

        out.seekp(100);
        for (size_t i = 0; i < people.size(); i++)
        {
            out.width(26);
            out << left << people[i].getName() << ";\t" << people[i].getGender() << "\t" << people[i].getBirthYear() << "\t";
            if(people[i].getAlive())
            {
                out << "Alive\n";
            }
            else
            {
                out << people[i].getDeathYear() << endl;
            }
        }

        out.close();
        return true;
    }
}

//Returns a vector containing the people.
vector<Persons> DataLayer::getVector()
{
    return people;
}

//Sets the vector to the given value.
void DataLayer::setVector(vector <Persons> p)
{
    people = p;
}

//Adds the given person to the vector.
//Note the autosave.
void DataLayer::addPerson(const Persons& p)
{
    people.push_back(p);
    saveToFile();
}

//Deletes the person in place n in the vector.
//Note the autosave.
void DataLayer::deletePerson(int n)
{
    people.erase(people.begin() + n);
    saveToFile();
}
<|endoftext|>


<commit_before>/**
 * Madhav Datt - 14CS30015
 *
 * Software Engineering Lab - Assignment 3
 * Contains implementation of the Date Computations Functions
 *
 */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdint>
#include <regex>
#include <exception>

#include "date_comp.h"
#include "date.h"

/**
 * Check validity of (d, m, y) as a triplet
 */
bool is_valid_Date (uint32_t date, uint32_t month, uint32_t year)
{
    // Check validity of passed d and m values
    if (is_valid_Arg (date, month) == false)
        return false;

    // Check if date in month
    if (date > month_length (month, year))
        return false;

    return true;
}

/**
 * Check if d or m take invalid values
 */
bool is_valid_Arg (uint32_t date, uint32_t month)
{
    // date or month are out of bounds/take invalid values
    if (date > 31 || date < 1 || month > 12 || month < 1)
        return false;

    return true;
}

 /**
  * Check if y is a leap year
  */
bool is_leap_Year (uint32_t year)
{
    bool flag = false;

    // Leap year - divisible by 4 & if divisible by 100, then also by 400
    if (year % 100 == 0 && year % 400 == 0)
        flag = true;
    else if (year % 100 != 0 && year % 4 == 0)
        flag = true;

    return flag;
}

/**
 * Give length of month for given year
 * Consider leap years and February
 */
uint32_t month_length (uint32_t month, uint32_t year)
{
    // month_days[i] = number of days in ith month
    static const uint32_t month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    uint32_t month_length = month_days[month];

    // Leap year and month is February then length = 29
    if (is_leap_Year (year) && month == 2)
        month_length = 29;

    return month_length;
}

/**
 * Give three letter name of month
 */
const char* month_name (uint32_t month)
{
    // month_days[i] = three letter name of ith month
    static const char month_name[][4] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    return month_name[month];
}

/**
 * Give full name of month - "January" etc.
 */
const char* month_name_full (uint32_t month)
{
    // month_days[i] = fulll name of ith month
    static const char month_name[][10] = {"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    return month_name[month];
}

/**
 * Give number of weeks in year y
 * A week starts on Monday and ends on Sunday. Weeks are numbered in a year from 1 to 52/53.
 * Week 1 (W01) of a year starts contains the first Thursday of the year.
 */
int number_of_weeks (uint32_t year)
{
    // Last day of year (falls in last week)
    Date year_end (static_cast<Day> (31), static_cast<Month> (12), year);

    // Find first Thursday of year
    Date year_start (static_cast<Day> (1), static_cast<Month> (1), year);
    while ((WeekDay)year_start != 4)
        ++year_start;

    // Find start of Week 1 of year
    year_start = year_start + (-3);

    // Number of days between first week and end of year
    int num_days = year_end - year_start;

    // Return week number in which end of year falls
    return static_cast<int> (num_days / 7) + 1;
}

/**
 * Date formatter function
 * Accept date in specified format
 *
 * dateFormat:
 * 0: No date. This is valid for output only.
 * "d": single digit date in one digit, double digit date in two digits (7, 23)
 * "dd": all dates in two digits with single digit dates with leading 0 (07, 23)
 */
void formatter_date (const char* dateString, char* dateFormat) throw (invalid_argument)
{
    // "d": single digit date in one digit, double digit date in two digits
    if (strcmp (dateString, "d") == 0)
        dateFormat = new char[2];

    // "dd": all dates in two digits with single digit dates with leading 0
    else if (strcmp (dateString, "dd") == 0)
        dateFormat = new char[3];

    // 0: No date
    else if (strcmp (dateString, "0") == 0)
        dateFormat = new char[2];

    // Incorrect format entered
    else
        throw invalid_argument (create_message (__PRETTY_FUNCTION__, __LINE__, "Invalid Argument"));

    strcpy (dateFormat, dateString);
}

/**
 * Month formatter function
 * Accept month in specified format
 *
 * monthFormat:
 * 0: each month in its full name (February, November). This is valid for output only.
 * "m": single digit month in one digit, double digit month in two digits (2, 11)
 * "mm": all months in two digits with single digit months with leading 0 (02, 11)
 * "mmm": each month with first three letters of its name (Feb, Nov). This is valid for output only.
 */
void formatter_month (const char* dateString, char* monthFormat) throw (invalid_argument)
{
    // "m": single digit month in one digit, double digit month in two digits
    if (strcmp (dateString, "m") == 0)
        monthFormat = new char[2];

    // "mm": all months in two digits with single digit months with leading 0
    else if (strcmp (dateString, "mm") == 0)
        monthFormat = new char[3];

    // "mmm": each month with first three letters of its name
    else if (strcmp (dateString, "mmm") == 0)
        monthFormat = new char[4];

    // 0: each month in its full name
    else if (strcmp (dateString, "0") == 0)
        monthFormat = new char[2];

    // Incorrect format entered
    else
        throw invalid_argument (create_message (__PRETTY_FUNCTION__, __LINE__, "Invalid Argument"));

    strcpy (monthFormat, dateString);
}

/**
 * Year formatter function
 * Accept year in specified format
 *
 * yearFormat:
 * 0: No year. This is valid for output only.
 * "yy": year in last two digits (1961 as 61, 2016 as 16)
 * "yyyy": year in four digits (1961 as 1961, 2016 as 2016)
 */
void formatter_year (const char* dateString, char* yearFormat) throw (invalid_argument)
{
    // "yy": year in last two digits
    if (strcmp (dateString, "yy") == 0)
        yearFormat = new char[3];

    // "yyyy": year in four digits
    else if (strcmp (dateString, "yyyy") == 0)
        yearFormat = new char[5];

    // 0: No year
    else if (strcmp (dateString, "0") == 0)
        yearFormat = new char[2];

    // Incorrect format entered
    else
        throw invalid_argument (create_message (__PRETTY_FUNCTION__, __LINE__, "Invalid Argument"));

    strcpy (yearFormat, dateString);
}

/**
 * Check if passed dateString matches format value for field date
 */
bool check_dateFormat (string dateString, const char* format, bool is_input)
{
    bool flag = false;

    // "d": single digit date in one digit, double digit date in two digits
    if (strcmp (format, "d") == 0)
        if (regex_match (dateString, regex ("[1-3]?[0-9]")) == true)
            flag = true;

    // "dd": all dates in two digits with single digit dates with leading 0
    else if (strcmp (format, "dd") == 0)
        if (regex_match (dateString, regex ("0[1-9]|[1-3][0-9]")) == true)
            flag = true;

    // 0: No date
    else if (strcmp (format, "0") == 0 && is_input == false)
        if (dateString == "")
            flag = true;

    return flag;
}

/**
 * Check if passed dateString matches format value for field month
 */
bool check_monthFormat (string dateString, const char* format, bool is_input)
{
    bool flag = false;

    // "m": single digit month in one digit, double digit month in two digits
    if (strcmp (format, "m") == 0)
        if (regex_match (dateString, regex ("1?[0-9]")) == true)
            flag = true;

    // "mm": all months in two digits with single digit months with leading 0
    else if (strcmp (format, "mm") == 0)
        if (regex_match (dateString, regex ("0[1-9]|1[0-2]")) == true)
            flag = true;

    // "mmm": each month with first three letters of its name
    // 0: each month in its full name
    else if ((strcmp (format, "mmm") == 0 || strcmp (format, "0") == 0) && is_input == false)
    {
        for (int i = 1; i < 12; i++)
        {
            // Check match for names against each month for format
            if (strcmp (dateString.c_str (), month_name (i)) == 0 || strcmp (dateString.c_str (), month_name_full (i)) == 0)
            {
                flag = true;
                break;
            }
        }
    }

    return flag;
}

/**
 * Check if passed dateString matches format value for field year
 */
bool check_yearFormat (string dateString, const char* format, bool is_input)
{
    bool flag = false;

    // "yy": year in last two digits
    if (strcmp (format, "yy") == 0)
        if (regex_match (dateString, regex ("[0-9][0-9]")) == true)
            flag = true;

    // "yyyy": year in four digits
    else if (strcmp (format, "yyyy") == 0)
        if (regex_match (dateString, regex ("[1-2][09][0-9][0-9]")) == true)
            flag = true;

    // 0: No year
    else if (strcmp (format, "0") == 0 && is_input == false)
        if (dateString == "")
            flag = true;

    return flag;
}

/**
 * Generate error messages for exceptions thrown
 * Error message includes type of exception, throwing function and line
 */
const string create_message (const char* function, uint32_t line, string error_type)
{
    string message;
    strcpy (message, error_type);
    strcat (message, "at ");
    strcat (message, to_string (line));
    strcat (message, ": ");
    strcat (message, function);
    return message;
}
<commit_msg>update error message generator for exceptions thrown<commit_after>/**
 * Madhav Datt - 14CS30015
 *
 * Software Engineering Lab - Assignment 3
 * Contains implementation of the Date Computations Functions
 *
 */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdint>
#include <regex>
#include <exception>

#include "date_comp.h"
#include "date.h"

/**
 * Check validity of (d, m, y) as a triplet
 */
bool is_valid_Date (uint32_t date, uint32_t month, uint32_t year)
{
    // Check validity of passed d and m values
    if (is_valid_Arg (date, month) == false)
        return false;

    // Check if date in month
    if (date > month_length (month, year))
        return false;

    return true;
}

/**
 * Check if d or m take invalid values
 */
bool is_valid_Arg (uint32_t date, uint32_t month)
{
    // date or month are out of bounds/take invalid values
    if (date > 31 || date < 1 || month > 12 || month < 1)
        return false;

    return true;
}

 /**
  * Check if y is a leap year
  */
bool is_leap_Year (uint32_t year)
{
    bool flag = false;

    // Leap year - divisible by 4 & if divisible by 100, then also by 400
    if (year % 100 == 0 && year % 400 == 0)
        flag = true;
    else if (year % 100 != 0 && year % 4 == 0)
        flag = true;

    return flag;
}

/**
 * Give length of month for given year
 * Consider leap years and February
 */
uint32_t month_length (uint32_t month, uint32_t year)
{
    // month_days[i] = number of days in ith month
    static const uint32_t month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    uint32_t month_length = month_days[month];

    // Leap year and month is February then length = 29
    if (is_leap_Year (year) && month == 2)
        month_length = 29;

    return month_length;
}

/**
 * Give three letter name of month
 */
const char* month_name (uint32_t month)
{
    // month_days[i] = three letter name of ith month
    static const char month_name[][4] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    return month_name[month];
}

/**
 * Give full name of month - "January" etc.
 */
const char* month_name_full (uint32_t month)
{
    // month_days[i] = fulll name of ith month
    static const char month_name[][10] = {"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    return month_name[month];
}

/**
 * Give number of weeks in year y
 * A week starts on Monday and ends on Sunday. Weeks are numbered in a year from 1 to 52/53.
 * Week 1 (W01) of a year starts contains the first Thursday of the year.
 */
int number_of_weeks (uint32_t year)
{
    // Last day of year (falls in last week)
    Date year_end (static_cast<Day> (31), static_cast<Month> (12), year);

    // Find first Thursday of year
    Date year_start (static_cast<Day> (1), static_cast<Month> (1), year);
    while ((WeekDay)year_start != 4)
        ++year_start;

    // Find start of Week 1 of year
    year_start = year_start + (-3);

    // Number of days between first week and end of year
    int num_days = year_end - year_start;

    // Return week number in which end of year falls
    return static_cast<int> (num_days / 7) + 1;
}

/**
 * Date formatter function
 * Accept date in specified format
 *
 * dateFormat:
 * 0: No date. This is valid for output only.
 * "d": single digit date in one digit, double digit date in two digits (7, 23)
 * "dd": all dates in two digits with single digit dates with leading 0 (07, 23)
 */
void formatter_date (const char* dateString, char* dateFormat) throw (invalid_argument)
{
    // "d": single digit date in one digit, double digit date in two digits
    if (strcmp (dateString, "d") == 0)
        dateFormat = new char[2];

    // "dd": all dates in two digits with single digit dates with leading 0
    else if (strcmp (dateString, "dd") == 0)
        dateFormat = new char[3];

    // 0: No date
    else if (strcmp (dateString, "0") == 0)
        dateFormat = new char[2];

    // Incorrect format entered
    else
        throw invalid_argument (create_message (__PRETTY_FUNCTION__, __LINE__, "Invalid Argument"));

    strcpy (dateFormat, dateString);
}

/**
 * Month formatter function
 * Accept month in specified format
 *
 * monthFormat:
 * 0: each month in its full name (February, November). This is valid for output only.
 * "m": single digit month in one digit, double digit month in two digits (2, 11)
 * "mm": all months in two digits with single digit months with leading 0 (02, 11)
 * "mmm": each month with first three letters of its name (Feb, Nov). This is valid for output only.
 */
void formatter_month (const char* dateString, char* monthFormat) throw (invalid_argument)
{
    // "m": single digit month in one digit, double digit month in two digits
    if (strcmp (dateString, "m") == 0)
        monthFormat = new char[2];

    // "mm": all months in two digits with single digit months with leading 0
    else if (strcmp (dateString, "mm") == 0)
        monthFormat = new char[3];

    // "mmm": each month with first three letters of its name
    else if (strcmp (dateString, "mmm") == 0)
        monthFormat = new char[4];

    // 0: each month in its full name
    else if (strcmp (dateString, "0") == 0)
        monthFormat = new char[2];

    // Incorrect format entered
    else
        throw invalid_argument (create_message (__PRETTY_FUNCTION__, __LINE__, "Invalid Argument"));

    strcpy (monthFormat, dateString);
}

/**
 * Year formatter function
 * Accept year in specified format
 *
 * yearFormat:
 * 0: No year. This is valid for output only.
 * "yy": year in last two digits (1961 as 61, 2016 as 16)
 * "yyyy": year in four digits (1961 as 1961, 2016 as 2016)
 */
void formatter_year (const char* dateString, char* yearFormat) throw (invalid_argument)
{
    // "yy": year in last two digits
    if (strcmp (dateString, "yy") == 0)
        yearFormat = new char[3];

    // "yyyy": year in four digits
    else if (strcmp (dateString, "yyyy") == 0)
        yearFormat = new char[5];

    // 0: No year
    else if (strcmp (dateString, "0") == 0)
        yearFormat = new char[2];

    // Incorrect format entered
    else
        throw invalid_argument (create_message (__PRETTY_FUNCTION__, __LINE__, "Invalid Argument"));

    strcpy (yearFormat, dateString);
}

/**
 * Check if passed dateString matches format value for field date
 */
bool check_dateFormat (string dateString, const char* format, bool is_input)
{
    bool flag = false;

    // "d": single digit date in one digit, double digit date in two digits
    if (strcmp (format, "d") == 0)
        if (regex_match (dateString, regex ("[1-3]?[0-9]")) == true)
            flag = true;

    // "dd": all dates in two digits with single digit dates with leading 0
    else if (strcmp (format, "dd") == 0)
        if (regex_match (dateString, regex ("0[1-9]|[1-3][0-9]")) == true)
            flag = true;

    // 0: No date
    else if (strcmp (format, "0") == 0 && is_input == false)
        if (dateString == "")
            flag = true;

    return flag;
}

/**
 * Check if passed dateString matches format value for field month
 */
bool check_monthFormat (string dateString, const char* format, bool is_input)
{
    bool flag = false;

    // "m": single digit month in one digit, double digit month in two digits
    if (strcmp (format, "m") == 0)
        if (regex_match (dateString, regex ("1?[0-9]")) == true)
            flag = true;

    // "mm": all months in two digits with single digit months with leading 0
    else if (strcmp (format, "mm") == 0)
        if (regex_match (dateString, regex ("0[1-9]|1[0-2]")) == true)
            flag = true;

    // "mmm": each month with first three letters of its name
    // 0: each month in its full name
    else if ((strcmp (format, "mmm") == 0 || strcmp (format, "0") == 0) && is_input == false)
    {
        for (int i = 1; i < 12; i++)
        {
            // Check match for names against each month for format
            if (strcmp (dateString.c_str (), month_name (i)) == 0 || strcmp (dateString.c_str (), month_name_full (i)) == 0)
            {
                flag = true;
                break;
            }
        }
    }

    return flag;
}

/**
 * Check if passed dateString matches format value for field year
 */
bool check_yearFormat (string dateString, const char* format, bool is_input)
{
    bool flag = false;

    // "yy": year in last two digits
    if (strcmp (format, "yy") == 0)
        if (regex_match (dateString, regex ("[0-9][0-9]")) == true)
            flag = true;

    // "yyyy": year in four digits
    else if (strcmp (format, "yyyy") == 0)
        if (regex_match (dateString, regex ("[1-2][09][0-9][0-9]")) == true)
            flag = true;

    // 0: No year
    else if (strcmp (format, "0") == 0 && is_input == false)
        if (dateString == "")
            flag = true;

    return flag;
}

/**
 * Generate error messages for exceptions thrown
 * Error message includes type of exception, throwing function and line
 */
const string create_message (const char* function, uint32_t line, string error_type)
{
    string message = error_type + " at " + to_string (line) + ": " + function;
    return message;
}
<|endoftext|>


<commit_before>/*
 * Treecode_.cpp
 *
 *  Created on: Oct 5, 2015
 *      Author: lurker
 */

#include "treecode.h"

#include <mexplus.h>
#include "utils.h"

using namespace std;
using namespace mexplus;

template class mexplus::Session<treecode>;

namespace {

MEX_DEFINE(new)(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){
	InputArguments input(nrhs, prhs, 4);
	OutputArguments output(nlhs, plhs, 1);

	auto px = mxGetPr(prhs[0]);
	auto py = mxGetPr(prhs[1]);
	auto pl = mxGetPr(prhs[2]);
	auto pv = mxGetPr(prhs[3]);

	output.set(0, Session<treecode>::create(new treecode(
			*px, *py, * pl , *pv
			)));
}

MEX_DEFINE(delete) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
	InputArguments input(nrhs, prhs, 1);
	OutputArguments output(nlhs, plhs, 0);
	auto root = Session<treecode>::get(input.get(0));

	Session<treecode>::destroy(input.get(0));
}

MEX_DEFINE(setAttribute) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])  {
	InputArguments input(nrhs, prhs, 2);
	OutputArguments output(nlhs, plhs, 0);

	auto attributes = mxGetPr(prhs[1]);

	auto root = Session<treecode>::get(input.get(0));
	for (auto it : root->root->points) {
		it->attribute = *attributes;
		attributes++;
	}

}

MEX_DEFINE(split) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
	InputArguments input(nrhs, prhs, 1);
	OutputArguments output(nlhs, plhs, 0);

	auto root = Session<treecode>::get(input.get(0));
	root->root->populate();
}

MEX_DEFINE(buildmatrix) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
	InputArguments input(nrhs, prhs, 2);
	OutputArguments output(nlhs, plhs, 1);

	auto root = Session<treecode>::get(input.get(0));
	auto num = root->size * root->size;
	auto theta_ptr = mxGetPr(prhs[1]);
	if (num == 0) {
		std::cout << "empty cell, stopped" << std::endl;
		return;
	}
	plhs[0] = mxCreateNumericMatrix(num, num,mxDOUBLE_CLASS, mxREAL);
	auto Radptr  = mxGetPr(plhs[0]);

	omp_set_num_threads(omp_get_num_procs());

	int i;

#pragma omp parallel for shared(theta_ptr, root, Radptr, num) private(i)
	for (i = 0; i < num; i++) {
		traversal(root, *theta_ptr, root->root->points[i], root->root, num, Radptr);
	}
}

MEX_DEFINE(buildop)(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
// not implemented, since the source class only permits int32_t as size.
}

}

MEX_DISPATCH
<commit_msg>use 2048 threads<commit_after>/*
 * Treecode_.cpp
 *
 *  Created on: Oct 5, 2015
 *      Author: lurker
 */

#include "treecode.h"

#include <mexplus.h>
#include "utils.h"

using namespace std;
using namespace mexplus;

template class mexplus::Session<treecode>;

namespace {

MEX_DEFINE(new)(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){
	InputArguments input(nrhs, prhs, 4);
	OutputArguments output(nlhs, plhs, 1);

	auto px = mxGetPr(prhs[0]);
	auto py = mxGetPr(prhs[1]);
	auto pl = mxGetPr(prhs[2]);
	auto pv = mxGetPr(prhs[3]);

	output.set(0, Session<treecode>::create(new treecode(
			*px, *py, * pl , *pv
			)));
}

MEX_DEFINE(delete) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
	InputArguments input(nrhs, prhs, 1);
	OutputArguments output(nlhs, plhs, 0);
	auto root = Session<treecode>::get(input.get(0));

	Session<treecode>::destroy(input.get(0));
}

MEX_DEFINE(setAttribute) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])  {
	InputArguments input(nrhs, prhs, 2);
	OutputArguments output(nlhs, plhs, 0);

	auto attributes = mxGetPr(prhs[1]);

	auto root = Session<treecode>::get(input.get(0));
	for (auto it : root->root->points) {
		it->attribute = *attributes;
		attributes++;
	}

}

MEX_DEFINE(split) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
	InputArguments input(nrhs, prhs, 1);
	OutputArguments output(nlhs, plhs, 0);

	auto root = Session<treecode>::get(input.get(0));
	root->root->populate();
}

MEX_DEFINE(buildmatrix) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
	InputArguments input(nrhs, prhs, 2);
	OutputArguments output(nlhs, plhs, 1);

	auto root = Session<treecode>::get(input.get(0));
	auto num = root->size * root->size;
	auto theta_ptr = mxGetPr(prhs[1]);
	if (num == 0) {
		std::cout << "empty cell, stopped" << std::endl;
		return;
	}
	plhs[0] = mxCreateNumericMatrix(num, num,mxDOUBLE_CLASS, mxREAL);
	auto Radptr  = mxGetPr(plhs[0]);

//	omp_set_num_threads(omp_get_num_procs());
	omp_set_num_threads(2048);

	int i;

#pragma omp parallel for shared(theta_ptr, root, Radptr, num) private(i)
	for (i = 0; i < num; i++) {
		traversal(root, *theta_ptr, root->root->points[i], root->root, num, Radptr);
	}
}

MEX_DEFINE(buildop)(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
// not implemented, since the source class only permits int32_t as size.
}

}

MEX_DISPATCH
<|endoftext|>


<commit_before><commit_msg>add a warning to Time class that it is broken API<commit_after><|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <gp_Ax1.hxx>
#endif

#include "FeatureRevolution.h"

using namespace Part;

App::PropertyFloatConstraint::Constraints Revolution::angleRangeU = {-360.0f,360.0f,1.0f};

PROPERTY_SOURCE(Part::Revolution, Part::Feature)

Revolution::Revolution()
{
    ADD_PROPERTY(Source,(0));
    ADD_PROPERTY(Base,(Base::Vector3f(0.0f,0.0f,0.0f)));
    ADD_PROPERTY(Axis,(Base::Vector3f(0.0f,0.0f,1.0f)));
    ADD_PROPERTY(Angle,(360.0f));
    Angle.setConstraints(&angleRangeU);
}

short Revolution::mustExecute() const
{
    if (Base.isTouched() ||
        Axis.isTouched() ||
        Source.isTouched())
        return 1;
    return 0;
}

App::DocumentObjectExecReturn *Revolution::execute(void)
{
    App::DocumentObject* link = Source.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Source.getValue());

    Base::Vector3f b = Base.getValue();
    Base::Vector3f v = Axis.getValue();
    gp_Pnt pnt(b.x,b.y,b.z);
    gp_Dir dir(v.x,v.y,v.z);

    try {
        // Now, let's get the TopoDS_Shape
        TopoDS_Shape revolve = base->Shape.getShape().revolve(gp_Ax1(pnt, dir),
            Angle.getValue()/180.0f*Standard_PI);
        if (revolve.IsNull())
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        this->Shape.setValue(revolve);
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
}
<commit_msg>+ fix but that Angle has no effect after creation of revolve feature<commit_after>/***************************************************************************
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <gp_Ax1.hxx>
#endif

#include "FeatureRevolution.h"

using namespace Part;

App::PropertyFloatConstraint::Constraints Revolution::angleRangeU = {-360.0f,360.0f,1.0f};

PROPERTY_SOURCE(Part::Revolution, Part::Feature)

Revolution::Revolution()
{
    ADD_PROPERTY(Source,(0));
    ADD_PROPERTY(Base,(Base::Vector3f(0.0f,0.0f,0.0f)));
    ADD_PROPERTY(Axis,(Base::Vector3f(0.0f,0.0f,1.0f)));
    ADD_PROPERTY(Angle,(360.0f));
    Angle.setConstraints(&angleRangeU);
}

short Revolution::mustExecute() const
{
    if (Base.isTouched() ||
        Axis.isTouched() ||
        Angle.isTouched() ||
        Source.isTouched())
        return 1;
    return 0;
}

App::DocumentObjectExecReturn *Revolution::execute(void)
{
    App::DocumentObject* link = Source.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Source.getValue());

    Base::Vector3f b = Base.getValue();
    Base::Vector3f v = Axis.getValue();
    gp_Pnt pnt(b.x,b.y,b.z);
    gp_Dir dir(v.x,v.y,v.z);

    try {
        // Now, let's get the TopoDS_Shape
        TopoDS_Shape revolve = base->Shape.getShape().revolve(gp_Ax1(pnt, dir),
            Angle.getValue()/180.0f*Standard_PI);
        if (revolve.IsNull())
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        this->Shape.setValue(revolve);
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
}
<|endoftext|>