Skip to content

Commit

Permalink
Optimizes includes (#566)
Browse files Browse the repository at this point in the history
Reduces the compilation footprint by optimizing which files include which other files.
This enables writing code that compiles faster.

===

* Makes the compile flag parametrizable for gcc.

* Adds commands to generate statistics about includes.

* Adds missing include.

* Refactors the SNIP static valuesto a separate include file.

* Refactors static includes from memoryconfig into a separate file.

* Moves out the declaration of conversion helper functions from If.hxx to a new file Convert.hxx.

* Makes the traction throttle interface usable without having a class declaration for traction throttle itself.

* Separates the traction throttle interface from the implementation.

* Fixes whitespace.

* fix hanging brace
  • Loading branch information
balazsracz authored Aug 19, 2021
1 parent 4fec273 commit 43bfc88
Show file tree
Hide file tree
Showing 18 changed files with 773 additions and 534 deletions.
8 changes: 5 additions & 3 deletions etc/freertos.armv7m.mk
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,21 @@ ifdef DEBUG_MEMORY_USE
ARCHFLAGS += -funwind-tables
endif

ASFLAGS = -c $(ARCHFLAGS)
COMPILEOPT = -c

ASFLAGS = $(COMPILEOPT) $(ARCHFLAGS)

CORECFLAGS = $(ARCHFLAGS) -Wall -Werror -Wno-unknown-pragmas \
-fdata-sections -ffunction-sections \
-fno-builtin -fno-stack-protector -mfix-cortex-m3-ldrd \
-D__FreeRTOS__ -DGCC_ARMCM3 -specs=nano.specs

CFLAGS += -c $(ARCHOPTIMIZATION) $(CORECFLAGS) -std=c99 \
CFLAGS += $(COMPILEOPT) $(ARCHOPTIMIZATION) $(CORECFLAGS) -std=c99 \
-Wstrict-prototypes -D_REENT_SMALL \
$(CFLAGSENV) $(CFLAGSEXTRA) \


CXXFLAGS += -c $(ARCHOPTIMIZATION) $(CORECFLAGS) -std=c++14 \
CXXFLAGS += $(COMPILEOPT) $(ARCHOPTIMIZATION) $(CORECFLAGS) -std=c++14 \
-D_ISOC99_SOURCE -D__STDC_FORMAT_MACROS \
-fno-exceptions -fno-rtti \
-Wsuggest-override -Wno-psabi \
Expand Down
11 changes: 11 additions & 0 deletions etc/prog.mk
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ endif
cg.svg: $(EXECUTABLE).ndlst $(OPENMRNPATH)/bin/callgraph.py
$(OPENMRNPATH)/bin/callgraph.py --max_indep 6 --min_size $(CGMINSIZE) $(CGARGS) --map $(EXECUTABLE).map < $(EXECUTABLE).ndlst 2> cg.debug.txt | tee cg.dot | dot -Tsvg > cg.svg

incstatsprep:
make -j3 clean
$(MAKE) -j9 -k COMPILEOPT=-E || true

incstats: incstatsprep
$(MAKE) cincstats

cincstats:
@find . -name "*.o" | xargs cat | wc -l
@find . -name "*.o" | xargs -L 1 parse-gcc-e.awk | sort -k 2 | group.awk | sort -n > /tmp/stats.txt

-include $(OBJS:.o=.d)
-include $(TESTOBJS:.o=.d)

Expand Down
5 changes: 3 additions & 2 deletions src/openlcb/ConfigEntry.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@
#ifndef _OPENLCB_CONFIGENTRY_HXX_
#define _OPENLCB_CONFIGENTRY_HXX_

#include <sys/types.h>
#include <stdint.h>
#include <endian.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

#include <functional>

Expand Down
2 changes: 1 addition & 1 deletion src/openlcb/ConfigRenderer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#include <climits>
#include <string>

#include "openlcb/SimpleNodeInfo.hxx"
#include "openlcb/SimpleNodeInfoDefs.hxx"
#include "utils/OptionalArgs.hxx"
#include "utils/StringPrintf.hxx"

Expand Down
2 changes: 1 addition & 1 deletion src/openlcb/ConfigRepresentation.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#define _OPENLCB_CONFIGREPRESENTATION_HXX_

#include "openlcb/ConfigEntry.hxx"
#include "openlcb/MemoryConfig.hxx"
#include "openlcb/MemoryConfigDefs.hxx"

namespace openlcb
{
Expand Down
133 changes: 133 additions & 0 deletions src/openlcb/Convert.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/** \copyright
* Copyright (c) 2021, Balazs Racz
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
*
* \file Convert.hxx
*
* Conversion routines for OpenLCB types.
*
* @author Balazs Racz
* @date 17 Aug 2021
*/

#ifndef _OPENLCB_CONVERT_HXX_
#define _OPENLCB_CONVERT_HXX_

#include <endian.h>
#include <string.h>

#include "openlcb/Defs.hxx"

namespace openlcb
{

/** Convenience function to render a 48-bit NMRAnet node ID into a new buffer.
*
* @param id is the 48-bit ID to render.
* @returns a new buffer (from the main pool) with 6 bytes of used space, a
* big-endian representation of the node ID.
*/
extern string node_id_to_buffer(NodeID id);
/** Convenience function to render a 48-bit NMRAnet node ID into an existing
* buffer.
*
* @param id is the 48-bit ID to render.
* @param data is the memory space to write the rendered ID into. There must be
* at least 6 bytes available at this address.
*/
extern void node_id_to_data(NodeID id, void *data);

/** Converts a 6-byte-long buffer to a node ID.
*
* @param buf is a buffer that has to have exactly 6 bytes used, filled with a
* big-endian node id.
* @returns the node id (in host endian).
*/
extern NodeID buffer_to_node_id(const string &buf);
/** Converts 6 bytes of big-endian data to a node ID.
*
* @param d is a pointer to at least 6 valid bytes.
* @returns the node ID represented by the first 6 bytes of d.
*/
extern NodeID data_to_node_id(const void *d);

/** Converts an Event ID to a Payload suitable to be sent as an event report. */
extern Payload eventid_to_buffer(uint64_t eventid);

/** Takes 8 bytes (big-endian) from *data, and returns the event id they
* represent. */
inline uint64_t data_to_eventid(const void *data)
{
uint64_t ret = 0;
memcpy(&ret, data, 8);
return be64toh(ret);
}

/** Formats a payload for response of error response messages such as OPtioanl
* Interaction Rejected or Terminate Due To Error. */
extern string error_to_buffer(uint16_t error_code, uint16_t mti);

/** Formats a payload for response of error response messages such as Datagram
* Rejected. */
extern string error_to_buffer(uint16_t error_code);

/** Writes an error code into a payload object at a given pointer. */
extern void error_to_data(uint16_t error_code, void *data);

/** Parses an error code from a payload object at a given pointer. */
extern uint16_t data_to_error(const void *data);

/** Appends an error to the end of an existing buffer. */
extern void append_error_to_buffer(uint16_t error_code, Payload *p);

/** Parses the payload of an Optional Interaction Rejected or Terminate Due To
* Error message.
* @param payload is the contents of the incoming addressed message.
* @param error_code will hold the 2-byte error code, or ERROR_PERMANENT if not
* specified
* @param mti will hold the MTI value, or 0 if not specified
* @param error_message will hold all remaining bytes that came with the error
* message.
*/
extern void buffer_to_error(const Payload &payload, uint16_t *error_code,
uint16_t *mti, string *error_message);

/** A global class / variable for empty or not-yet-initialized payloads. */
extern string EMPTY_PAYLOAD;

/// @return the high 4 bytes of a node ID. @param id is the node ID.
inline unsigned node_high(NodeID id)
{
return id >> 32;
}
/// @return the low 4 bytes of a node ID. @param id is the node ID.
inline unsigned node_low(NodeID id)
{
return id & 0xffffffffU;
}

} // namespace openlcb

#endif
3 changes: 3 additions & 0 deletions src/openlcb/Defs.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ typedef uint64_t NodeID;
/** Alias to a 48-bit NMRAnet Node ID type */
typedef uint16_t NodeAlias;

/// Container that carries the data bytes in an NMRAnet message.
typedef string Payload;

/// Guard value put into the the internal node alias maps when a node ID could
/// not be translated to a valid alias.
static const NodeAlias NOT_RESPONDING = 0xF000;
Expand Down
93 changes: 5 additions & 88 deletions src/openlcb/If.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -38,104 +38,21 @@
/// @todo(balazs.racz) remove this dep
#include <string>

#include "openlcb/Node.hxx"
#include "openlcb/Defs.hxx"
#include "executor/Dispatcher.hxx"
#include "executor/Service.hxx"
#include "executor/Executor.hxx"
#include "executor/Service.hxx"
#include "openlcb/Convert.hxx"
#include "openlcb/Defs.hxx"
#include "openlcb/Node.hxx"
#include "utils/Buffer.hxx"
#include "utils/Queue.hxx"
#include "utils/Map.hxx"
#include "utils/Queue.hxx"

namespace openlcb
{

class Node;

/// Container that carries the data bytes in an NMRAnet message.
typedef string Payload;

/** Convenience function to render a 48-bit NMRAnet node ID into a new buffer.
*
* @param id is the 48-bit ID to render.
* @returns a new buffer (from the main pool) with 6 bytes of used space, a
* big-endian representation of the node ID.
*/
extern string node_id_to_buffer(NodeID id);
/** Convenience function to render a 48-bit NMRAnet node ID into an existing
* buffer.
*
* @param id is the 48-bit ID to render.
* @param data is the memory space to write the rendered ID into. There must be
* at least 6 bytes available at this address.
*/
extern void node_id_to_data(NodeID id, void* data);

/** Converts a 6-byte-long buffer to a node ID.
*
* @param buf is a buffer that has to have exactly 6 bytes used, filled with a
* big-endian node id.
* @returns the node id (in host endian).
*/
extern NodeID buffer_to_node_id(const string& buf);
/** Converts 6 bytes of big-endian data to a node ID.
*
* @param d is a pointer to at least 6 valid bytes.
* @returns the node ID represented by the first 6 bytes of d.
*/
extern NodeID data_to_node_id(const void* d);

/** Converts an Event ID to a Payload suitable to be sent as an event report. */
extern Payload eventid_to_buffer(uint64_t eventid);

/** Takes 8 bytes (big-endian) from *data, and returns the event id they
* represent. */
inline uint64_t data_to_eventid(const void* data) {
uint64_t ret = 0;
memcpy(&ret, data, 8);
return be64toh(ret);
}

/** Formats a payload for response of error response messages such as OPtioanl
* Interaction Rejected or Terminate Due To Error. */
extern string error_to_buffer(uint16_t error_code, uint16_t mti);

/** Formats a payload for response of error response messages such as Datagram
* Rejected. */
extern string error_to_buffer(uint16_t error_code);

/** Writes an error code into a payload object at a given pointer. */
extern void error_to_data(uint16_t error_code, void* data);

/** Parses an error code from a payload object at a given pointer. */
extern uint16_t data_to_error(const void *data);

/** Appends an error to the end of an existing buffer. */
extern void append_error_to_buffer(uint16_t error_code, Payload* p);

/** Parses the payload of an Optional Interaction Rejected or Terminate Due To
* Error message.
* @param payload is the contents of the incoming addressed message.
* @param error_code will hold the 2-byte error code, or ERROR_PERMANENT if not
* specified
* @param mti will hold the MTI value, or 0 if not specified
* @param error_message will hold all remaining bytes that came with the error
* message.
*/
extern void buffer_to_error(const Payload& payload, uint16_t* error_code, uint16_t* mti, string* error_message);

/** A global class / variable for empty or not-yet-initialized payloads. */
extern string EMPTY_PAYLOAD;

/// @return the high 4 bytes of a node ID. @param id is the node ID.
inline unsigned node_high(NodeID id) {
return id >> 32;
}
/// @return the low 4 bytes of a node ID. @param id is the node ID.
inline unsigned node_low(NodeID id) {
return id & 0xffffffffU;
}

/// Helper function to send an event report to the bus. Performs
/// synchronous (dynamic) memory allocation so use it sparingly and when
/// there is sufficient amount of RAM available.
Expand Down
Loading

0 comments on commit 43bfc88

Please sign in to comment.