Updating variable every x minutes - c

I have a small program, which uses glib.
You can see it in codereview. The title is "Reading messages. What can be done better?".
I have a endless while loop in a main method.
In this loop I have a GTree.
int main()
{
//some setup/mallocs
GTree* t = g_tree_new_full((GCompareDataFunc)g_ascii_strcasecmp,NULL,free_data,free_data);
while (1) {
//some tasks; accessing tree
}
//some free
}
Tree is accessed inside this loop.
I wish to update this tree every x minutes(for example every 15 minutes).
Is it possible? How can I do it and avoid collisions?

Instead of doing while (1) { ... } in your code, use GLib's main event loop. Beyond making this a lot easier, it will also allow you to integrate with other main loop based code, such as GTK+, the asynchronous functions in GIO and other libraries.
gboolean every_15_minutes (gpointer user_data) {
/* some tasks; accessing tree */
}
int main (void) {
GMainLoop* loop = g_main_loop_new (NULL, FALSE);
/* some setup/mallocs */
GTree* t = g_tree_new_full((GCompareDataFunc)g_ascii_strcasecmp,NULL,free_data,free_data);
g_timeout_add_seconds (60 * 15, every_15_minutes, NULL);
g_main_loop_run (loop);
/* some free */
}
As for avoiding collisions, you could do a g_tree_lookup to verify there aren't any existing entries with that key before a g_tree_insert, or just do a g_tree_replace which will discard the old value if there is a collision.

Related

FreeRTOS: xEventGroupWaitBits() crashes inside a loop with scheduler running

We have several tasks running on an STM32 MCU. In the main.c file we call all the init functions for the various threads. Currently there is one renewing xTimer to trigger a periodic callback (which, at present, does nothing except print a message that it was called). Declarations as follows, outside any function:
TimerHandle_t xMotorTimer;
StaticTimer_t xMotorTimerBuffer;
EventGroupHandle_t MotorEventGroupHandle;
In the init function for the thread:
xMotorTimer = xTimerCreateStatic("MotorTimer",
xTimerPeriod,
uxAutoReload,
( void * ) 0,
MotorTimerCallback,
&xMotorTimerBuffer);
xTimerStart(xMotorTimer, 100);
One thread starts an infinite loop that pauses on an xEventGroupWaitBits() to determine whether to enter an inner loop, which is then governed by its own state:
DeclareTask(MotorThread)
{
bool done = false;
EventBits_t event;
for (;;)
{
Packet * pkt = NULL;
event = xEventGroupWaitBits( MotorEventGroupHandle,
EVT_MOTOR_START | EVT_MOTOR_STOP, // EventBits_t uxBitsToWaitFor
pdTRUE, // BaseType_t xClearOnExit
pdFALSE, // BaseType_t xWaitForAllBits,
portMAX_DELAY //TickType_t xTicksToWait
);
if (event & EVT_MOTOR_STOP)
{
MotorStop(true);
}
if (event & EVT_MOTOR_START)
{
EnableMotor(MOTOR_ALL);
done = false;
while (!done && !abortTest)
{
xQueueReceive(motorQueue, &pkt, portMAX_DELAY);
if (pkt == NULL)
{
done = true;
} else {
done = MotorExecCmd(pkt);
done = ( uxQueueMessagesWaiting(motorQueue) == ( UBaseType_t ) 0);
FreePacket(pkt);
}
}
}
}
}
xEventGroupWaitBits() fires successfully once, the inner loop enters, then exits when the program state meets the expected conditions. The outer loop repeats as it should, but when it arrives again at the xEventGroupWaitBits() call, it crashes almost instantly. In fact, it crashes a few lines down into the wait function, at a call to uxTaskResetEventItemValue(). I can't even step the debugger into the function, as if calling a bad address. But if I check the disassembly, the memory address for the BL instruction hasn't changed since the previous loop, and that address is valid. The expected function is actually there.
I can prevent this chain of events happening altogether by not calling that xTimerStart() and leaving everything else as-is. Everything runs just fine, so it's definitely not xEventGroupWaitBits() (or at least not just that). We tried switching to xEventGroupGetBits() and adding a short osDelay to the loop just as an experiment. That also froze the whole system.
So, main question. Are we doing something FreeRTOS is not meant to do here, using xEventGroupWaitBits() with xTimers running? Or is there supposed to be something between xEventGroupWaitBits() calls, possibly some kind of state reset that we've overlooked? Reviewing the docs, I can't see it, but I could have missed a detail. The

