Skip to content

Commit 8d5767c

Browse files
author
Taylor Holberton
committed
Reducing library size by using custom buffer
1 parent 86c7d53 commit 8d5767c

File tree

4 files changed

+74
-25
lines changed

4 files changed

+74
-25
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project("tinyalsa-cxx" CXX)
44

55
option(TINYALSA_EXAMPLES "Whether or not to build the examples." OFF)
66

7-
set(common_warnings -Wall -Wextra -Werror -Wfatal-errors)
7+
set(common_cxxflags -Wall -Wextra -Werror -Wfatal-errors)
88

99
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
1010
set(tinyalsa_cxxflags ${common_warnings})
@@ -16,7 +16,7 @@ add_library("tinyalsa-cxx"
1616
"tinyalsa.hpp"
1717
"tinyalsa.cpp")
1818

19-
target_compile_options("tinyalsa-cxx" PRIVATE ${tinyalsa_cxxflags})
19+
target_compile_options("tinyalsa-cxx" PRIVATE ${tinyalsa_cxxflags} -fno-rtti -fno-exceptions)
2020

2121
target_include_directories("tinyalsa-cxx" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
2222

Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ CXXFLAGS := -Wall -Wextra -Werror -Wfatal-errors -I $(CURDIR)
55
ifdef TINYALSA_DEBUG
66
CXXFLAGS := $(CXXFLAGS) -g
77
else
8-
CXXFLAGS := $(CXXFLAGS) -Os -fno-rtti
8+
CXXFLAGS := $(CXXFLAGS) -Os -fno-rtti -fno-exceptions
99
endif
1010

1111
examples += examples/pcminfo
12+
examples += examples/pcmlist
1213

1314
.PHONY: all
1415
all: libtinyalsa-cxx.a
1516

1617
libtinyalsa-cxx.a: tinyalsa.o
1718
$(AR) $(ARFLAGS) $@ $^
1819

19-
tinyalsa.o: tinyalsa.cpp
20+
tinyalsa.o: tinyalsa.cpp tinyalsa.hpp
2021

2122
.PHONY: examples
2223
examples: $(examples)
@@ -25,9 +26,13 @@ examples/pcminfo: examples/pcminfo.o libtinyalsa-cxx.a
2526

2627
examples/pcminfo.o: examples/pcminfo.cpp tinyalsa.hpp
2728

29+
examples/pcmlist: examples/pcmlist.o libtinyalsa-cxx.a
30+
31+
examples/pcmlist.o: examples/pcmlist.cpp tinyalsa.hpp
32+
2833
examples/%: examples/%.o libtinyalsa-cxx.a
2934
$(CXX) $^ -o $@ libtinyalsa-cxx.a
3035

3136
.PHONY: clean
3237
clean:
33-
$(RM) tinyalsa.o libtinyalsa-cxx.a
38+
$(RM) tinyalsa.o libtinyalsa-cxx.a $(examples) examples/*.o

tinyalsa.cpp

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <algorithm>
44
#include <new>
55
#include <type_traits>
6-
#include <vector>
76

87
#include <dirent.h>
98
#include <errno.h>
@@ -25,14 +24,6 @@ namespace {
2524
/// The type used to identify hardware parameters.
2625
using parameter_name = int;
2726

28-
/// Indicates the number of elements
29-
/// in a mask. Not to be considered with
30-
/// the number of physical bits in the structure.
31-
inline constexpr size_type mask_bits_count()
32-
{
33-
return sizeof(snd_mask::bits) / sizeof(snd_mask::bits[0]);
34-
}
35-
3627
/// Represents an indexed mask parameter.
3728
///
3829
/// @tparam param The index of the mask parameter.
@@ -451,6 +442,61 @@ const char* get_error_description(int error) noexcept
451442
}
452443
}
453444

445+
//=====================//
446+
// Section: POD Buffer //
447+
//=====================//
448+
449+
/// A simple buffer for POD type data.
450+
///
451+
/// TODO : Check the impact of multiple instantiations
452+
/// on overall binary size.
453+
///
454+
/// @tparam element_type The type of the element
455+
/// stored in the buffer.
456+
template <typename element_type>
457+
struct pod_buffer final
458+
{
459+
/// The array of elements.
460+
element_type* data = nullptr;
461+
/// The number of elements in the buffer.
462+
size_type size = 0;
463+
/// Constructs an empty buffer.
464+
constexpr pod_buffer() noexcept : data(nullptr), size(0) {}
465+
/// Moves a buffer from one variable to another.
466+
///
467+
/// @param other The variable to be moved.
468+
inline constexpr pod_buffer(pod_buffer&& other) noexcept
469+
: data(other.data),
470+
size(other.size)
471+
{
472+
other.data = nullptr;
473+
other.size = 0;
474+
}
475+
/// Releases memory allocated by the buffer.
476+
~pod_buffer()
477+
{
478+
std::free(data);
479+
data = nullptr;
480+
size = 0;
481+
}
482+
/// Adds an element to the end of the buffer.
483+
///
484+
/// @param e The element to add to the end of the buffer.
485+
///
486+
/// @return True on success, false on failure.
487+
bool emplace_back(element_type&& e) noexcept
488+
{
489+
auto* tmp = (element_type*) std::realloc(data, (size + 1) * sizeof(element_type));
490+
if (!tmp) {
491+
return false;
492+
}
493+
data = tmp;
494+
size++;
495+
data[size - 1] = std::move(e);
496+
return true;
497+
}
498+
};
499+
454500
//=============================//
455501
// Section: Interleaved Reader //
456502
//=============================//
@@ -756,7 +802,7 @@ struct parsed_name final
756802
/// @param name The filename to be parsed.
757803
///
758804
/// @return True on a match, false on failure.
759-
constexpr bool parse(const char* name) noexcept;
805+
bool parse(const char* name) noexcept;
760806
/// Indicates if a character is a decimal number or not.
761807
///
762808
/// @return True if it is a decimal character, false otherwise.
@@ -775,7 +821,7 @@ struct parsed_name final
775821
}
776822
};
777823

778-
constexpr bool parsed_name::parse(const char* name) noexcept
824+
bool parsed_name::parse(const char* name) noexcept
779825
{
780826
auto name_length = strlen(name);
781827
if (!name_length) {
@@ -838,7 +884,7 @@ class pcm_list_impl final
838884
{
839885
friend pcm_list;
840886
/// The array of information instances.
841-
std::vector<pcm_info> info_vec;
887+
pod_buffer<pcm_info> info_buffer;
842888
};
843889

844890
pcm_list::pcm_list() noexcept : self(nullptr)
@@ -887,9 +933,7 @@ pcm_list::pcm_list() noexcept : self(nullptr)
887933
continue;
888934
}
889935

890-
try {
891-
self->info_vec.emplace_back(info_result.unwrap());
892-
} catch (...) {
936+
if (!self->info_buffer.emplace_back(info_result.unwrap())) {
893937
break;
894938
}
895939
}
@@ -907,12 +951,12 @@ pcm_list::~pcm_list()
907951

908952
const pcm_info* pcm_list::data() const noexcept
909953
{
910-
return self ? self->info_vec.data() : nullptr;
954+
return self ? self->info_buffer.data : nullptr;
911955
}
912956

913957
size_type pcm_list::size() const noexcept
914958
{
915-
return self ? self->info_vec.size() : 0;
959+
return self ? self->info_buffer.size : 0;
916960
}
917961

918962
} // namespace tinyalsa

tinyalsa.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class pcm
316316
///
317317
/// @return On success, zero is returned.
318318
/// On failure, a copy of errno is returned.
319-
virtual result prepare() noexcept;
319+
result prepare() noexcept;
320320
/// Starts the PCM. This can have different
321321
/// meanings depending on whether the PCM is
322322
/// a capture device or a playback device.
@@ -332,15 +332,15 @@ class pcm
332332
///
333333
/// @return On success, zero is returned.
334334
/// On failure, a copy of errno is returned.
335-
virtual result start() noexcept;
335+
result start() noexcept;
336336
/// Stops either the playback or capture loop
337337
/// of the audio device. Any buffered audio that
338338
/// exist at the point of calling this function
339339
/// is lost.
340340
///
341341
/// @return On success, zero is returned.
342342
/// On failure, a copy of errno is returned instead.
343-
virtual result drop() noexcept;
343+
result drop() noexcept;
344344
/// Opens a capture PCM.
345345
///
346346
/// @param card The index of the card to open the PCM from.

0 commit comments

Comments
 (0)