Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/static allocation #169

Merged
82 changes: 60 additions & 22 deletions erpc_c/config/erpc_config.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* Copyright 2020 ACRIOS Systems s.r.o.
* Copyright 2020-2021 ACRIOS Systems s.r.o.
* All rights reserved.
*
*
Expand All @@ -23,39 +23,77 @@

//! @name Threading model options
//@{
#define ERPC_THREADS_NONE (0) //!< No threads.
#define ERPC_THREADS_PTHREADS (1) //!< POSIX pthreads.
#define ERPC_THREADS_FREERTOS (2) //!< FreeRTOS.
#define ERPC_THREADS_ZEPHYR (3) //!< ZEPHYR.
#define ERPC_THREADS_MBED (4) //!< Mbed OS
#define ERPC_THREADS_WIN32 (5) //!< WIN32
#define ERPC_THREADS_THREADX (6) //!< THREADX
#define ERPC_ALLOCATION_POLICY_DYNAMIC (0U) //!< Dynamic allocation policy
#define ERPC_ALLOCATION_POLICY_STATIC (1U) //!< Static allocation policy

#define ERPC_NOEXCEPT_DISABLED (0) //!< Disabling noexcept feature.
#define ERPC_NOEXCEPT_ENABLED (1) //!< Enabling noexcept feature.
#define ERPC_THREADS_NONE (0U) //!< No threads.
#define ERPC_THREADS_PTHREADS (1U) //!< POSIX pthreads.
#define ERPC_THREADS_FREERTOS (2U) //!< FreeRTOS.
#define ERPC_THREADS_ZEPHYR (3U) //!< ZEPHYR.
#define ERPC_THREADS_MBED (4U) //!< Mbed OS
#define ERPC_THREADS_WIN32 (5U) //!< WIN32
#define ERPC_THREADS_THREADX (6U) //!< THREADX

#define ERPC_NESTED_CALLS_DISABLED (0) //!< No nested calls support.
#define ERPC_NESTED_CALLS_ENABLED (1) //!< Nested calls support.
#define ERPC_NOEXCEPT_DISABLED (0U) //!< Disabling noexcept feature.
#define ERPC_NOEXCEPT_ENABLED (1U) //!< Enabling noexcept feature.

#define ERPC_NESTED_CALLS_DETECTION_DISABLED (0) //!< Nested calls detection disabled.
#define ERPC_NESTED_CALLS_DETECTION_ENABLED (1) //!< Nested calls detection enabled.
#define ERPC_NESTED_CALLS_DISABLED (0U) //!< No nested calls support.
#define ERPC_NESTED_CALLS_ENABLED (1U) //!< Nested calls support.

#define ERPC_MESSAGE_LOGGING_DISABLED (0) //!< Trace functions disabled.
#define ERPC_MESSAGE_LOGGING_ENABLED (1) //!< Trace functions enabled.
#define ERPC_NESTED_CALLS_DETECTION_DISABLED (0U) //!< Nested calls detection disabled.
#define ERPC_NESTED_CALLS_DETECTION_ENABLED (1U) //!< Nested calls detection enabled.

#define ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED (0) //!< Do not use MCMGR for MU ISR management.
#define ERPC_TRANSPORT_MU_USE_MCMGR_ENABLED (1) //!< Use MCMGR for MU ISR management.
#define ERPC_MESSAGE_LOGGING_DISABLED (0U) //!< Trace functions disabled.
#define ERPC_MESSAGE_LOGGING_ENABLED (1U) //!< Trace functions enabled.

#define ERPC_PRE_POST_ACTION_DISABLED (0) //!< Pre post shim callbacks functions disabled.
#define ERPC_PRE_POST_ACTION_ENABLED (1) //!< Pre post shim callback functions enabled.
#define ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED (0U) //!< Do not use MCMGR for MU ISR management.
#define ERPC_TRANSPORT_MU_USE_MCMGR_ENABLED (1U) //!< Use MCMGR for MU ISR management.

