Skip to content

Commit

Permalink
Merge pull request #5 from BluEye-Robotics/jp-pino/performance
Browse files Browse the repository at this point in the history
Reduce copies when reading repeated values
  • Loading branch information
jp-pino authored Nov 20, 2024
2 parents 4a526ec + adafceb commit 0a77a39
Show file tree
Hide file tree
Showing 42 changed files with 1,321 additions and 1,473 deletions.
97 changes: 47 additions & 50 deletions examples/ipc/god.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <unistd.h>

#include <tyndall/ipc/ipc.h>
#define debug_stdout stdout
Expand All @@ -11,59 +11,63 @@

#define len(array) (int)(sizeof(array) / sizeof(array[0]))

typedef struct
{
const char * const name;
int respawn; // respawn on error: -1 = infinite , 0 = never, 1 = once, 2 = twice, etc.
typedef struct {
const char *const name;
int respawn; // respawn on error: -1 = infinite , 0 = never, 1 = once, 2 =
// twice, etc.

// internal
// internal
pid_t pid;
int alive;
char* args[10]; // increase as needed
char *args[10]; // increase as needed

} child;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wwrite-strings" // ref https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94554

child children[] =
{
//==================== FILL IN PROCESSES ====================
{
.name = "/usr/bin/tyndall_ex_ipc_writer",
.respawn = -1,
},
{
.name = "/usr/bin/tyndall_ex_ipc_reader",
.args = { "--my_option", "--my_other_option", },
},
//===========================================================
#pragma GCC diagnostic ignored \
"-Wwrite-strings" // ref https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94554

child children[] = {
//==================== FILL IN PROCESSES ====================
{
.name = "/usr/bin/tyndall_ex_ipc_writer",
.respawn = -1,
},
{
.name = "/usr/bin/tyndall_ex_ipc_reader",
.args =
{
"--my_option",
"--my_other_option",
},
},
//===========================================================
};
#define n_children len(children)

#pragma GCC diagnostic pop

//==================== STATUSES THAT BYPASS RESPAWN =========
// Children that are configured to respawn will not be respawned if they return with these statuses:
int respawn_bypass_statuses[] = { 0, SIGINT };
// Children that are configured to respawn will not be respawned if they return
// with these statuses:
int respawn_bypass_statuses[] = {0, SIGINT};
//===========================================================

int fork_child(child *c)
{
int fork_child(child *c) {
pid_t pid = fork();

debug_assert(pid != -1, return 1);

if (pid == 0)
{
debug("child %u (%s) was spawned by parent %u\n", getpid(), c->name, getppid());
if (pid == 0) {
debug("child %u (%s) was spawned by parent %u\n", getpid(), c->name,
getppid());

setpgid(0, 0); // switch process group so ctrl-c only interrupts god

char * child_argv[len(c->args) + 2];
child_argv[0] = (char*)(c->name);
for (int i=0; i < len(c->args); ++i)
child_argv[i+1] = c->args[i];
char *child_argv[len(c->args) + 2];
child_argv[0] = (char *)(c->name);
for (int i = 0; i < len(c->args); ++i)
child_argv[i + 1] = c->args[i];
child_argv[len(c->args) + 1] = NULL;

int rc = execv(c->name, child_argv);
Expand All @@ -77,16 +81,13 @@ int fork_child(child *c)
return 0;
}

void exit_handler(int sig)
{
void exit_handler(int sig) {
debug("got signal %d\n", sig);

// kill the children manually, since they're in a different group
signal(SIGCHLD, SIG_IGN);
for (int i=0; i < n_children; ++i)
{
if (children[i].alive)
{
for (int i = 0; i < n_children; ++i) {
if (children[i].alive) {
debug("killing %u (%s)\n", children[i].pid, children[i].name);
debug_assert(kill(children[i].pid, sig) == 0);
}
Expand All @@ -99,8 +100,7 @@ void exit_handler(int sig)
exit(sig);
}

void child_handler(int sig)
{
void child_handler(int sig) {
pid_t pid = -1;
int status;

Expand All @@ -118,17 +118,15 @@ void child_handler(int sig)
c->alive = 0;
debug("child %u (%s) exited with status %d\n", c->pid, c->name, status);

if ((c->respawn != 0))
{
if ((c->respawn != 0)) {
int bypass_statuses = 0;
for (int i=0; i < len(respawn_bypass_statuses); ++i)
for (int i = 0; i < len(respawn_bypass_statuses); ++i)
if (status == respawn_bypass_statuses[i])
++bypass_statuses;

if (bypass_statuses)
debug("respawn bypassed\n");
else
{
else {
debug("respawning child\n");
fork_child(c);

Expand All @@ -137,19 +135,18 @@ void child_handler(int sig)
}
}

int main()
{
int main() {
debug("starting %u (god process)\n", getpid());

for (int i=0; i < n_children; ++i)
for (int i = 0; i < n_children; ++i)
fork_child(children + i);

debug("%u (god process) finished spawning threads\n", getpid());

signal(SIGINT, exit_handler);
signal(SIGCHLD, child_handler);

while(1)
while (1)
pause();

return 0;
Expand Down
18 changes: 9 additions & 9 deletions examples/ipc/my_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ typedef struct
} data[50];
} my_struct;
#define my_struct_print(print, s, ...) print("%d\t%d\t%d" __VA_ARGS__ , s.data[0].ii, s.data[0].iii, s.data[0].iiii)
#define my_struct_print(print, s, ...) print("%d\t%d\t%d" __VA_ARGS__ ,
s.data[0].ii, s.data[0].iii, s.data[0].iiii)
#define my_struct_inc(entry) \
do{ \
Expand All @@ -31,16 +32,15 @@ typedef struct
}while(0)
*/

typedef struct
{
typedef struct {
unsigned char i;
float j;
} my_struct;

#define my_struct_print(print, s, ...) print("%u %f" __VA_ARGS__ , s.i, s.j)
#define my_struct_print(print, s, ...) print("%u %f" __VA_ARGS__, s.i, s.j)

#define my_struct_inc(entry) \
do{ \
++(entry.i); \
++(entry.j); \
}while(0)
#define my_struct_inc(entry) \
do { \
++(entry.i); \
++(entry.j); \
} while (0)
19 changes: 5 additions & 14 deletions examples/ipc/reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,18 @@

int run = 1;

void sig_handler(int sig)
{
run = 0;
}

void sig_handler(int sig) { run = 0; }

int main()
{
int main() {
signal(SIGINT, sig_handler);


while (run)
{
while (run) {
my_struct entry;

if (ipc_read(entry, "/my/topic") == 0)
{
if (ipc_read(entry, "/my/topic") == 0) {
debug("new entry:\t");
my_struct_print(debug_plain, entry, "\n");
}
else
} else
debug_error("no entry\n");

usleep(3 * 1000);
Expand Down
12 changes: 3 additions & 9 deletions examples/ipc/writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,14 @@

int run = 1;

void sig_handler(int sig)
{
run = 0;
}

void sig_handler(int sig) { run = 0; }

int main()
{
int main() {
signal(SIGINT, sig_handler);

my_struct entry = {};

while (run)
{
while (run) {
ipc_write(entry, "/my/topic");

my_struct_inc(entry);
Expand Down
14 changes: 5 additions & 9 deletions examples/log/C.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
#define LOG_PRINTF
//#define LOG_FMT
// #define LOG_FMT
#include <tyndall/log/log.h>

#include <unistd.h>
#include <signal.h>
#include <unistd.h>

sig_atomic_t run = 1;

void cb_sig(int sig)
{
void cb_sig(int sig) {
log_info("got signal %d\n", sig);
run = 0;
}

int main()
{
int main() {
log_debug("hei %d\n", 3);

signal(SIGINT, cb_sig);


while(run)
{
while (run) {
log_debug("loopityloop\n");

log_once_error("loopityloop\n");
Expand Down
45 changes: 18 additions & 27 deletions examples/meta.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
#include <cstdio>
#include <tyndall/meta/iterate.h>
#include <tyndall/meta/strval.h>
#include <tyndall/meta/typevals.h>
#include <cstdio>
#include <typeinfo>

template<typename T>
struct tstruct
{
template <typename T> struct tstruct {
using Type = T;
T a;
};

int main()
{
int main() {
constexpr auto sv = "hei"_strval;
printf("strval: %s\n", sv.c_str());
printf("strval from type: %s\n", decltype(sv)::c_str());
printf("strval length: %d\n", (""_strval).length());
printf("strval sum: %s\n", ("hei"_strval + "du"_strval).c_str());
printf("occurrences: %d\n", ("hei din sei"_strval).occurrences('i'));
printf("replace: %s\n", ("hei din sei"_strval).replace<'i', 'y'>().c_str());
printf("remove_leading: %s\n", ("///hei din sei"_strval).remove_leading<'/'>().c_str());
printf("remove_leading: %s\n",
("///hei din sei"_strval).remove_leading<'/'>().c_str());
printf("to_strval: %s\n", to_strval<42>::c_str());

{
printf("typevals:\n");
{
struct A{int a; float b;};
struct B{int a; float b;};
static constexpr auto col =
typevals{}
+ 5
+ A{4,2}
+ B{3,9}
;
struct A {
int a;
float b;
};
struct B {
int a;
float b;
};
static constexpr auto col = typevals{} + 5 + A{4, 2} + B{3, 9};
printf("col size: %d\n", col.size());

constexpr auto res = col.get<2>();
Expand All @@ -43,26 +42,18 @@ int main()
}

{
static constexpr auto c =
typevals{}
+ tstruct<int>{5}
;
static constexpr auto c = typevals{} + tstruct<int>{5};
constexpr auto res = c.get<0>();
printf("c res: %s\n", typeid(res).name());
decltype(res)::Type t;
(void)sizeof(t);
}

{
static constexpr auto c =
typevals{}
+ tstruct<int>{-5}
+ tstruct<float>{3}
+ tstruct<unsigned>{8}
;
static constexpr auto c = typevals{} + tstruct<int>{-5} +
tstruct<float>{3} + tstruct<unsigned>{8};

iterate<c.size()>
([](auto index){
iterate<c.size()>([](auto index) {
printf("iteration %d: %s\n", index(), typeid(index).name());
});
}
Expand Down
Loading

0 comments on commit 0a77a39

Please sign in to comment.