-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharray_lock.c
103 lines (96 loc) · 2.37 KB
/
array_lock.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#include <assert.h>
#define N (10000000)
int idx=1,x=0,y=0;
unsigned char *lock;
int num_threads;
int FetchAndInc(int oldVal, int newVal, int *ptr)
{
int oldValOut;
unsigned char result;
asm("lock cmpxchgl %4, %1 \n setzb %0"
:"=qm"(result), "+m" (*ptr), "=a" (oldValOut)
:"a" (oldVal), "r" (newVal)
: );
if(!result)
return result;
else
return oldVal;
}
int acquire(int *idx)
{
int curr;
do
{
// asm("mfence":::"memory");
curr = FetchAndInc(*idx,(*(idx)+64)%(64*num_threads),idx);
// asm("mfence":::"memory");
} while (!curr);
while(lock[curr]);
// printf("Acquire ID : %d\n",curr);
return curr;
}
void release(int curr)
{
// asm("mfence":::"memory");
lock[curr] = 1;
asm("mfence":::"memory");
// printf("Release ID : %d\n",curr);
lock[(curr+64)%(64*num_threads)] = 0;
asm("mfence":::"memory");
}
void *critical(void* param)
{
int i, id = *(int *)param;
int curr;
for(int i=0;i<N;i++)
{
curr = acquire(&idx);
// assert(x==y);
x = y+1;
y++;
release(curr);
}
}
int main(int argc, char* argv[])
{
int i,*id;
pthread_t *tid;
pthread_attr_t attr;
struct timeval tv0, tv1;
struct timezone tz0, tz1;
if(argc!=2)
{
printf("Need no. of threads");
exit(1);
}
num_threads = atoi(argv[1]);
id = (int*)malloc(num_threads*sizeof(int));
tid = (pthread_t*)malloc(num_threads*sizeof(pthread_t));
lock = (unsigned char*)malloc((num_threads+1)*64*sizeof(unsigned char));
for (i=0; i<num_threads; i++)
id[i] = i;
for(i=0;i<64*num_threads;i=i+16)
{
lock[i+1] = 1;
}
lock[idx] = 0;
gettimeofday(&tv0, &tz0);
pthread_attr_init(&attr);
for (i=0; i<num_threads; i++) {
pthread_create(&tid[i], &attr, critical, &id[i]);
}
for (i=0; i<num_threads; i++) {
pthread_join(tid[i], NULL);
}
gettimeofday(&tv1, &tz1);
// assert(x==y);
// assert(x==N*num_threads);
// printf("x:%d y%d\n",x,y);
printf("X: %d, Y: %d \ntime: %ld microseconds\n", x, y, (tv1.tv_sec-tv0.tv_sec)*1000000+(tv1.tv_usec-tv0.tv_usec));
// printf(" %lu bytes", sizeof(unsigned char));
return 0;
}