Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

modern-multithreading-c-java

.pdf
Скачиваний:
18
Добавлен:
22.05.2015
Размер:
4.77 Mб
Скачать

REACHABILITY TESTING

425

The OpenList contains program information that is used to compute the events that could have occurred besides r. For example, the OpenLists for the receive events in the example bounded buffer program above capture run-time information about the guard conditions (i.e., the list of accept alternatives that are open when a deposit or withdraw alternative is selected). This information enabled us to determine, for example, that a withdraw event could not be executed in place of the first deposit event. More OpenList examples are given below.

The individual fields of an event descriptor are referenced using dot notation. For example, operation op of sending event s is referred to as s.op. Tables 7.1 and 7.2 summarize the specific information that is contained in the event descriptors for the various synchronization constructs. Although the information is construct-specific, the format and general meaning of the fields in the event descriptors are the same for all constructs. This will allow us to present a single race analysis algorithm that operates on event descriptors and thus works for any construct. The values for most of the fields in the event descriptors are straightforward, except for the OpenList in receiving events. Below we describe how to compute OpenLists and provide examples of event descriptors for the various constructs.

Descriptors for Asynchronous Message Passing Events For asynchronous message passing, the OpenList of a receive event r contains a single port, which is the source port of r. A send event s is said to be open at a receive event r if port s.Destination is in the OpenList of r, which means that the ports of s and r match. For a sending event s to be in the race set of receive event r, it is necessary (but not sufficient) for s to be open at r. The race analysis algorithm presented in the next section can be used to determine whether s is involved in a race condition that could allow s to be the send partner of r.

Figure 7.18 shows a space-time diagram representing an execution with three threads. Thread T2 receives messages from ports p1 and p2. Thread T1 sends two messages to port p1. Thread T3 sends its first message to port p1 and its second message to port p2. Event descriptors are shown for each of the events.

TABLE 7.1 Event Descriptors for a Sending Event s

Synchronization

 

 

 

 

Construct

SendingThread

Destination

Operation

i

 

 

 

 

 

Asynchronous

Sending thread

Port ID

Send

Event index

message passing

 

 

 

 

Synchronous

Sending thread

Port ID

Send

Event index

message passing

 

 

 

 

Semaphores

Calling thread

Semaphore ID

P or V

Event index

Locks

Calling thread

Lock ID

Lock or unlock

Event index

Monitors

Calling thread

Monitor ID

Method name

Event index

 

 

 

 

 

426

 

TESTING AND DEBUGGING CONCURRENT PROGRAMS

TABLE 7.2 Event Descriptors for a Receiving Event r

 

 

 

 

 

 

 

 

 

Synchronization

 

 

 

 

 

 

 

Construct

Destination

 

 

OpenList

i

 

 

 

 

 

 

 

Asynchronous

Receiving thread

 

Port of r

Event index

message passing

 

 

 

 

 

 

 

Synchronous

Receiving thread

 

List of open ports

Event index

message passing

 

 

 

 

(including the port of r)

 

Semaphores

Semaphore ID

 

List of open operations

Event index

 

 

 

 

 

(P and/or V )

 

Locks

Lock ID

 

List of open operations

Event index

 

 

 

 

 

(lock and/or unlock)

 

Monitors

Monitor ID

 

List of the monitor’s

Event index

 

 

 

 

 

methods

 

 

 

 

 

 

 

 

 

 

T1

T2

T3

 

s2 (T1,p1,send,1)

r1 (T2,p1,1)

 

 

 

s1 (T3,p1,send,1)

 

 

 

r2 (T2,p1,2)

 

 

 

 

s3 (T3,p2,send,2)

 

r3 (T2,p2,3)

 

 

 

 

 

 

 

 

 

s4 (T1,p1,send,2)

 

 

r4 (T2,p1,4)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 7.18 Sequence of asynchronous send/receive events.

Descriptors for Synchronous Message Passing Events Synchronous message passing may involve the use of selective waits. The OpenList of a receive event r is a list of ports that had open receive alternatives when r was selected. Note that this list always includes the source port of r. For a simple receive statement that is not in a selective wait, the OpenList contains a single port, which is the source port of the receive statement. Event s is said to be open at r if port s.Destination is in the OpenList of r.

