• 沒有找到結果。

Deriving a unique totally ordered sequence of execution states

Chapter 5. Effective Test Set and Dynamic Effective Testing

5.4. Implementation of transformation function Γ based on the partial

5.4.2. Deriving a unique totally ordered sequence of execution states

A partial ordering of events is considered to be a general form for representing the event order of a concurrent system [62] in cases where a global clock is not available.

The version number used to determine the order of events actually records the partial ordering of these events. In addition to the shared memory model, almost all synchronization models can be represented in this way. Given the partial order graph, we are able to determine the ordering of any two events based on whether there is a path between them. Algorithm 6 shows how to generate the partial order graph of a SYN-sequence that contains the read and write operations R(U,V,L,C,T) and W(U,V,L,C). Figure 25 shows a feasible SYN-sequence S of the concurrent program in Figure 24 and the partial order graph of S.

70

Algorithm 6: Generate the partial order graph of a SYN-sequence S

Input: A SYN-sequence S that contains two types of synchronization events, read and write, which are represented by R(U,V,L,C,T) and W(U,V,L,C), respectively.

Output: A partial order graph PG.

(1) Let PG be a graph without any nodes or edges. Add each synchronization event of S to PG as a node.

(2) For the synchronization events of the same process, add an edge from the i-th event to the j-th event, where j=i+1.

(3) For two synchronization events X and Y, add an edge (X,Y) to PG if (a) X and Y are not part of the same process, (b) X and Y operate on the same shared variable, and (c) X and Y are one of the following:

X and Y are W(v,i,∗,∗)18 and R(v,i,∗,∗,∗). In cases where there are multiple R(v,i,∗,∗,∗) events in the same process, only one edge is added to PG in which R(v,i,*,*) is the earliest event in the process.

X and Y are W(v,i,∗,∗) and W(v,i+1,∗,∗), where the process of W(v,i+1,∗,∗) does not have event R(v,i,∗,∗,∗).

X and Y are R(v,i,∗,∗,∗) and W(v,i+1,∗,∗). In cases where there are multiple R(v,i,∗,∗,∗) events in the same process, only one edge is added to PG in which R(v,i,∗,∗,∗) is the latest event in the process.

a and b are shared variables.

a does not have an initial value and the initial value of b is 0.

Process P0 Process P1

Figure 24. Example of a concurrent program

18 The “*” is a wildcard character representing any execution locations, accessed values, or names of local variables.

W(a,1,S0,0,1)

Figure 25. SYN-sequence S and its partial order graph

One of the methods used to obtain the execution state after each synchronization event is to derive a totally ordered sequence from a partial ordering of events [63]. Each execution of an event will trigger a deterministic transition between two execution states.

If there are N events in a SYN-sequence, we can obtain a sequence of N+119 execution states from the totally ordered sequence of the N events. The totally ordered can be obtained by applying a topological sort in the partial order graph, but this is not always unique if a topological sort does not form a Hamiltonian path [64]. Figure 26 shows two valid totally ordered sequences of events (TS0 and TS1) obtained from the partial order graph shown in Figure 25. It is generally always possible to form a second valid total order by swapping two consecutive events that are not connected by an edge in the partial order graph to each other:

