Skip to content

Instantly share code, notes, and snippets.

@TheCodeArtist
Created July 25, 2013 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheCodeArtist/6082246 to your computer and use it in GitHub Desktop.
Save TheCodeArtist/6082246 to your computer and use it in GitHub Desktop.
Define and test custom atomic structure and functions in the absence of gcc intrinsics. atomic_t, atomic_set(), atomic_read(), atomic_inc().
/* atomic-test.c
*
* Compiled using "gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
* Compiler cmd : `gcc atomic-test.c -lpthread -o atomic-test`
*
* objdump -S shows that the lock prefix in properly inserted
*
* 08048674 <atomic_inc>:
* 8048674: 55 push %ebp
* 8048675: 89 e5 mov %esp,%ebp
* 8048677: 8b 45 08 mov 0x8(%ebp),%eax
* 804867a: 8b 55 08 mov 0x8(%ebp),%edx
* 804867d: f0 ff 00 lock incl (%eax)
* 8048680: 5d pop %ebp
* 8048681: c3 ret
*
* Multiple runs on an Intel Core2 - 4cores
* Result : "atomic_count:300000" (as expected)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <pthread.h>
/* atomics */
typedef struct {
volatile int counter;
} atomic_t;
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic_read(v) ((v)->counter)
static inline void atomic_inc(atomic_t *v)
{
asm volatile( "lock incl %0"
: "+m" (v->counter));
}
/* globals */
#define THRD_NUM 15
static atomic_t atomic_count;
static pthread_cond_t g_cond;
static pthread_mutex_t g_mutex;
void* thread_func(void*p) {
pthread_mutex_t* lock = (pthread_mutex_t*)p;
pthread_mutex_lock(lock);
pthread_cond_wait(&g_cond, lock);
pthread_mutex_unlock(lock);
int i;
for (i=0;i<20000;++i){
atomic_inc(&atomic_count);
}
return NULL;
}
int main() {
atomic_set(&atomic_count, 0);
pthread_cond_init(&g_cond, NULL);
pthread_mutex_init(&g_mutex, NULL);
pthread_t pid[THRD_NUM];
int i;
for (i=0; i<THRD_NUM; i++) {
pthread_create(&pid[i], NULL, thread_func, &g_mutex);
}
sleep(3);
pthread_cond_broadcast(&g_cond);
for (i=0; i<THRD_NUM; i++) {
pthread_join(pid[i], NULL);
}
long ans = atomic_read(&atomic_count);
printf("atomic_count:%ld \n", ans);
}
@TheCodeArtist
Copy link
Author

Originally written to test http://stackoverflow.com/q/17861335/319204

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment