-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCASBuffer.cpp
106 lines (91 loc) · 2.03 KB
/
CASBuffer.cpp
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
104
105
106
#include "CASBuffer.h"
void CASBuffer::put(long val){
long i=0;
bool isFirst = true;
while(
InterlockedCompareExchange(&buf[write_pos],
val, BANK_IS_FREE) != BANK_IS_FREE
);
skip_write();
}
void CASBuffer::put(const char* in_buf, unsigned int bytes){
//convert to long
unsigned int longs = bytes/sizeof(long);
long rest = 0;
memcpy(&rest, in_buf+(bytes-bytes%sizeof(long)),bytes%sizeof(long));
/*for(int i=0; i<bytes%sizeof(long); i++){
rest|=in_buf[bytes-(i+1)];
rest<<=sizeof(char)*8;
}*/
long * in_lBuf = (long*)in_buf;
unsigned int ctrl_pos = write_pos;
//wait until i write
put(BANK_IS_FREE);
for(int i=0;i<longs;i++){
put(in_lBuf[i]);
}
put(rest);
unsigned int this_pos = write_pos;
write_pos=ctrl_pos;
put(bytes+CTRL_VALS);
write_pos=this_pos;
}
long CASBuffer::get(bool isCtrl, long xch){
long xchng = BANK_IS_FREE;
long result=BANK_IS_FREE;
long i, hit_cnt=0;
bool isFirst = true;
for (;;) {
i = InterlockedCompareExchange(&buf[read_pos],
xchng,
result);
if(isCtrl && isFirst){
if(i != BANK_IS_FREE){
xchng = xch;
}else{
if(++hit_cnt==10){
hit_cnt=0;
Sleep(0.1);
}
continue;
}
}
if(isFirst)
result = i;
if(!isFirst)
break;
isFirst=false;
}
skip_read();
return result;
}
unsigned int CASBuffer::get(char* in_buf){
unsigned int ctrl_pos = read_pos;
unsigned int ctrl = get(true, BANK_IS_READ);
if(ctrl==EOWS){
//restore state
read_pos=ctrl_pos;
get(true, EOWS);
read_pos=ctrl_pos;
return 0;
}
unsigned int bytes = ctrl-CTRL_VALS;
unsigned int longs = bytes/sizeof(long);
long rest = 0;
long * in_lBuf = (long*)in_buf;
for(int i=0;i<longs;i++){
in_lBuf[i]=get();
}
rest = get();
memcpy(in_buf+(bytes-bytes%sizeof(long)), &rest,bytes%sizeof(long));
/*
for(int i=bytes%sizeof(long); i>0; i--){
rest>>=sizeof(char)*8;
in_buf[bytes-i]=rest&0xFF;
}*/
unsigned int this_pos = read_pos;
read_pos=ctrl_pos;
get();
read_pos=this_pos;
return bytes;
}