Figure 7.19 shows a space-time diagram representing an execution with three threads. Thread T1 sends two messages to port p1, and thread T3 sends two messages to port p2. Thread T2 executes a selective wait with receive alternatives for p1 and p2. Assume that whenever p2 is selected, the alternative for p1 is open, and whenever p1 is selected, the alternative for p2 is closed. This is reflected in the OpenLists for the receive events, which are shown between braces {. . .} in the event descriptors. Note that each solid arrow is followed by a dotted arrow in the opposite direction. The dotted arrows represent the updating of timestamps when the synchronous communication completes. Timestamp schemes are described in Section 7.5.4.

Descriptors for Semaphore Events Figure 7.20 shows an execution involving threads T1 and T2 and semaphore s, where s is a binary semaphore initialized

REACHABILITY TESTING

 

 

 

 

427

T1

T2

T3

s2 (T1,p1,send,1)

 

r1 (T2,{p1,p2},1)

 

 

 

 

s1 (T3,p2,send,1)

 

 

 

 

 

r2 (T2,{p1},2)

 

 

 

 

 

 

 

 

 

 

r3 (T2,{p1,p2},3)

 

 

s3 (T3,p2,send,2)

s4 (T1,p1,send,2)

 

 

 

 

 

 

r4 (T2,{p1},4)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 7.19 Sequence of synchronous send/receive events.

T1

s

T2

 

e1 (s,{P},1)

 

p1 (T2,s,P,1)

 

 

 

e2 (s,{V},2) v1 (T2,s,V,2)

p2 (T1,s,P,1) e3 (s,{P},3)

e4 (s,{V},4)

v2 (T1,s,V,2)

Figure 7.20 Sequence of P and V operations.

to 1. There is one time line for each thread and each semaphore. A solid arrow represents the completion of a P() or V() operation. The open lists for the completion events model the fact that P and V operations on a binary semaphore must alternate. This means that the OpenList of a completion event for a binary semaphore always contains one of P or V but not both. OpenLists for binary and counting semaphores can easily be calculated at run time based on the semaphore invariant (see Sections 3.1 and 3.4.1). A call event c for a P or V operation is open at a completion event e if c and e are operations on the same semaphore (i.e., c.Destination = e.Destination, and operation c.op of c is in the OpenList of e).

Descriptors for Lock Events If a lock is owned by some thread T when a completion event e occurs, each operation in the OpenList of e is prefixed with T to indicate that only T can perform the operation. (Recall that if a thread T owns lock L, only T can complete a lock() or unlock() operation on L.) For example, if the OpenList of a completion event e on a lock L contains two operations lock() and unlock(), and if L is owned by thread T when e occurs, the OpenList of e is {T : lock , T : unlock }. A call event c on lock L that is executed by thread T is open at a completion event e if (1) c.Destination = e.Destination;

(2) operation c.op is in the OpenList of e, and (3) if L is already owned when e occurs then T is the owner.

Figure 7.21 shows a space-time diagram representing an execution with two threads and a mutex lock k. Thread T2 performs two lock() operations followed by two unlock() operations, and thread T1 performs one lock() operation followed

428

 

TESTING AND DEBUGGING CONCURRENT PROGRAMS

T1

 

k

T2

 

 

e1 (k,{lock},1)

 

l1 (T2,k,lock,1)

 

 

 

 

 

 

 

 

 

 

 

e2 (k,{T2:lock,T2:unlock},2)

 

l2 (T2,k,lock,2)

 

 

 

e3 (k,{T2:lock,T2:unlock},3)

 

u1 (T2,k,unlock,3)

 

 

 

 

 

 

e4 (k,{T2:lock,T2:unlock},4)

 

u2 (T2,k,unlock,4)

 

 

l3 (T1,k,lock,1)

 

 

 

e5 (k,{lock},5)

 

 

 

u3 (T1,k,unlock,2)

 

 

 

e6 (k,{T1:lock,T1:unlock},6)

 

 

 

 

 

 

 

 

 

Figure 7.21 Sequence of lock and unlock operations.

by one unlock() operation. The OpenList for e2 reflects the fact that only thread T2 can complete a lock() or unlock() operation on k since T2 owns k when e occurs.

Descriptors for Monitor Events The invocation of a monitor method is modeled as a pair of monitor-call and monitor-entry events:

