Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6491286
initial testing
philbucher May 27, 2021
2525a30
Merge branch 'master' into testing-different-executables
philbucher Jun 1, 2021
e3862bf
restructured singleton tests
philbucher Jun 1, 2021
e5c4248
minor
philbucher Jun 1, 2021
a940186
minor
philbucher Jun 1, 2021
dbe5660
Merge branch 'master' into testing-different-executables
philbucher Jun 1, 2021
8224cf5
removed old files
philbucher Jun 1, 2021
fce152f
minor cleanup
philbucher Jun 1, 2021
e8eeb85
minor
philbucher Jun 1, 2021
90a2571
adding second scenario
philbucher Jun 1, 2021
14a309e
missing
philbucher Jun 1, 2021
b44bb76
adding scenario 3
philbucher Jun 1, 2021
5416a64
adding scenario 4
philbucher Jun 2, 2021
1241e36
adding scenario 5
philbucher Jun 2, 2021
4daf91c
adding scenario 6
philbucher Jun 2, 2021
e6d2065
improve registry
philbucher Jun 2, 2021
3c80c4b
extern no longer necessary
philbucher Jun 2, 2021
2343d8f
adding comment
philbucher Jun 2, 2021
48cf7eb
try singleton
philbucher Jun 2, 2021
d5a54f7
last attempt
philbucher Jun 2, 2021
0f855b5
using Singleton of Alexandrescu
philbucher Jun 21, 2021
3fb9562
Merge branch 'master' into testing-different-executables
philbucher Jun 21, 2021
efc5167
another test
philbucher Jun 21, 2021
c27eecd
Revert "extern no longer necessary"
philbucher Jun 2, 2021
f56a012
simplified
philbucher Jun 21, 2021
d7acf10
try sth
philbucher Jun 21, 2021
d6a4fac
missing extern
philbucher Jun 21, 2021
a470349
removed all CO_SIM_IO_EXTERN
philbucher Jun 21, 2021
6cbca80
this is promissing
philbucher Jun 21, 2021
05e703b
missing updates
philbucher Jun 21, 2021
4ca4642
moving definition
philbucher Jun 21, 2021
830e39b
maybe wrong place?
philbucher Jun 21, 2021
1956142
adding Philipps example
philbucher Jun 21, 2021
1536b1c
philipps example with CoSimIO
philbucher Jun 21, 2021
c1dd877
calling CoSimIO
philbucher Jun 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions co_sim_io/c/co_sim_io_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extern "C" {
#include "co_sim_io_c.h"
}
#include "../co_sim_io.hpp"
DEFINE_SINGLETON_MAIN( );

namespace {
// get C Info from C++ Info
Expand Down
199 changes: 199 additions & 0 deletions co_sim_io/impl/Threads.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#ifndef THREADS_H_
#define THREADS_H_

////////////////////////////////////////////////////////////////////////////////
// macro DEFAULT_THREADING
// Selects the default threading model for certain components of Loki
// If you don't define it, it defaults to single-threaded
// All classes in Loki have configurable threading model; DEFAULT_THREADING
// affects only default template arguments
////////////////////////////////////////////////////////////////////////////////

// Last update: June 20, 2001

#ifndef DEFAULT_THREADING
#define DEFAULT_THREADING /**/ ::Loki::SingleThreaded
#endif

namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
// class template SingleThreaded
// Implementation of the ThreadingModel policy used by various classes
// Implements a single-threaded model; no synchronization
////////////////////////////////////////////////////////////////////////////////

template <class Host>
class SingleThreaded
{
public:
struct Lock
{
Lock() {}
explicit Lock(const SingleThreaded&) {}
};

typedef Host VolatileType;

typedef int IntType;

static IntType AtomicAdd(volatile IntType& lval, IntType val)
{ return lval += val; }

static IntType AtomicSubtract(volatile IntType& lval, IntType val)
{ return lval -= val; }

static IntType AtomicMultiply(volatile IntType& lval, IntType val)
{ return lval *= val; }

static IntType AtomicDivide(volatile IntType& lval, IntType val)
{ return lval /= val; }

static IntType AtomicIncrement(volatile IntType& lval)
{ return ++lval; }

static IntType AtomicDecrement(volatile IntType& lval)
{ return --lval; }

static void AtomicAssign(volatile IntType & lval, IntType val)
{ lval = val; }

static void AtomicAssign(IntType & lval, volatile IntType & val)
{ lval = val; }
};

#ifdef _WINDOWS_

////////////////////////////////////////////////////////////////////////////////
// class template ObjectLevelLockable
// Implementation of the ThreadingModel policy used by various classes
// Implements a object-level locking scheme
////////////////////////////////////////////////////////////////////////////////

template <class Host>
class ObjectLevelLockable
{
mutable CRITICAL_SECTION mtx_;

public:
ObjectLevelLockable()
{
::InitializeCriticalSection(&mtx_);
}

~ObjectLevelLockable()
{
::DeleteCriticalSection(&mtx_);
}

class Lock;
friend class Lock;

class Lock
{
ObjectLevelLockable const& host_;

Lock(const Lock&);
Lock& operator=(const Lock&);
public:

explicit Lock(const ObjectLevelLockable& host) : host_(host)
{
::EnterCriticalSection(&host_.mtx_);
}

~Lock()
{
::LeaveCriticalSection(&host_.mtx_);
}
};

typedef volatile Host VolatileType;

typedef LONG IntType;

static IntType AtomicIncrement(volatile IntType& lval)
{ return InterlockedIncrement(&const_cast<IntType&>(lval)); }

static IntType AtomicDecrement(volatile IntType& lval)
{ return InterlockedDecrement(&const_cast<IntType&>(lval)); }

static void AtomicAssign(volatile IntType& lval, IntType val)
{ InterlockedExchange(&const_cast<IntType&>(lval), val); }

static void AtomicAssign(IntType& lval, volatile IntType& val)
{ InterlockedExchange(&lval, val); }
};

template <class Host>
class ClassLevelLockable
{
struct Initializer
{
CRITICAL_SECTION mtx_;

Initializer()
{
::InitializeCriticalSection(&mtx_);
}
~Initializer()
{
::DeleteCriticalSection(&mtx_);
}
};

static Initializer initializer_;

public:
class Lock;
friend class Lock;

class Lock
{
Lock(const Lock&);
Lock& operator=(const Lock&);
public:
Lock()
{
::EnterCriticalSection(&initializer_.mtx_);
}
explicit Lock(const ClassLevelLockable&)
{
::EnterCriticalSection(&initializer_.mtx_);
}
~Lock()
{
::LeaveCriticalSection(&initializer_.mtx_);
}
};

typedef volatile Host VolatileType;

typedef LONG IntType;

static IntType AtomicIncrement(volatile IntType& lval)
{ return InterlockedIncrement(&const_cast<IntType&>(lval)); }

static IntType AtomicDecrement(volatile IntType& lval)
{ return InterlockedDecrement(&const_cast<IntType&>(lval)); }

static void AtomicAssign(volatile IntType& lval, IntType val)
{ InterlockedExchange(&const_cast<IntType&>(lval), val); }

static void AtomicAssign(IntType& lval, volatile IntType& val)
{ InterlockedExchange(&lval, val); }
};

template <class Host>
typename ClassLevelLockable<Host>::Initializer
ClassLevelLockable<Host>::initializer_;

#endif
}