#define ERPC_PRE_POST_ACTION_DEFAULT_DISABLED (0) //!< Pre post shim default callbacks functions disabled.
#define ERPC_PRE_POST_ACTION_DEFAULT_ENABLED (1) //!< Pre post shim default callback functions enabled.
#define ERPC_PRE_POST_ACTION_DISABLED (0U) //!< Pre post shim callbacks functions disabled.
#define ERPC_PRE_POST_ACTION_ENABLED (1U) //!< Pre post shim callback functions enabled.

#define ERPC_PRE_POST_ACTION_DEFAULT_DISABLED (0U) //!< Pre post shim default callbacks functions disabled.
#define ERPC_PRE_POST_ACTION_DEFAULT_ENABLED (1U) //!< Pre post shim default callback functions enabled.
//@}

//! @name Configuration options
//@{

//! @def ERPC_ALLOCATION_POLICY
//!
//! @brief Choose which allocation policy should be used.
//!
//! Set ERPC_ALLOCATION_POLICY_DYNAMIC if dynamic allocations should be used.
//! Set ERPC_ALLOCATION_POLICY_STATIC if static allocations should be used.
//!
//! Default value is ERPC_ALLOCATION_POLICY_DYNAMIC or in case of FreeRTOS it can be auto-detected if __has_include() is supported
//! by compiler. Uncomment comment bellow to use static allocation policy.
//! In case of static implementation user need consider another values to set (ERPC_CODEC_COUNT,
//! ERPC_MESSAGE_LOGGERS_COUNT, ERPC_CLIENTS_THREADS_AMOUNT).
// #define ERPC_ALLOCATION_POLICY (ERPC_ALLOCATION_POLICY_STATIC)

//! @def ERPC_CODEC_COUNT
//!
//! @brief Set amount of codecs objects used simultaneously in case of ERPC_ALLOCATION_POLICY is set to
//! ERPC_ALLOCATION_POLICY_STATIC. For example if client or server is used in one thread then 1. If both are used in one thread per
//! each then 2, ... Default value 2.
// #define ERPC_CODEC_COUNT (2U)

//! @def ERPC_MESSAGE_LOGGERS_COUNT
//!
//! @brief Set amount of message loggers objects used simultaneously in case of ERPC_ALLOCATION_POLICY is set to
//! ERPC_ALLOCATION_POLICY_STATIC.
//! For example if client or server is used in one thread then 1. If both are used in one thread per each then 2, ...
//! For arbitrated client 1 is enough.
//! Default value 0 (May not be used).
// #define ERPC_MESSAGE_LOGGERS_COUNT (0U)

//! @def ERPC_CLIENTS_THREADS_AMOUNT
//!
//! @brief Set amount of client threads objects used in case of ERPC_ALLOCATION_POLICY is set to ERPC_ALLOCATION_POLICY_STATIC.
//! Default value 1 (Most of current cases).
// #define ERPC_CLIENTS_THREADS_AMOUNT (1U)

//! @def ERPC_THREADS
//!
//! @brief Select threading model.
Expand Down
17 changes: 17 additions & 0 deletions erpc_c/infra/erpc_basic_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

#include "erpc_basic_codec.h"

#include "erpc_manually_constructed.h"

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include <new>
#endif
#include <cassert>

using namespace erpc;
Expand Down Expand Up @@ -370,3 +375,15 @@ void BasicCodec::readCallback(funPtr callbacks1, funPtr *callback2)
// callbacks = callback directly
*callback2 = callbacks1;
}

ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT);

Codec *BasicCodecFactory ::create()
{
ERPC_CREATE_NEW_OBJECT(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT)
}

void BasicCodecFactory ::dispose(Codec *codec)
{
ERPC_DESTROY_OBJECT(codec, s_basicCodecManual, ERPC_CODEC_COUNT)
}
6 changes: 2 additions & 4 deletions erpc_c/infra/erpc_basic_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

#include "erpc_codec.h"

#include <new>

/*!
* @addtogroup infra_codec
* @{
Expand Down Expand Up @@ -385,14 +383,14 @@ class BasicCodecFactory : public CodecFactory
*
* @return Pointer to created codec.
*/
virtual Codec *create(void) override { return new (std::nothrow) BasicCodec; }
virtual Codec *create(void) override;