žSU monitors. When a thread T calls a method of monitor M, a monitor-call event c occurs on T . When T eventually enters M, a monitor-entry event e occurs on M, and then T starts to execute inside M.

žSC monitors. When a thread T calls a method of monitor M, a monitorcall event c occurs on T . A call event also occurs when T tries to reenter a monitor M after being signaled. When T eventually (re)enters M, a monitorentry event e occurs on M, and T starts to execute inside M.

In these scenarios, we say that T is the calling thread of c and e, and M is the destination monitor of c as well as the owning monitor of e. A call event c is open at an entry event e if the destination monitor of c is the owning monitor of e (i.e., c.Destination = e.Destination). The OpenList of an entry event always contains all the methods of the monitor since threads are never prevented from entering any monitor method (although they must enter sequentially and they may be blocked after they enter).

Figure 7.22 shows a space-time diagram representing an execution involving three threads T1, T2, and T3, an SC monitor m1 with methods a() and b(), and an SC monitor m2 with a single method c(). Thread T1 enters m1.a() first and executes a wait operation. The second call event performed by T1 occurs when T1 reenters m1.a() after being signaled by T2. Note that if m1 were an SU

REACHABILITY TESTING

 

 

 

 

 

429

 

T1

m1

T2

m2

T3

c1 (T1,m1,a,1)

 

 

e1 (m1,{a,b},1)

 

 

 

 

 

 

 

 

 

 

wait

 

 

 

 

 

c2 (T2,m1,b,1)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e2 (m1,{a,b},2)

 

 

 

 

 

 

 

 

 

 

 

 

signal

 

 

 

 

 

 

c3 (T1,m1,a,2) e3 (m1,{a,b},3)

c4 (T1,m2,c,3) e4 (m2,{c},1)

e5 (m2,{c},2) c5 (T3,m2,c,1)

c6 (T3,m1,b,2)

e6 (m1,{a,b},4)

Figure 7.22 Sequence of monitor call and entry events.

monitor, there would be no c3 event representing reentry. After T1 exits from m1, T1 enters and exits m2. This is followed by thread T3 entering and exiting m2 and then entering and exiting m1.

7.5.3 Race Analysis of SYN-Sequences

In this section we show how to perform race analysis on SYN-sequences. Section 7.5.2 showed a common event descriptor format for a variety of synchronization constructs. To illustrate race analysis, we will first consider a program CP that uses asynchronous ports. We assume that the messages sent from one thread to another may be received out of order. To simplify our discussion, we also assume that each thread has a single port from which it receives messages.

Let Q be an SR-sequence recorded during an execution of CP with input X. Assume that a b is a synchronization pair in Q, c is a send event in Q that is not a, and c’s message is sent to the same thread that executed b. We need to determine whether sending events a and c have a race (i.e., whether c b can happen instead of a b during an execution of CP with input X). Furthermore, we need to identify races by analyzing Q, not CP.

To determine accurately all the races in an execution, the program’s semantics must be analyzed. Fortunately, for the purpose of reachability testing, we need only consider a special type of race, called a lead race. Lead races can be identified by analyzing the SYN-sequence of an execution (i.e., without analyzing the source code).

Definition 6.1 Let Q be the SYN-sequence exercised by an execution of a concurrent program CP with input X. Let a b be a synchronization pair in Q and let c be another sending event in Q. There exists a lead race between c and < a, b > if c b can form a synchronization pair during some other execution

430

TESTING AND DEBUGGING CONCURRENT PROGRAMS

of CP with input X, provided that all the events that happened before c or b in Q are replayed in this other execution.

Note that Definition 6.1 requires all events that can potentially affect c or b in Q to be replayed in the other execution. If the events that happened before b are replayed, and the events that happened before c are replayed, we can be sure that b and c will also occur, without having to analyze the code.

Definition 6.2 The race set of a b in Q is defined as the set of sending events c such that c has a (lead) race with a b in Q.

We will refer to the receive event in Q that receives the message from c as receive event d, denoted by c d. (If the message from c was not received in Q, d does not exist.) To determine whether a b and c in Q have a message race, consider the 11 possible relationships that can hold between a, b, c, and d in Q:

(1)c d and d b.

(2)c d, b d, and b c.

(3)c is send event that is never received and b c.

