I would like to modify some elements of a structure atomically. My current implementation uses mutexes to protect the critical code, and can be seen below.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
#define ITER 100000
typedef struct global_status {
int32_t context_delta;
uint32_t global_access_count;
} global_status_t;
global_status_t g_status;
void *context0(void *ptr)
{
unsigned int iter = ITER;
while (iter--) {
wait_event_from_device0();
pthread_mutex_lock(&thread_mutex);
g_status.context_delta++;
g_status.global_access_count++;
pthread_mutex_unlock(&thread_mutex);
}
return NULL;
}
void *context1(void *ptr)
{
unsigned int iter = ITER;
while (iter--) {
wait_event_from_device1();
pthread_mutex_lock(&thread_mutex);
g_status.context_delta--;
g_status.global_access_count++;
pthread_mutex_unlock(&thread_mutex);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid0, tid1;
int iret;
if ((iret = pthread_create(&tid0, NULL, context0, NULL))) {
fprintf(stderr, "context0 creation error!\n");
return EXIT_FAILURE;
}
if ((iret = pthread_create(&tid1, NULL, context1, NULL))) {
fprintf(stderr, "context1 creation error!\n");
return EXIT_FAILURE;
}
pthread_join(tid0, NULL);
pthread_join(tid1, NULL);
printf("%d, %d\n", g_status.context_delta, g_status.global_access_count);
return 0;
}
I am planning to port this code into an RTOS which does not support posix, and I would like to do this operation atomically without using mutexes or disabling/enabling interrupts.
How can I do this operation? Is it possible by using 'atomic compare and swap function' (CAS)?
Seems like in your example you have two threads servicing to different devices. You maybe able to do away with locking completely using a per-device structure. The global will be the aggregate of all per-device statistics. If you do need locks you can use CAS, LL/SC or any supported underlying atomic construct.