/*!
* @brief Dispose codec.
*
* @param[in] codec Codec to dispose.
*/
virtual void dispose(Codec *codec) override { delete codec; }
virtual void dispose(Codec *codec) override;
};

} // namespace erpc
Expand Down
61 changes: 61 additions & 0 deletions erpc_c/infra/erpc_manually_constructed.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

#ifndef _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_
#define _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_

#include "erpc_config_internal.h"

#include <new>
#include <stdint.h>

Expand Down Expand Up @@ -154,6 +157,14 @@ class ManuallyConstructed
}
}

/*!
* @brief Returns information if object is free or is used.
*
* @return true Object is constructed and used.
* @return false Object wasn't constructer or it is destructed and free.
*/
bool isUsed() { return m_isConstructed; }

protected:
/*!
* @brief Storage for the object.
Expand All @@ -170,6 +181,56 @@ class ManuallyConstructed
bool m_isConstructed = false;
};

#define ERPC_MANUALLY_CONSTRUCTED(class, variableName) static ManuallyConstructed<class> variableName
#define ERPC_MANUALLY_CONSTRUCTED_ARRAY(class, variableName, dimension) \
ERPC_MANUALLY_CONSTRUCTED(class, variableName)[dimension]

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
#define ERPC_MANUALLY_CONSTRUCTED_STATIC(class, variableName) ERPC_MANUALLY_CONSTRUCTED(class, variableName)
#else
#define ERPC_MANUALLY_CONSTRUCTED_STATIC(class, variableName)
#endif

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
#define ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(class, variableName, dimension) \
ERPC_MANUALLY_CONSTRUCTED_ARRAY(class, variableName, dimension)
#else
#define ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(class, variableName, dimension)
#endif

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#define ERPC_CREATE_NEW_OBJECT(class, arrayOfObjects, numberOfObjects, ...) \
return new (std::nothrow) class(__VA_ARGS__);

#define ERPC_DESTROY_OBJECT(object, ...) delete object;

#elif ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
#define ERPC_CREATE_NEW_OBJECT(class, arrayOfObjects, numberOfObjects, ...) \
uint8_t objectsIterator; \
class *ret = NULL; \
for (objectsIterator = 0; objectsIterator < numberOfObjects; objectsIterator++) \
{ \
if (!arrayOfObjects[objectsIterator].isUsed()) \
{ \
arrayOfObjects[objectsIterator].construct(__VA_ARGS__); \
ret = arrayOfObjects[objectsIterator].get(); \
break; \
} \
} \
return ret;

#define ERPC_DESTROY_OBJECT(object, arrayOfObjects, numberOfObjects) \
uint8_t objectsIterator; \
for (objectsIterator = 0; objectsIterator < numberOfObjects; objectsIterator++) \
{ \
if (object == arrayOfObjects[objectsIterator].get()) \
{ \
arrayOfObjects[objectsIterator].destroy(); \
break; \
} \
}
#endif

} // namespace erpc

/*! @} */
Expand Down
16 changes: 14 additions & 2 deletions erpc_c/infra/erpc_message_loggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

#include "erpc_message_loggers.h"

#include "erpc_manually_constructed.h"

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include <new>
#endif

using namespace erpc;
using namespace std;
Expand All @@ -20,6 +24,8 @@ using namespace std;
// Code
////////////////////////////////////////////////////////////////////////////////

ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(MessageLogger, s_messageLoggersManual, ERPC_MESSAGE_LOGGERS_COUNT);

MessageLoggers::~MessageLoggers(void)
{
MessageLogger *logger;
Expand All @@ -28,7 +34,7 @@ MessageLoggers::~MessageLoggers(void)
{
logger = m_logger;
m_logger = m_logger->getNext();
delete logger;
ERPC_DESTROY_OBJECT(logger, s_messageLoggersManual, ERPC_MESSAGE_LOGGERS_COUNT)
}
}

Expand All @@ -40,7 +46,7 @@ bool MessageLoggers::addMessageLogger(Transport *transport)

