-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathILamportLock.java
More file actions
152 lines (124 loc) · 4.54 KB
/
Copy pathILamportLock.java
File metadata and controls
152 lines (124 loc) · 4.54 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package lab2try1;
import java.util.*;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
public class ILamportLock implements ImprovedBakeryLock{
private class Pair implements Comparable{
private Integer key, priority; // 0 is max priority
Pair(Integer ia, Integer ib){
key = ia;
priority = ib;
}
Pair(Pair obj){
key = obj.key;
priority = obj.priority;
}
public void setKey(Integer ikey){
key = ikey;
}
public void setPrior(Integer iprior){
priority = iprior;
}
@Override
public int compareTo(Object ix){
Pair x = (Pair)ix;
if(this.key < x.key){
return -1;
}
else if(Objects.equals(this.key, x.key)){
return 0;
}
return 1;
}
};
private final Integer threads = 100;
private final ArrayList<Pair> tickets = new ArrayList<>(threads);
private final ArrayList<Boolean> entering = new ArrayList<>(threads);
private final TreeSet<Pair>freeUsedTickets = new TreeSet<>();
private final Integer ticketBound = 3;
// private final AtomicInteger maxTicket = new AtomicInteger(0);
private final Semaphore fillCount = new Semaphore(ticketBound);
private Boolean isInitialized = Boolean.FALSE;
ILamportLock(){
synchronized(isInitialized){
if(!isInitialized){
for(int i = 0; i < threads; i++){
tickets.add(new Pair(-1, -1));
entering.add(false);
freeUsedTickets.add(new Pair(i,0));
}
isInitialized = true;
}
}
}
@Override
public void lock(Integer pid){
try{
fillCount.acquire();
}
catch(InterruptedException me){
}
actualLock(pid);
}
@Override
public void lockInterruptibly(Integer pid) throws InterruptedException{
fillCount.acquire();
actualLock(pid);
}
@Override
public boolean tryLock(Integer pid){
Boolean result = fillCount.tryAcquire();
if(!result){
return false;
}
actualLock(pid);
return true;
}
@Override
public boolean tryLock(Integer pid, long time, TimeUnit unit) throws InterruptedException{
Boolean result = fillCount.tryAcquire(time, unit);
if(!result){
return false;
}
actualLock(pid);
return true;
}
@Override
public Condition newCondition() throws UnsupportedOperationException{
throw new UnsupportedOperationException();
}
@Override
public void unlock(Integer pid){
Pair freeTicket = new Pair(tickets.get(pid));
freeTicket.setPrior(freeTicket.priority + 1);
tickets.get(pid).setKey(-1);
tickets.get(pid).setPrior(-1);
synchronized(freeUsedTickets){
freeUsedTickets.add(freeTicket);
}
fillCount.release();
System.out.println("Thread #" + pid + " exited....");
}
private void actualLock(Integer pid){
Pair ticket;
entering.set(pid, true);
synchronized(freeUsedTickets){
ticket = freeUsedTickets.pollFirst();
}
entering.set(pid, false);
tickets.set(pid, ticket);
System.out.println(pid + " got " + ticket.key + " with priority " + ticket.priority);
for(int i = 0; i < threads; i++){
if(i == pid){ continue; }
while(entering.get(i)){ Thread.yield(); }
while(tickets.get(pid).priority > tickets.get(i).priority && tickets.get(i).priority != -1){ Thread.yield(); }
if(tickets.get(i).priority.equals(tickets.get(pid).priority)){
while(tickets.get(i).key != -1 && tickets.get(pid).key >= tickets.get(i).key){ Thread.yield(); }}
// if(tickets.get(i).equals(tickets.get(pid))){ // to prove that there is no duplicates
// System.out.println("WARNING!!! DUPLICATE FOR " + pid + " IN " + i);
// }
}
// System.out.println(freeUsedTickets);
}
}