(4)c d, b d, c||b, and a and c are send events of the same thread.

(5)c d, b d, c||b, and a and c are send events of different threads.

(6)c d, b d, c b, and a and c are send events of the same threads.

(7)c d, b d, c b, and a and c are send events of different threads.

(8)c is a send event that is not received, c||b, and a and c are send events of the same thread.

(9)c is a send event that is not received, c||b, and a and c are send events of different threads.

(10)c is a send event that is not received, c b, and a and c are send events of the same thread.

(11)c is a send event that is not received, c b, and a and c are send events of different threads.

The happened before relation e f was defined in Section 6.3.4. Recall that it is easy to examine a space-time diagram visually and determine the causal relations. For two events e and f in a space-time diagram, e f if and only if there is no message e f or f e and there exists a path from e to f that follows the vertical lines and arrows in the diagram.

Figure 7.23 shows 11 space-time diagrams that illustrate these 11 relations. Each of the diagrams contains a curve, called the frontier. Only the events happening before b or c are above the frontier. (A send event before the frontier may have its corresponding receive event below the frontier, but not vice versa.) For each of diagrams (4) through (11), if the send and receive events above the

REACHABILITY TESTING

 

 

 

 

c

 

 

 

d

 

 

 

a

 

 

f

b

 

 

 

 

 

 

c

 

 

 

 

 

 

 

 

(1)

 

 

 

 

 

 

 

b

 

 

 

 

a

 

 

 

 

 

 

 

 

 

 

 

c

 

 

 

d

 

 

 

 

 

 

 

 

 

 

 

(5)

 

 

 

 

b

 

 

 

 

a

 

 

 

 

 

 

 

 

 

 

c

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(9)

 

 

 

431

 

b

 

e

 

a

 

b

 

 

a

 

a

 

 

 

 

 

 

b

 

 

 

 

 

f

 

 

 

e

 

c

 

 

 

 

 

 

 

 

 

 

 

 

 

d

 

 

 

 

 

 

 

 

 

 

c

 

 

 

 

d

 

 

(2)

 

 

 

 

 

 

 

 

 

 

 

(3)

 

(4)

 

 

 

 

 

c

 

c

 

 

f

a

 

a

 

 

 

 

 

 

 

 

 

 

 

 

 

a

 

e

b

 

b

 

c

b

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

d

 

 

 

d

 

 

 

 

 

 

 

 

 

 

 

 

(6)

 

 

 

 

(7)

 

(8)

 

 

 

 

 

c

 

c

 

 

 

a

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e

 

 

f

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

b

 

 

 

 

b

 

 

 

 

 

 

 

 

 

 

 

(10)

 

 

 

 

(11)

 

 

 

Figure 7.23 For message a b and send event c d in Q, the eleven possible relations between a, b, c, and d.

frontier are repeated, events b and c will also be repeated and the message sent by c could be received by b. This is not true for diagrams (1), (2), and (3).

Based on these diagrams, we can define the race set of a b in Q as follows:

Definition 6.3 Let Q be an SR-sequence of a program using asynchronous communication and let a b be a synchronization pair in Q. The race set of a b in Q is {c|c is a send event in Q; c has b’s thread as the receiver; not b c; and if c d, then b d}.

Figure 7.24a shows an asychronous SR-sequence and the race set for each receive event in this SR-sequence. Consider send event s8 in Fig. 7.24a. Send event s8 is received by Thread2 and is in the race sets for receive events r1 and r2 of Thread2. Send event s8 is not in the race set for receive event r6 since r6 happens before s8. Send event s8 is not in the race set for receive event r7 since s8 r8 but r8 r7 . Thus, s8 is in the race sets for receive events of Thread2 that happen before r8 but do not happen before s8.

The asynchronous ports and mailboxes used in Chapters 5 and 6 are FIFO ports, which means that messages sent from one thread to another thread are received in the order that they are sent. With FIFO ordering, some of relations

(1)through (11) above must be modified:

žRelations (4) and (8) no longer have a race between message a b and c.

žRelations (6) and (10) are not possible.

žRelations (5), (7), (9), and (11) have a race between a b and c if and only if all the messages that are sent from c’s thread to b’s thread before c

is sent are received before b occurs.

432

 

 

 

 

TESTING AND DEBUGGING CONCURRENT PROGRAMS

