diff --git a/.gitignore b/.gitignore index 5e5539c..da6d8ee 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ build**/ .idea/ .vs/ CMakeSettings.json +run/ +img/ \ No newline at end of file diff --git a/src/base/Semaphore.cpp b/src/base/Semaphore.cpp deleted file mode 100644 index e409df8..0000000 --- a/src/base/Semaphore.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* AXPbox Alpha Emulator - * Copyright (C) 2020 Tomáš Glozar - * Website: https://github.com/lenticularis39/axpbox - * - * Forked from: ES40 emulator - * Copyright (C) 2007-2008 by the ES40 Emulator Project - * Copyright (C) 2007 by Camiel Vanderhoeven - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Although this is not required, the author would appreciate being notified of, - * and receiving any modifications you may make to the source code that might - * serve the general public. - * - * Parts of this file based upon the Poco C++ Libraries, which is Copyright (C) - * 2004-2006, Applied Informatics Software Engineering GmbH. and Contributors. - */ - -// -// Semaphore.cpp -// -// $Id: Semaphore.cpp,v 1.1 2008/05/31 15:47:28 iamcamiel Exp $ -// -// Library: Foundation -// Package: Threading -// Module: Semaphore -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#include "Semaphore.hpp" - -#if defined(POCO_OS_FAMILY_WINDOWS) -#include "Semaphore_WIN32.cpp" -#else -#include "Semaphore_POSIX.cpp" -#endif - -CSemaphore::CSemaphore(int n) : CSemaphoreImpl(n, n) {} - -CSemaphore::CSemaphore(int n, int max) : CSemaphoreImpl(n, max) {} - -CSemaphore::~CSemaphore() {} diff --git a/src/base/Semaphore.hpp b/src/base/Semaphore.hpp index 6eafcbf..6f3aef4 100644 --- a/src/base/Semaphore.hpp +++ b/src/base/Semaphore.hpp @@ -28,138 +28,64 @@ * Parts of this file based upon the Poco C++ Libraries, which is Copyright (C) * 2004-2006, Applied Informatics Software Engineering GmbH. and Contributors. */ +#pragma once -// -// Semaphore.h -// -// $Id: Semaphore.h,v 1.1 2008/05/31 15:47:28 iamcamiel Exp $ -// -// Library: Foundation -// Package: Threading -// Module: Semaphore -// -// Definition of the Semaphore class. -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// +#include "es40_debug.hpp" +#include +#include +#include -#ifndef Foundation_Semaphore_INCLUDED -#define Foundation_Semaphore_INCLUDED - -#include "Exception.hpp" -#include "Foundation.hpp" - -#if defined(POCO_OS_FAMILY_WINDOWS) -#include "Semaphore_WIN32.hpp" -#else -#include "Semaphore_POSIX.hpp" -#endif - -class CSemaphore : private CSemaphoreImpl -/// A Semaphore is a synchronization object with the following -/// characteristics: -/// A semaphore has a value that is constrained to be a non-negative -/// integer and two atomic operations. The allowable operations are V -/// (here called set()) and P (here called wait()). A V (set()) operation -/// increases the value of the semaphore by one. -/// A P (wait()) operation decreases the value of the semaphore by one, -/// provided that can be done without violating the constraint that the -/// value be non-negative. A P (wait()) operation that is initiated when -/// the value of the semaphore is 0 suspends the calling thread. -/// The calling thread may continue when the value becomes positive again. -{ +class CSemaphore { public: - CSemaphore(int n); - CSemaphore(int n, int max); - /// Creates the semaphore. The current value - /// of the semaphore is given in n. The - /// maximum value of the semaphore is given - /// in max. - /// If only n is given, it must be greater than - /// zero. - /// If both n and max are given, max must be - /// greater than zero, n must be greater than - /// or equal to zero and less than or equal - /// to max. - - ~CSemaphore(); - /// Destroys the semaphore. - - void set(); - /// Increments the semaphore's value by one and - /// thus signals the semaphore. Another thread - /// waiting for the semaphore will be able - /// to continue. - - void wait(); - /// Waits for the semaphore to become signalled. - /// To become signalled, a semaphore's value must - /// be greater than zero. - /// Decrements the semaphore's value by one. - - void wait(long milliseconds); - /// Waits for the semaphore to become signalled. - /// To become signalled, a semaphore's value must - /// be greater than zero. - /// Throws a TimeoutException if the semaphore - /// does not become signalled within the specified - /// time interval. - /// Decrements the semaphore's value by one - /// if successful. - - bool tryWait(long milliseconds); - /// Waits for the semaphore to become signalled. - /// To become signalled, a semaphore's value must - /// be greater than zero. - /// Returns true if the semaphore - /// became signalled within the specified - /// time interval, false otherwise. - /// Decrements the semaphore's value by one - /// if successful. + explicit CSemaphore(int n) : m_count(n), m_max(n) {} + CSemaphore(int n, int max) : m_count(n), m_max(max) { + if (n < 0 || n > max) { + FAILURE(InvalidArgument, "Invalid initial count for semaphore"); + } + } + + ~CSemaphore() = default; + CSemaphore() = delete; + CSemaphore(const CSemaphore &) = delete; + CSemaphore &operator=(const CSemaphore &) = delete; + CSemaphore(const CSemaphore &&) = delete; + CSemaphore &operator=(const CSemaphore &&) = delete; + + void set() { + std::unique_lock const lock(m_mutex); + if (m_count >= m_max) { + FAILURE(System, "cannot signal semaphore: count would exceed maximum"); + } + ++m_count; + m_cv.notify_one(); + } + + void wait() { + std::unique_lock lock(m_mutex); + m_cv.wait(lock, [this] { return m_count > 0; }); + --m_count; + } + + void wait(long milliseconds) { + std::unique_lock lock(m_mutex); + if (!m_cv.wait_for(lock, std::chrono::milliseconds(milliseconds), [this] { return m_count > 0; })) { + FAILURE(Timeout, "Timeout"); + } + --m_count; + } + + bool tryWait(long milliseconds) { + std::unique_lock lock(m_mutex); + if (m_cv.wait_for(lock, std::chrono::milliseconds(milliseconds), [this] { return m_count > 0; })) { + --m_count; + return true; + } + return false; + } private: - CSemaphore(); - CSemaphore(const CSemaphore &); - CSemaphore &operator=(const CSemaphore &); -}; - -// -// inlines -// -inline void CSemaphore::set() { setImpl(); } - -inline void CSemaphore::wait() { waitImpl(); } - -inline void CSemaphore::wait(long milliseconds) { - if (!waitImpl(milliseconds)) - throw CTimeoutException(); -} - -inline bool CSemaphore::tryWait(long milliseconds) { - return waitImpl(milliseconds); -} - -#endif // Foundation_Semaphore_INCLUDED + int m_count; + int m_max; + std::mutex m_mutex; + std::condition_variable m_cv; +}; \ No newline at end of file diff --git a/src/base/Semaphore_POSIX.cpp b/src/base/Semaphore_POSIX.cpp deleted file mode 100644 index 4b098ff..0000000 --- a/src/base/Semaphore_POSIX.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* AXPbox Alpha Emulator - * Copyright (C) 2020 Tomáš Glozar - * Website: https://github.com/lenticularis39/axpbox - * - * Forked from: ES40 emulator - * Copyright (C) 2007-2008 by the ES40 Emulator Project - * Copyright (C) 2007 by Camiel Vanderhoeven - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Although this is not required, the author would appreciate being notified of, - * and receiving any modifications you may make to the source code that might - * serve the general public. - * - * Parts of this file based upon the Poco C++ Libraries, which is Copyright (C) - * 2004-2006, Applied Informatics Software Engineering GmbH. and Contributors. - */ - -// -// Semaphore_POSIX.cpp -// -// Library: Foundation -// Package: Threading -// Module: Semaphore -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// SPDX-License-Identifier: BSL-1.0 -// - -#include "Semaphore_POSIX.hpp" -#include - -// -// Note: pthread_cond_timedwait() with CLOCK_MONOTONIC is supported -// on Linux and QNX, as well as on Android >= 5.0 (API level 21). -// On Android < 5.0, HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC is defined -// to indicate availability of non-standard pthread_cond_timedwait_monotonic(). -// -#ifndef POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT -#if (defined(__linux__) || defined(__QNX__)) && \ - !(defined(__ANDROID__) && \ - (defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC) || \ - __ANDROID_API__ <= 21)) -#define POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT 1 -#endif -#endif - -#ifndef POCO_HAVE_CLOCK_GETTIME -#if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || \ - defined(POCO_VXWORKS) || defined(__QNX__) -#ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac - // OS 10.12/iOS 10 -#define POCO_HAVE_CLOCK_GETTIME -#endif -#endif -#endif - -CSemaphoreImpl::CSemaphoreImpl(int n, int max) : _n(n), _max(max) { - poco_assert(n >= 0 && max > 0 && n <= max); - -#if defined(POCO_VXWORKS) - // This workaround is for VxWorks 5.x where - // pthread_mutex_init() won't properly initialize the mutex - // resulting in a subsequent freeze in pthread_mutex_destroy() - // if the mutex has never been used. - std::memset(&_mutex, 0, sizeof(_mutex)); -#endif - if (pthread_mutex_init(&_mutex, NULL)) - throw CSystemException("cannot create semaphore (mutex)"); - -#if defined(POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT) - pthread_condattr_t attr; - if (pthread_condattr_init(&attr)) { - pthread_mutex_destroy(&_mutex); - throw CSystemException("cannot create semaphore (condition attribute)"); - } - if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) { - pthread_condattr_destroy(&attr); - pthread_mutex_destroy(&_mutex); - throw CSystemException( - "cannot create semaphore (condition attribute clock)"); - } - if (pthread_cond_init(&_cond, &attr)) { - pthread_condattr_destroy(&attr); - pthread_mutex_destroy(&_mutex); - throw CSystemException("cannot create semaphore (condition)"); - } - pthread_condattr_destroy(&attr); -#else - if (pthread_cond_init(&_cond, NULL)) { - pthread_mutex_destroy(&_mutex); - throw CSystemException("cannot create semaphore (condition)"); - } -#endif -} - -CSemaphoreImpl::~CSemaphoreImpl() { - pthread_cond_destroy(&_cond); - pthread_mutex_destroy(&_mutex); -} - -void CSemaphoreImpl::waitImpl() { - if (pthread_mutex_lock(&_mutex)) - throw CSystemException("wait for semaphore failed (lock)"); - while (_n < 1) { - if (pthread_cond_wait(&_cond, &_mutex)) { - pthread_mutex_unlock(&_mutex); - throw CSystemException("wait for semaphore failed"); - } - } - --_n; - pthread_mutex_unlock(&_mutex); -} - -bool CSemaphoreImpl::waitImpl(long milliseconds) { - int rc = 0; - struct timespec abstime; - -#if defined(POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT) - clock_gettime(CLOCK_MONOTONIC, &abstime); - abstime.tv_sec += milliseconds / 1000; - abstime.tv_nsec += (milliseconds % 1000) * 1000000; - if (abstime.tv_nsec >= 1000000000) { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } -#elif defined(POCO_HAVE_CLOCK_GETTIME) - clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_sec += milliseconds / 1000; - abstime.tv_nsec += (milliseconds % 1000) * 1000000; - if (abstime.tv_nsec >= 1000000000) { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } -#else - struct timeval tv; - gettimeofday(&tv, NULL); - abstime.tv_sec = tv.tv_sec + milliseconds / 1000; - abstime.tv_nsec = tv.tv_usec * 1000 + (milliseconds % 1000) * 1000000; - if (abstime.tv_nsec >= 1000000000) { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } -#endif - - if (pthread_mutex_lock(&_mutex) != 0) - throw CSystemException("wait for semaphore failed (lock)"); - while (_n < 1) { - if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime))) { - if (rc == ETIMEDOUT) - break; - pthread_mutex_unlock(&_mutex); - throw CSystemException("cannot wait for semaphore"); - } - } - if (rc == 0) - --_n; - pthread_mutex_unlock(&_mutex); - return rc == 0; -} diff --git a/src/base/Semaphore_POSIX.hpp b/src/base/Semaphore_POSIX.hpp deleted file mode 100644 index a93c41d..0000000 --- a/src/base/Semaphore_POSIX.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* AXPbox Alpha Emulator - * Copyright (C) 2020 Tomáš Glozar - * Website: https://github.com/lenticularis39/axpbox - * - * Forked from: ES40 emulator - * Copyright (C) 2007-2008 by the ES40 Emulator Project - * Copyright (C) 2007 by Camiel Vanderhoeven - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Although this is not required, the author would appreciate being notified of, - * and receiving any modifications you may make to the source code that might - * serve the general public. - * - * Parts of this file based upon the Poco C++ Libraries, which is Copyright (C) - * 2004-2006, Applied Informatics Software Engineering GmbH. and Contributors. - */ - -// -// Semaphore_POSIX.h -// -// $Id: Semaphore_POSIX.h,v 1.1 2008/05/31 15:47:28 iamcamiel Exp $ -// -// Library: Foundation -// Package: Threading -// Module: Semaphore -// -// Definition of the SemaphoreImpl class for POSIX Threads. -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#ifndef Foundation_Semaphore_POSIX_INCLUDED -#define Foundation_Semaphore_POSIX_INCLUDED - -#include "Exception.hpp" -#include "Foundation.hpp" -#include -#include - -class CSemaphoreImpl { -protected: - CSemaphoreImpl(int n, int max); - ~CSemaphoreImpl(); - void setImpl(); - void waitImpl(); - bool waitImpl(long milliseconds); - -private: - volatile int _n; - int _max; - pthread_mutex_t _mutex; - pthread_cond_t _cond; -}; - -// -// inlines -// -inline void CSemaphoreImpl::setImpl() { - if (pthread_mutex_lock(&_mutex)) - throw CSystemException("cannot signal semaphore (lock)"); - if (_n < _max) { - ++_n; - } else { - pthread_mutex_unlock(&_mutex); - throw CSystemException( - "cannot signal semaphore: count would exceed maximum"); - } - if (pthread_cond_signal(&_cond)) { - pthread_mutex_unlock(&_mutex); - throw CSystemException("cannot signal semaphore"); - } - pthread_mutex_unlock(&_mutex); -} - -#endif // Foundation_Semaphore_POSIX_INCLUDED diff --git a/src/base/Semaphore_WIN32.cpp b/src/base/Semaphore_WIN32.cpp deleted file mode 100644 index 90bdb9d..0000000 --- a/src/base/Semaphore_WIN32.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* AXPbox Alpha Emulator - * Copyright (C) 2020 Tomáš Glozar - * Website: https://github.com/lenticularis39/axpbox - * - * Forked from: ES40 emulator - * Copyright (C) 2007-2008 by the ES40 Emulator Project - * Copyright (C) 2007 by Camiel Vanderhoeven - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Although this is not required, the author would appreciate being notified of, - * and receiving any modifications you may make to the source code that might - * serve the general public. - * - * Parts of this file based upon the Poco C++ Libraries, which is Copyright (C) - * 2004-2006, Applied Informatics Software Engineering GmbH. and Contributors. - */ - -// -// Semaphore_WIN32.cpp -// -// $Id: Semaphore_WIN32.cpp,v 1.1 2008/05/31 15:47:28 iamcamiel Exp $ -// -// Library: Foundation -// Package: Threading -// Module: Semaphore -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#include "Semaphore_WIN32.hpp" - -CSemaphoreImpl::CSemaphoreImpl(int n, int max) { - poco_assert(n >= 0 && max > 0 && n <= max); - - _sema = CreateSemaphoreW(NULL, n, max, NULL); - if (!_sema) { - throw CSystemException("cannot create semaphore"); - } -} - -CSemaphoreImpl::~CSemaphoreImpl() { CloseHandle(_sema); } - -void CSemaphoreImpl::waitImpl() { - switch (WaitForSingleObject(_sema, INFINITE)) { - case WAIT_OBJECT_0: - return; - default: - throw CSystemException("wait for semaphore failed"); - } -} - -bool CSemaphoreImpl::waitImpl(long milliseconds) { - switch (WaitForSingleObject(_sema, milliseconds + 1)) { - case WAIT_TIMEOUT: - return false; - case WAIT_OBJECT_0: - return true; - default: - throw CSystemException("wait for semaphore failed"); - } -} diff --git a/src/base/Semaphore_WIN32.hpp b/src/base/Semaphore_WIN32.hpp deleted file mode 100644 index 39dd3db..0000000 --- a/src/base/Semaphore_WIN32.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* AXPbox Alpha Emulator - * Copyright (C) 2020 Tomáš Glozar - * Website: https://github.com/lenticularis39/axpbox - * - * Forked from: ES40 emulator - * Copyright (C) 2007-2008 by the ES40 Emulator Project - * Copyright (C) 2007 by Camiel Vanderhoeven - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Although this is not required, the author would appreciate being notified of, - * and receiving any modifications you may make to the source code that might - * serve the general public. - * - * Parts of this file based upon the Poco C++ Libraries, which is Copyright (C) - * 2004-2006, Applied Informatics Software Engineering GmbH. and Contributors. - */ - -// -// Semaphore_WIN32.h -// -// $Id: Semaphore_WIN32.h,v 1.1 2008/05/31 15:47:28 iamcamiel Exp $ -// -// Library: Foundation -// Package: Threading -// Module: Semaphore -// -// Definition of the SemaphoreImpl class for WIN32. -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#ifndef Foundation_Semaphore_WIN32_INCLUDED -#define Foundation_Semaphore_WIN32_INCLUDED - -#include "Exception.hpp" -#include "Foundation.hpp" -#include "UnWindows.hpp" - -class CSemaphoreImpl { -protected: - CSemaphoreImpl(int n, int max); - ~CSemaphoreImpl(); - void setImpl(); - void waitImpl(); - bool waitImpl(long milliseconds); - -private: - HANDLE _sema; -}; - -// -// inlines -// -inline void CSemaphoreImpl::setImpl() { - if (!ReleaseSemaphore(_sema, 1, NULL)) { - throw CSystemException("cannot signal semaphore"); - } -} - -#endif // Foundation_Semaphore_WIN32_INCLUDED diff --git a/src/es40_debug.cpp b/src/es40_debug.cpp deleted file mode 100644 index abdc487..0000000 --- a/src/es40_debug.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* AXPbox Alpha Emulator - * Copyright (C) 2020 Tomáš Glozar - * Website: https://github.com/lenticularis39/axpbox - * - * Forked from: ES40 emulator - * Copyright (C) 2007-2008 by the ES40 Emulator Project - * Copyright (C) 2007 by Camiel Vanderhoeven - This file is based upon GXemul. - * - * Copyright (C) 2004-2007 Anders Gavare. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -/***************************************************************************** - * - * NOTE: debug(), fatal(), and debug_indentation() are not re-entrant. - * The global variable quiet_mode can be used to suppress the output - * of debug(), but not the output of fatal(). - * - *****************************************************************************/ -#include "StdAfx.hpp" - -// int verbose = 0; -int quiet_mode = 0; - -static int debug_indent = 0; -static int debug_currently_at_start_of_line = 1; - -/* - * va_debug(): - * - * Used internally by debug() and fatal(). - */ -static void va_debug(va_list argp, char *fmt) { - char buf[DEBUG_BUFSIZE + 1]; - char *s; - int i; - - buf[0] = buf[DEBUG_BUFSIZE] = 0; - - // vsnprintf(buf, DEBUG_BUFSIZE, fmt, argp); - sprintf(buf, fmt, argp); - - s = buf; - while (*s) { - if (debug_currently_at_start_of_line) { - for (i = 0; i < debug_indent; i++) - printf(" "); - } - - printf("%c", *s); - - debug_currently_at_start_of_line = 0; - if (*s == '\n' || *s == '\r') - debug_currently_at_start_of_line = 1; - s++; - } -} - -/* - * debug_indentation(): - * - * Modify the debug indentation. - */ -void debug_indentation(int diff) { - debug_indent += diff; - if (debug_indent < 0) - fprintf(stderr, "WARNING: debug_indent less than 0!\n"); -} - -/* - * debug(): - * - * Debug output (ignored if quiet_mode is set). - */ -void debug(char *fmt, ...) { - va_list argp; - - if (quiet_mode) - return; - - va_start(argp, fmt); - va_debug(argp, fmt); - va_end(argp); -} - -/* - * fatal(): - * - * Fatal works like debug(), but doesn't care about the quiet_mode - * setting. - */ -void fatal(char *fmt, ...) { - va_list argp; - - va_start(argp, fmt); - va_debug(argp, fmt); - va_end(argp); -} diff --git a/src/es40_debug.hpp b/src/es40_debug.hpp index 9373c70..9b84a38 100644 --- a/src/es40_debug.hpp +++ b/src/es40_debug.hpp @@ -29,74 +29,47 @@ * Anders Gavare. All rights reserved. */ -#include +#pragma once +#include "base/Exception.hpp" +#include #if !defined(INCLUDED_DEBUG_H) #define INCLUDED_DEBUG_H +#endif -#define DEBUG_BUFSIZE 1024 -#define FAILMSG_BUFSIZE 8000 -#define DEBUG_INDENTATION 4 - -#ifdef HAVE___FUNCTION__ -#define FAILURE(cls, error_msg) \ - { \ - char where_msg[FAILMSG_BUFSIZE];; \ - sprintf(where_msg, "%s, line %i, function '%s'", __FILE__, __LINE__, \ - __FUNCTION__); \ - throw C##cls##Exception(error_msg, where_msg); \ - } - -#else -#define FAILURE(cls, error_msg) \ - { \ - char where_msg[FAILMSG_BUFSIZE]; \ - sprintf(where_msg, "%s, line %i", __FILE__, __LINE__); \ - throw C##cls##Exception(error_msg, where_msg); \ +#define FAILURE(cls, error_msg, ...) \ + { \ + char what_msg[8000]; \ + int ret = snprintf(what_msg, sizeof(what_msg), error_msg, ##__VA_ARGS__); \ + if (ret < 0 || ret >= sizeof(what_msg)) { \ + throw CRuntimeException("Error constructing error message"); \ + } \ + char where_msg[8000]; \ + ret = snprintf(where_msg, sizeof(where_msg), "%s, line %i", __FILE__, __LINE__); \ + if (ret < 0 || ret >= sizeof(where_msg)) { \ + throw CRuntimeException("Error constructing error message"); \ + } \ + throw C##cls##Exception(what_msg, where_msg); \ } -#endif /* !HAVE___FUNCTION__ */ #define FAILURE_1(cls, error_msg, a) \ - { \ - char what_msg[FAILMSG_BUFSIZE]; \ - sprintf(what_msg, error_msg, a); \ - FAILURE(cls, what_msg); \ - } + FAILURE(cls, error_msg, a) #define FAILURE_2(cls, error_msg, a, b) \ - { \ - char what_msg[FAILMSG_BUFSIZE]; \ - sprintf(what_msg, error_msg, a, b); \ - FAILURE(cls, what_msg); \ - } + FAILURE(cls, error_msg, a, b) #define FAILURE_3(cls, error_msg, a, b, c) \ - { \ - char what_msg[FAILMSG_BUFSIZE]; \ - sprintf(what_msg, error_msg, a, b, c); \ - FAILURE(cls, what_msg); \ - } + FAILURE(cls, error_msg, a, b, c) #define FAILURE_4(cls, error_msg, a, b, c, d) \ - { \ - char what_msg[FAILMSG_BUFSIZE]; \ - sprintf(what_msg, error_msg, a, b, c, d); \ - FAILURE(cls, what_msg); \ - } + FAILURE(cls, error_msg, a, b, c, d) #define FAILURE_5(cls, error_msg, a, b, c, d, e) \ - { \ - char what_msg[FAILMSG_BUFSIZE]; \ - sprintf(what_msg, error_msg, a, b, c, d, e); \ - FAILURE(cls, what_msg); \ - } + FAILURE(cls, error_msg, a, b, c, d, e) #define FAILURE_6(cls, error_msg, a, b, c, d, e, f) \ - { \ - char what_msg[FAILMSG_BUFSIZE]; \ - sprintf(what_msg, error_msg, a, b, c, d, e, f); \ - FAILURE(cls, what_msg); \ - } + FAILURE(cls, error_msg, a, b, c, d, e, f) + #define CHECK_ALLOCATION(ptr) \ { \ @@ -115,7 +88,3 @@ } \ } -void debug_indentation(int diff); -void debug(char *fmt, ...); -void fatal(char *fmt, ...); -#endif