Created
July 25, 2013 18:05
-
-
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().
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Originally written to test http://stackoverflow.com/q/17861335/319204