proper way to create multiple forked threads

I'm creating a timer function for a bit of embedded code that will allow me to bypass certain GPIO checks while a certain process is running, i.e., when the timer is running in a non-blocking manner.
This seems to run just fine the first 11 times the operations occur, but every time, on the 11th iteration the system will crash. The likely culprit is something in how the timer thread is being handled. My guess is there's some bit of memory cleanup that I'm not handling properly and that's leading to memory leaks of some kind. But I'm really not sure.
I can see through debug tracing that the thread is exiting after each iteration.
Here is the timer code:
#include <time.h>
#include <semaphore.h>
#include <pthread.h>
#include <msp432e4_timer.h>
extern void TaskSleep(uint32_t delay);
static bool timerActive;
static sem_t timerSem;
pthread_t timerThread;
pthread_attr_t attrs;
struct sched_param priParam;
static void *msp432e4_timer(void *argUnused) {
sem_wait(&timerSem);
timerActive = true;
sem_post(&timerSem);
TaskSleep(40);
sem_wait(&timerSem);
timerActive = false;
sem_post(&timerSem);
return (NULL);
}
void initTimer() {
int retc;
pthread_attr_init(&attrs);
priParam.sched_priority = 1;
retc = pthread_attr_setschedparam(&attrs, &priParam);
retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
retc |= pthread_attr_setstacksize(&attrs, 1024);
if (retc != 0) {
// failed to set attributes
while (1) {}
}
timerActive = false;
if((sem_init(&timerSem, 0, 0)) != 0) {
while(1);
}
sem_post(&timerSem);
}
/*
* return true on starting a new timer
* false implies timer already active
*/
void timerStart() {
int retc;
retc = pthread_create(&timerThread, &attrs, msp432e4_timer, NULL);
if (retc != 0) {
// pthread_create() failed
while (1) {}
}
}
/* return true if timer active */
bool timerCheck() {
bool retval;
sem_wait(&timerSem);
retval = timerActive;
sem_post(&timerSem);
return(retval);
}
The TaskSleep function is a call to a freeRTOS TaskDelay function. It's used in many points throughout the system and has never been an issue.
Hopefully someone can point me in the right direction.
But you didn't really post enough of your code to determine where the problems might be, but I thought this might be worth mentioning:
A general problem is that the sample code you have is open loop wrt thread creation; that is there is nothing to throttle it, and if your implementation has a particularly slow thread exit handling, you could have many zombie threads lying around that haven't died yet.
In typical embedded / real time systems, you want to move resource allocation out of the main loop, since it is often non deterministic. So, more often you would create a timer thread, and park it until it is needed:
void *TimerThread(void *arg) {
while (sem_wait(&request) == 0) {
msp432e4_timer(void *arg);
}
return 0
}
void TimerStart(void) {
sem_post(&request);
}

GtkSpinner with long-lasting function with C