if (transport != NULL)
{
logger = new (nothrow) MessageLogger(transport);
logger = create(transport);
if (logger != NULL)
{
if (m_logger == NULL)
Expand Down Expand Up @@ -84,4 +90,10 @@ erpc_status_t MessageLoggers::logMessage(MessageBuffer *msg)

return err;
}

MessageLogger *MessageLoggers::create(Transport *transport)
{
ERPC_CREATE_NEW_OBJECT(MessageLogger, s_messageLoggersManual, ERPC_MESSAGE_LOGGERS_COUNT, transport)
}

#endif /* ERPC_MESSAGE_LOGGING */
10 changes: 10 additions & 0 deletions erpc_c/infra/erpc_message_loggers.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ class MessageLoggers
* @return The eRPC status based on transport type.
*/
erpc_status_t logMessage(MessageBuffer *msg);

private:
/**
* @brief This function create new MessageLogger object
*
* @param[in] transport Transport used by MessageLogger.
*
* @return MessageLogger* Returns new MessageLogger object.
*/
MessageLogger *create(Transport *transport);
};

} // namespace erpc
Expand Down
12 changes: 9 additions & 3 deletions erpc_c/infra/erpc_transport_arbitrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
#include "erpc_transport_arbitrator.h"

#include "erpc_config_internal.h"
#include "erpc_manually_constructed.h"

#include <cassert>
#include <cstdio>
Expand All @@ -25,6 +25,9 @@ using namespace erpc;
// Code
////////////////////////////////////////////////////////////////////////////////

ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(TransportArbitrator::PendingClientInfo, s_pendingClientInfoArray,
ERPC_CLIENTS_THREADS_AMOUNT);

TransportArbitrator::TransportArbitrator(void)
: Transport()
, m_sharedTransport(NULL)
Expand Down Expand Up @@ -169,6 +172,9 @@ erpc_status_t TransportArbitrator::clientReceive(client_token_t token)
return kErpcStatus_Success;
}

TransportArbitrator::PendingClientInfo *TransportArbitrator::createPendingClient(void){ ERPC_CREATE_NEW_OBJECT(
TransportArbitrator::PendingClientInfo, s_pendingClientInfoArray, ERPC_CLIENTS_THREADS_AMOUNT) }

TransportArbitrator::PendingClientInfo *TransportArbitrator::addPendingClient(void)
{
Mutex::Guard lock(m_clientListMutex);
Expand All @@ -177,7 +183,7 @@ TransportArbitrator::PendingClientInfo *TransportArbitrator::addPendingClient(vo
PendingClientInfo *info = NULL;
if (!m_clientFreeList)
{
info = new PendingClientInfo();
info = createPendingClient();
}
else
{
Expand Down Expand Up @@ -241,7 +247,7 @@ void TransportArbitrator::freeClientList(PendingClientInfo *list)
{
temp = info;
info = info->m_next;
delete temp;
ERPC_DESTROY_OBJECT(temp, s_pendingClientInfoArray, ERPC_CLIENTS_THREADS_AMOUNT)
}
}

Expand Down
15 changes: 11 additions & 4 deletions erpc_c/infra/erpc_transport_arbitrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@ class TransportArbitrator : public Transport
*/
virtual bool hasMessage(void) override;

protected:
Transport *m_sharedTransport; //!< Transport being shared through this arbitrator.
Codec *m_codec; //!< Codec used to read incoming message headers.

/*!
* @brief Request info for a client trying to receive a response.
*/
Expand All @@ -154,10 +150,21 @@ class TransportArbitrator : public Transport
~PendingClientInfo(void);
};

protected:
Transport *m_sharedTransport; //!< Transport being shared through this arbitrator.
Codec *m_codec; //!< Codec used to read incoming message headers.

PendingClientInfo *m_clientList; //!< Active client receive requests.
PendingClientInfo *m_clientFreeList; //!< Unused client receive info structs.
Mutex m_clientListMutex; //!< Mutex guarding the client active and free lists.

/*!
* @brief Create a Pending Client object.
*
* @return PendingClientInfo* Return created object.
*/
PendingClientInfo *createPendingClient(void);

/*!
* @brief This function adds pending client.
*
Expand Down
Loading