Thread1 Thread2

Thread3

 

Thread4

Thread1 Thread2

Thread3 Thread4

s1

 

{s1,s2,s3} r6

 

 

 

s6

 

 

 

s1

 

{s1} r6

 

 

 

s6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

s4

 

 

 

 

 

 

 

 

 

s4

 

 

 

 

 

s2

 

 

r1

 

 

 

 

 

r4 { }

s2

 

 

r1 {s8}

 

r4 { }

 

 

{s2,s3,s8,s10}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

s5

 

 

 

r5 {s9}

 

s8

 

 

s5

 

 

 

r5 {s9}

s8

 

 

 

{s3,s7,s8,s10}

 

 

 

 

r2 {s7,s8}

 

 

 

r2

 

 

 

 

 

s9

 

 

 

 

s9

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

{s3,s7,s10} r8

 

{ } r9

s7

 

 

s10

 

 

{s3,s7} r8

 

{ } r9

s7

s10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

s3

 

 

 

 

 

 

 

 

s3

 

 

 

 

 

 

 

{s3,s10} r7

 

 

 

 

 

 

 

 

{s3,s10} r7

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(a)

 

 

 

 

 

 

 

 

(b)

 

Figure 7.24 Race sets for SR-sequences.

Thus, the definition of race set must also be modified for FIFO asynchronous SR-sequences.

Definition 6.4 Let Q be an SR-sequence of a program using FIFO asynchronous communication, and let a b be a message in Q. The race set of a b in Q is {c|c is a send event in Q; c has b’s thread as the receiver; not b c; if c d, then b d; and all the messages that are sent from c’s thread to b’s thread before c is sent are received before b occurs}.

Figure 7.24b shows a FIFO asynchronous SR-sequence and the race set for each receive event in this SR-sequence. (Since the asynchronous SR-sequence in Fig. 7.24a satisfies FIFO ordering, it is also used in Fig. 7.24b.) Consider the nonreceived send event s3 in Fig. 7.24b. Send event s3 has Thread2 as the receiver and is in the race sets for receive events r7 and r8 in Thread2. Thread2 executes r2 immediately before executing r8. Since r2 has the same sender as s3 and s2 is sent to Thread2 before s3 is sent, s2 has to be received by Thread2 before s3 is received. Thus, s3 is not in the race set for receive event r2. (Note that in Fig. 7.24a, s3 is in the race sets for receive events r6, r1, r2, r8, and r7.)

In some parallel programs, nondeterminism is considered to be the result of a programming error [Empath et al. 1992]. If an execution of CP with input X is expected to be deterministic, the race set for each receive event in Q should be empty. If the race set for each receive event in Q is empty, all executions of CP with input X exercise the same SR-sequence and produce the same result.

In general, sending and receiving events may involve constructs such as semaphores, locks, and monitors, not just message passing. The following definition describes how to compute the race set of a receiving event assuming that all the constructs use FIFO semantics.

Definition 6.5 Let Q be a SYN-sequence exercised by program CP. A sending event s is in the race set of a receiving event r if (1) s is open at r; (2) r does

REACHABILITY TESTING

433

not happen before s; (3) if < s, r > is a synchronization pair, r happens before r ; and (4) s and r are consistent with FIFO semantics (i.e., all the messages that were sent to the same destination as s, and were sent before s, are received before r).

Following are some examples of race sets:

ž Asynchronous message passing. The race sets for the receive events in Fig. 7.18 are as follows: race(r1 ) = {s2 } and race(r2 ) = race(r3 ) = race(r4 ) = {}. Note that s3 is not in the race set of r1 because s3 is sent to a different port and thus s3 is not open at r1. For the same reason, s4 is not in the race set of r3. Note also that s4 is not in the race set of r1, because FIFO semantics ensures that s2 is received before s4.

žSynchronous message passing. The race sets of the receive events in Fig. 7.19 are as follows: race(r1 ) = {s2 }, race(r2 ) = {}, race(r3 ) = {s4 }, and race(r4 ) = {}. Since the receive alternative for port p2 was open whenever thread T2 selected the receive alternative for port p1, the race set for r1 contains s2 and the race set for r3 contains s4. On the other hand, since the receive alternative for p1 was closed whenever thread T2 selected the receive alternative for p2, the race set for r2 does not contain s3.