I'm making a GTK+3 application in C and I want a spinner to show when the program is processing the data. Here's what I generally have:
main()
{
//Some statements
g_signal_connect(G_OBJECT(btnGenerate), "clicked", G_CALLBACK(Generate), &mainform);
}
void Generate(GtkWidget *btnGenerate, form_widgets *p_main_form)
{
gtk_spinner_start(GTK_SPINNER(p_main_form->spnProcessing));
Begin_Lengthy_Processing(Parameters, Galore, ...);
//gtk_spinner_stop(GTK_SPINNER(p_main_form->spnProcessing));
}
I have the stop function commented out so I can see the spinner spin even after the function has finished, but the spinner starts after the function is finished, and I suspect it turns on in the main loop.
I also found out that the entire interface freezes during the execution of the long going function.
Is there a way to get it to start and display inside the callback function? I found the same question, but it uses Python and threads. This is C, not Python, so I would assume things are different.
You need to run your lengthy computation in a separate thread, or break it up into chunks and run each of them separately as idle callbacks in the main thread.
If your lengthy computation takes a single set of inputs and doesn’t need any more inputs until it’s finished, then you should construct it as a GTask and use g_task_run_in_thread() to start the task. Its result will be delivered back to the main thread via the GTask’s GAsyncReadyCallback. There’s an example here.
If it takes more input as it progresses, you probably want to use a GAsyncQueue to feed it more inputs, and a GThreadPool to provide the threads (amortising the cost of creating threads over multiple calls to the lengthy function, and protecting against denial of service).
The GNOME developer docs give an overview of how to do threading.
This is what I got:
int main()
{
// Statements...
g_signal_connect(G_OBJECT(btnGenerate), "clicked", G_CALLBACK(Process), &mainform);
// More statements...
}
void Process(GtkWidget *btnGenerate, form_widgets *p_main_form)
{
GError *processing_error;
GThread *start_processing;
gtk_spinner_start(GTK_SPINNER(p_main_form->spnProcessing));
active = true;
if((start_processing = g_thread_try_new(NULL, (GThreadFunc)Generate, p_main_form, &processing_error)) == NULL)
{
printf("%s\n", processing_error->message);
printf("Error, cannot create thread!?!?\n\n");
exit(processing_error->code);
}
}
void Generate(form_widgets *p_main_form)
{
// Long process
active = false;
}
My program, once cleaned up and finished, as there are many other bugs in the program, will be put on GitHub.
Thank you all for your help. This answer comes from looking at all of your answers and comments as well as reading some more documentation, but mostly your comments and answers.
I did something similar in my gtk3 program. It's not that difficult. Here's how I would go about it.
/**
g_idle_add_full() expects a pointer to a function with the signature below:
(*GSourceFunc) (gpointer user_data).
So your function signature must adhere to that in order to be called.
But you might want to pass variables to the function.
If you don't want to have the variables in the global scope
then you can do this:
typedef struct myDataType {
char* name;
int age;
} myDataType;
myDataType person = {"Max", 25};
then when calling g_idle_add_full() you do it this way:
g_idle_add_full(G_PRIORITY_HIGH_IDLE, myFunction, person, NULL);
*/
int main()
{
// Assumming there exist a pointer called data
g_idle_add_full(G_PRIORITY_HIGH_IDLE, lengthyProcessCallBack, data, NULL);
// GTK & GDK event loop continues and window should be responsive while function runs in background
}
gboolean lengthyProcessCallBack(gpointer data)
{
myDataType person = (myDataType) *data;
// Doing lenghthy stuff
while(;;) {
sleep(3600); // hypothetical long process :D
}
return FALSE; // removed from event sources and won't be called again.
}

RTOS MicroC tasking

I've been working on some RTOS MicroC project and whenever I've implemented some function it works just fine outside the task, but whenever I put in the task it just wouldn't do anything. I know I might not get answer to this, but any tips where to start looking would be a big help, thanks in advance.
a_sem = OSSemCreate(1);
static void AppTask1(void *p_arg)
{
(void) p_arg;
INT8U perr;
while (1)
{
OSSemPend(a_sem, 0, &perr);
planeAngles();// Functon that works outside the task
OSSemPost(a_sem);
OSTimeDly(OS_TICKS_PER_SEC/20);
}
}
static void AppTask2(void *p_arg)
{
(void) p_arg;
INT8U perr;
while (1)
{
OSSemPend(a_sem, 0, &perr);
servoTurns(); // Functon that works outside the task
OSSemPost(a_sem);
OSTimeDly(OS_TICKS_PER_SEC/20);
}
}
Both tasks wait on a semaphore, but it is not clear where that semaphore is initially given. It seems likely that neither task ever returns from the OSSemPend call.
Somewhere in your code, before AppTask1 and AppTask2 are created, you should have a line of code like this:
OSSemCreate(a_sem, 1, &perr);
You are creating a semaphore, a_sem with an initial value of 1 so that the first task that calls OSSemPend will successfully acquire the semaphore.
Also, you should not block forever on OSSemPend. Wait for awhile and then check the error status:
OSSemPend(a_sem, 10, &perr);
if(perr == OS_ERR_NONE)
{
/* You have the semaphore */
}
else
{
/* Error! Maybe a timeout */
}