////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

#endif
81 changes: 73 additions & 8 deletions co_sim_io/impl/co_sim_io_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,84 @@ This file contains the implementation of the functions defined in "co_sim_io.hpp
#include "utilities.hpp"
#include "version.hpp"

#include "singleton.h"

using maptype = std::unordered_map<std::string, std::unique_ptr<CoSimIO::Internals::Connection>>;

extern maptype registry_map;

#define DEFINE_SINGLETON_MAIN( ) maptype registry_map

namespace CoSimIO {

namespace Internals {
// TODO make sure this is unique even across compilation units (test somehow)
static std::unordered_map<std::string, std::unique_ptr<Connection>> s_co_sim_connections;

static bool HasIO(const std::string& rConnectionName)
template <typename T>
class Singleton
{
public:
static T& getInstance()
{
if (!m_instance) {
m_instance = CoSimIO::make_unique<T>();
}
return *m_instance;
}

private:
static std::unique_ptr<T> m_instance;
};

template<typename T>
std::unique_ptr<T> Singleton<T>::m_instance = nullptr;

template<typename T>
class Singleton2 {
public:
static T& Instance();

Singleton2(const Singleton2&) = delete;
Singleton2& operator= (const Singleton2) = delete;

protected:
Singleton2() {}
};

template<typename T>
T& Singleton2<T>::Instance()
{
return s_co_sim_connections.find(rConnectionName) != s_co_sim_connections.end();
// #ifdef CO_SIM_IO_EXTERN
// extern T t;
// #else
static T t;
// #endif
return t;
}

static Connection& GetConnection(const std::string& rConnectionName)
// using maptype = std::unordered_map<std::string, std::unique_ptr<Connection>>;

// typedef Loki::SingletonHolder<maptype> SingleA;

// // this function makes sure that the registry works correctly also across translation units / libraries
// // inline std::unordered_map<std::string, std::unique_ptr<Connection>>& GetRegistry()
// // {
// // static std::unordered_map<std::string, std::unique_ptr<Connection>> s_co_sim_connections;
// // return s_co_sim_connections;
// // }

// using CoSimIOSingletonType = Singleton2<maptype>;

// extern maptype registry_map;

inline bool HasIO(const std::string& rConnectionName)
{
return registry_map.find(rConnectionName) != registry_map.end();
}

inline Connection& GetConnection(const std::string& rConnectionName)
{
CO_SIM_IO_ERROR_IF_NOT(HasIO(rConnectionName)) << "Trying to use connection \"" << rConnectionName << "\" which does not exist!" << std::endl;
return *s_co_sim_connections.at(rConnectionName);
return *registry_map.at(rConnectionName);
}

} // namespace Internals
Expand Down Expand Up @@ -81,7 +144,7 @@ inline Info Connect(const Info& I_Settings)

CO_SIM_IO_ERROR_IF(HasIO(connection_name)) << "A connection from \"" << my_name << "\" to \"" << connect_to << "\"already exists!" << std::endl;

s_co_sim_connections[connection_name] = std::unique_ptr<Connection>(new Connection(I_Settings));
registry_map[connection_name] = std::unique_ptr<Connection>(new Connection(I_Settings));

auto info = GetConnection(connection_name).Connect(I_Settings);
info.Set<std::string>("connection_name", connection_name);
Expand All @@ -96,7 +159,7 @@ inline Info Disconnect(const Info& I_Info)
CO_SIM_IO_ERROR_IF_NOT(HasIO(connection_name)) << "Trying to disconnect connection \"" << connection_name << "\" which does not exist!" << std::endl;

auto info = GetConnection(connection_name).Disconnect(I_Info);
s_co_sim_connections.erase(connection_name);
registry_map.erase(connection_name);

return info;
}
Expand Down Expand Up @@ -214,4 +277,6 @@ inline Info Register(

} // namespace CoSimIO



#endif // CO_SIM_IO_IMPL_INCLUDED
Loading