žSemaphores. The race sets of the completion events in Fig. 7.20 are as follows: race(e1) = {p2} and race(e2) = race(e3) = race(e4) = {}. Note that since P () is not in the OpenList of e2, the race set for e2 does not contain p2. This captures the fact that the P () operation by T1 could start but not complete before the V () operation by T2 and hence that these operations do not race.

žLocks. The race sets of the completion events in Fig. 7.21 are as follows: race(e1) = {l3} and race(e2) = race(e3) = race(e4) = race(e5) = race(e6) = {}. Note that since T2 owned lock k when the operations for events e2, e3, and e4 were started, the race sets for e2, e3, and e4 are empty. This represents the fact that no other thread can complete a lock() operation on k while it is owned by T2.

ž Monitors. The race sets of the entry events in Fig. 7.22 are as follows: race(e1) = {c2}, race(e2) = race(e3) = {}race(e4) = {c5}, and race(e5) =

race(e6) = {}. Sending event c3 is not in the race set of e2 since c3 happened after e2. (Thread T2 entered monitor m at e2 and executed a signal operation that caused T1 to issue the call at c3.)

7.5.4 Timestamp Assignment

As we just saw, the definition of a race between sending events is based on the happened-before relation, which was defined in Section 6.3.3. In this section we present thread-centric and object-centric timestamp assignment schemes for capturing the happened-before relation during race analysis. A thread-centric

434

TESTING AND DEBUGGING CONCURRENT PROGRAMS

timestamp has a dimension equal to the number of threads involved in an execution. An object-centric timestamp has a dimension equal to the number of synchronization objects involved. Therefore, a thread-centric scheme is preferred when the number of threads is smaller than the number of synchronization objects, and an object-centric scheme is preferred otherwise.

Thread-Centric Scheme The vector timestamp scheme described in Section 6.3.5 is thread-centric by our definition and can be used for race analysis. Recall that in this scheme each thread maintains a vector clock. A vector clock is a vector of integers used to keep track of the integer clock of each thread. The integer clock of a thread is initially zero and is incremented each time the thread executes a send or receive event. Each send and receive event is also assigned a copy of the vector clock as its timestamp.

Let T .v be the vector clock maintained by a thread T . Let f.ts be the vector timestamp of event f . The vector clock of a thread is initially a vector of zeros. The following rules are used to update vector clocks and assign timestamps to the send and receive events in asynchronous message passing programs:

1.When a thread Ti executes a nonblocking send event s, it performs the following operations: (a) Ti .v[i] = Ti .v[i] + 1; (b) s.ts = Ti .v. The message sent by s also carries the timestamp s.ts.

2.When a thread Tj executes a receive event r with synchronization partner s, it performs the following operations: (a) Tj .v[j ] = Tj .v[j ] + 1; (b) Tj .v = max(Tj .v, s.ts); (c) r.ts = Tj .v.

Figure 7.25a shows the timestamps for the asynchronous message passing program in Fig. 7.18. A timestamp scheme for synchronous message passing was also described in Section 6.3.5, but this scheme must be extended before it can be used for race analysis. The scheme in Section 6.3.5 assigns the same timestamp to send and receive events that are synchronization partners:

1.When a thread Ti executes a blocking send event s, it performs the operation Ti .v[i] = Ti .v[i] + 1. The message sent by s also carries the value of vector clock Ti .v.

T1

T2

T3

T1

T2

T3

s2 [1,0,0]

 

r1 [0,1,1]

 

 

 

s1 [0,0,1]

 

 

 

r1 [0,1,1]

 

 

 

 

s1 [0,1,1]

 

r2 [1,2,1]

 

s2 [1,2,1]

 

 

r2 [1,2,1]

 

 

 

 

 

 

 

 

 

 

 

 

 

s3 [1,3,2]

 

 

 

 

 

 

 

 

 

 

r3 [1,3,2]

 

s3 [0,0,2]

 

 

r3 [1,3,2]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

s4 [2,4,2]

 

 

r4 [2,4,2]

 

 

s4 [2,0,0]

 

r4 [2,4,2]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(a)

 

 

 

 

 

(b)

 

 

 

Figure 7.25 Traditional timestamp schemes for asynchronous and synchronous message passing.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]