Running multiple concurrent GMainLoops

Are users of GLib allowed to run multiple GMainLoop instances concurrently in multiple threads, with each thread running its own instance? I've found "yes" and "no" answers all over the place. I realize that this question has been asked before in this very forum (December 2011).
However, I am able to run two GMainLoop instances at the same time without apparent issue. My test code is very simple:
Create a GMainLoop in main()
Create a timeout source for the default context and the main loop using g_timeout_add
Create a GThread in main()
Run the main loop using g_main_loop_run
[THREAD CONTEXT]: Create a context using g_main_context_new
[THREAD CONTEXT]: Set that context as the thread default using g_main_context_push_thread_default
[THREAD CONTEXT]: Create a loop using g_main_loop_new and give it the new context
[THREAD CONTEXT]: Create a timeout source, and attach it to the new context via g_source_attach.
[THREAD_CONTEXT]: Have the thread invoke g_main_loop_run
Doing this, I see both instances of the GMainLoop working just fine. The timeout callbacks are invoked correctly, and later calls to g_main_loop_quit work as expected.
So, it looks like it is not a problem to have multiple GMainLoop instances working concurrently. But perhaps I just haven't exercised the API enough to fully grasp the situation. Is there a definitive answer to this question?
Also, here's the actual test code if anybody cares to look:
#define THREAD_TIMEOUTS (20)
#define MAIN_TIMEOUS (1)
typedef struct timeout_struct
{
int i;
int max;
GMainLoop *loop;
char *name;
} TIMEOUT_STRUCT;
gboolean timeout_callback(gpointer data)
{
TIMEOUT_STRUCT *psTimeout = (TIMEOUT_STRUCT *)data;
psTimeout->i++;
if (psTimeout->i == psTimeout->max)
{
if (psTimeout->max == THREAD_TIMEOUTS)
{
g_main_loop_quit( (GMainLoop*)psTimeout->loop );
}
return FALSE;
}
return TRUE;
}
void* thread_function(void *data)
{
GMainContext *ps_context;
GMainLoop *ps_loop;
GSource *ps_timer;
TIMEOUT_STRUCT sTimeout;
ps_context = g_main_context_new();
g_main_context_push_thread_default(ps_context);
ps_loop = g_main_loop_new(ps_context, FALSE);
sTimeout.i = 0;
sTimeout.max = THREAD_TIMEOUTS;
sTimeout.loop = ps_loop;
sTimeout.name = "thread";
ps_timer = g_timeout_source_new_seconds(1);
g_source_set_callback(ps_timer, timeout_callback, &sTimeout, NULL);
g_source_attach(ps_timer, ps_context);
g_main_loop_run(ps_loop);
g_main_loop_quit( (GMainLoop*)data );
return NULL;
}
/*
* This main boots a thread, then starts up a GMainLoop. Then the thread runs
* a GMainLoop. The thread sets a timer that fires ten times and the main sets a
* timer that fires two times. The thread quits and
* and then the other main l
*
*
* */
int main()
{
GThread *ps_thread;
GMainLoop *loop;
TIMEOUT_STRUCT sTimeout;
loop = g_main_loop_new ( NULL , FALSE );
sTimeout.i = 0;
sTimeout.max = MAIN_TIMEOUS;
sTimeout.loop = loop;
sTimeout.name = "main";
// add source to default context
g_timeout_add (1 , timeout_callback, &sTimeout);
ps_thread = g_thread_new("thread", thread_function, loop);
g_main_loop_run (loop);
g_main_loop_unref(loop);
}
The book "Foundations of GTK+ Development" states this:
The GLib main loop is implemented as a number of structures, which allow multiple instances
to be run concurrently.
So, given this, my test code, and the link I posted in the comment above we have a definitive answer to this question.
Namely: Multiple threads may have their own GMainContext & GMainLoop, and are able to independently run these loops in a concurrent fashion.

Resources