TS0={ W(a,1,S0,0,1), W(a,2,S1,0,0), R(a,2,S1,1,0,T2), R(a,2,S0,1,0,T1),

19 Note that one of the N+1 execution states is the initial state.

72

Figure 26. Two totally ordered sequences of events from the same partial order graph TS0 reaches the same execution state at X and Y; that is, we can find the reiterated state {(S0,1,S1,1,Start), (a=0,b=0,T1=0,T2=0)} in TS0. However, there is no reiterated state found in TS1. This demonstrates that different totally ordered sequences of events may produce different derived execution states. Intuitively, we could consider enumerating all the feasible totally ordered sequences of events from a SYN-sequence S to obtain all the reachable execution states of S. However, there is sometimes a huge number of totally ordered sequences of events of a SYN-sequence, which provides the motivation to find out if it is sufficient to obtain a single totally ordered sequence of events for the Γ function to avoid boundless state reiteration. We employ topological sorting based on events with the lowest process ID appearing first to obtain a unique totally ordered sequence of events from a SYN-sequence (see Algorithm 7). Although the valid totally ordered sequences of events of a SYN-sequence are usually not unique, this topological sorting technique generates a unique totally ordered sequence of events for a SYN-sequence, since at each step it picks the available event with the smallest process

ID.

Algorithm 7: Generate a totally ordered sequence of events with the lowest process ID appearing first in the topological sorting from a SYN-sequence S

Input: A SYN-sequence S that contains two types of synchronization event, read and write, which are represented by R(U,V,L,C,T) and W(U,V,L,C), respectively.

We assume that each event in S is associated with its process ID.

Output: A totally ordered sequence of events TOS.

(1) Apply Algorithm 6 to derive a partial order graph PG from S.

(2) Set TOS to be a totally ordered list with no event.

(3) WHILE (There are still events in PG)

For all events without in-edges, pick up one event e that has the lowest associated process ID.

Add e to TOS.

Remove e and all its out-edges from PG.

END WHILE

The way to record synchronization events mentioned in Section 5.4.1 skips some statements, resulting in some execution states not being stored in the SYN-sequence.

Topological sorting based on events with the lowest process ID appearing first can only derive a single totally ordered sequence of the synchronization events, and it cannot discover all the reachable execution states in a SYN-sequence. The abstraction of execution states can be beneficial in speeding up the execution of SYN-sequence transformation function Γ and the subsequent race analyzer. However, we have to ensure that this abstraction does not obstruct the goal of state-cover testing of dynamic effective testing. Theorem 7 shows that we can still achieve dynamic effective testing under this abstraction.

74

Theorem 7: Assume that a DFA F exists that represents the execution of a concurrent program P with input X. ASET rules are applied to transform the program into a collection of synchronization events, and Algorithm 5 is applied to obtain the totally ordered sequences of events from SYN-sequences for the Γ function to perform SYN-sequence transformation before deriving race variants. This achieves dynamic effective testing of P with input X, with the testing process eventually terminating.

Proof: First, we show that boundless state reiteration will not occur in the testing process. There exists a DFA F of P with X, and so there must be a finite execution-state upper bound of P with X. Let this bound be N. Because we apply the ASET rules to transform the program into a collection synchronization events, the execution state after the execution of each event will be obtained. If boundless state reiteration occurs during testing, the execution state will reiterate at the end of some synchronization events. Since we apply Algorithm 7 to obtain a valid totally ordered sequence of events and then derive its corresponding execution-state sequence, some reachable states may not be revealed in the execution-state sequence. We can assume that the number of distinct execution states of P with X that can be examined by the Γ function when it analyzes the totally ordered sequences obtained from Algorithm 7 is M, where M≤N. Note that the derived execution-state sequence is unique. We then derive the same set of execution states from the same SYN-sequence. If the number of events of a SYN-sequence is greater than M, then the number of found execution states will also be greater than M. According to the pigeonhole principle, there must be reiterated states in the first

M states. Thus, all the recorded reiterated states must be one of the first M states in the SYN-sequence. That is, each state stored in the reiterated state set is assigned with the associated event ID of one of the first M states. In cases 1 and 2 of the Γ function, one of the reiterated states will be discovered and stored. In case 4, we truncate events after the identified reiterated states. Thus, the number of events of the transformed SYN-sequence will be shorter than M. In case 5B, the Γ function does not truncate the events immediately. However, it invokes Γ′′ which tries to discover if there is any iterated state. If the descendant SYN-sequences reaches the recorded reiterate states again, it is either abandoned or shortened by event truncation which makes the transformed SYN-sequence shorter than M. It is obvious that boundless state reiteration will not occur in the testing process.

Second, we have to prove that even if some execution states are not identified in a single totally ordered sequence of events, we can still explore all the feasible execution states in dynamic effective testing. We may skip some feasible execution states in dynamic effective testing only when we abandon more SYN-sequences in cases 3, 5A, and 6, and we truncate more events in case 4. In the Γ function, we use identified reiterated states to perform these discard actions. Since we can only identify fewer execution states in Algorithm 7, we perform fewer discard actions. It is then impossible to skip feasible execution states and we can achieve the goal of state-cover testing of dynamic effective testing. QED