design and analysis of executable software models
play

Design and Analysis of Executable Software Models: An Introduction - PowerPoint PPT Presentation

Design and Analysis of Executable Software Models: An Introduction and Overview Reiner H ahnle joint work with Antonio F. Montoya, Richard Bubel, Crystal C. Din and many others! Technical University of Darmstadt haehnle@cs.tu-darmstadt.de


  1. Asynchronous Method Calls Asynchronous Method Calls ◮ Syntax: target ! methodName(arg1, arg2, ...) ◮ Creates new task in COG of target ◮ Caller continues execution and allocates a future to store the result • Fut<T> v = o!m(e); Conditional Scheduling (Waiting for the Future) ◮ await g , where g is a polling guard ◮ Yields task execution until guard is true R. H¨ ahnle (TUD) Analysis of ESMs 17 / 54

  2. Asynchronous Method Calls Asynchronous Method Calls ◮ Syntax: target ! methodName(arg1, arg2, ...) ◮ Creates new task in COG of target ◮ Caller continues execution and allocates a future to store the result • Fut<T> v = o!m(e); Conditional Scheduling (Waiting for the Future) ◮ await g , where g is a polling guard ◮ Yields task execution until guard is true Reading Futures ◮ f.get - reads future f and blocks execution until result is available ◮ Deadlocks possible (use static analyzer for detection) ◮ Programming idiom: await f? prevents blocking (safe access) • Fut<T> v = o!m(e);...; await v?; r = v.get; R. H¨ ahnle (TUD) Analysis of ESMs 17 / 54

  3. Part II Resource Analysis Of ABS Models R. H¨ ahnle (TUD) Analysis of ESMs 18 / 54

  4. Introduction Static resource analysis attempts to infer upper bounds on the amount of resources that can be consumed by a system Some typical measured resources: ◮ Time (Computational complexity) ◮ Space (Memory comsumption) Related to distributed systems and ABS models ◮ Bandwidth ◮ Executed instructions per component (COG) R. H¨ ahnle (TUD) Analysis of ESMs 19 / 54

  5. A ABS model fragment An example that we want to analyze: class DBImpl implements DB { List<Account> as = Nil; Account getAccount(Int aid) { Account result = null ; ◮ A method getAccount that Int n = length(as); searches an Account aid Int cnt = 0; while (cnt < n) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } ... } R. H¨ ahnle (TUD) Analysis of ESMs 20 / 54

  6. A ABS model fragment An example that we want to analyze: class DBImpl implements DB { List<Account> as = Nil; Account getAccount(Int aid) { Account result = null ; ◮ A method getAccount that Int n = length(as); searches an Account aid Int cnt = 0; while (cnt < n) { ◮ It iterates over a field as Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } ... } R. H¨ ahnle (TUD) Analysis of ESMs 20 / 54

  7. A ABS model fragment An example that we want to analyze: class DBImpl implements DB { List<Account> as = Nil; Account getAccount(Int aid) { Account result = null ; ◮ A method getAccount that Int n = length(as); searches an Account aid Int cnt = 0; while (cnt < n) { ◮ It iterates over a field as Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); ◮ For each account a in as , call Int id=idFut.get; getAid and block execution if (aid == id) { result = a; until result is ready } cnt = cnt+1; } return result; } ... } R. H¨ ahnle (TUD) Analysis of ESMs 20 / 54

  8. A ABS model fragment An example that we want to analyze: class DBImpl implements DB { List<Account> as = Nil; Account getAccount(Int aid) { Account result = null ; ◮ A method getAccount that Int n = length(as); searches an Account aid Int cnt = 0; while (cnt < n) { ◮ It iterates over a field as Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); ◮ For each account a in as , call Int id=idFut.get; getAid and block execution if (aid == id) { result = a; until result is ready } ◮ If id is the account we are cnt = cnt+1; } looking for, store it in result return result; } ... } R. H¨ ahnle (TUD) Analysis of ESMs 20 / 54

  9. Basic approach (for Sequential Code) 1 Select a cost model • map each instruction to the amount of resources it consumes • dependant on the kind of resource to be measured Account getAccount(Int aid) { Account result = null ; Int n = length(as); 3 Int cnt = 0; while (cnt < n) { 1 + nth( as , cnt ) Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); 1 + getAid() 1 Int id=idFut.get; if (aid == id) { 1 result = a; } 1 cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 21 / 54

  10. Basic approach (for Sequential Code) 2 Perform size analysis and generate abstract representation • Abstract data structures to an integer representation of their size • Abstract method calls to cost functions Account getAccount(Int aid) { ◮ The list as is abstracted to its length Account result = null ; Int n = length(as); 3 Int cnt = 0; while (cnt < n) { 1 + nth( as , cnt ) Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); 1 + getAid() 1 Int id=idFut.get; if (aid == id) { 1 result = a; } cnt = cnt+1; 1 } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 21 / 54

  11. Basic approach (for Sequential Code) 2 Perform size analysis and generate abstract representation • Abstract data structures to an integer representation of their size • Abstract method calls to cost functions • Generate a cost equation for each block of code Account getAccount(Int aid) { ◮ The list as is abstracted to its length Account result = null ; Int n = length(as); 3 Int cnt = 0; while (cnt < n) { 1 + nth( as , cnt ) Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); 1 + getAid() 1 Int id=idFut.get; if (aid == id) { 1 result = a; } cnt = cnt+1; 1 } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 21 / 54

  12. Basic approach (for Sequential Code) 2 Perform size analysis and generate abstract representation • Abstract data structures to an integer representation of their size • Abstract method calls to cost functions • Generate a cost equation for each block of code Account getAccount(Int aid) { ◮ The list as is abstracted to its length Account result = null ; Int n = length(as); 3 Int cnt = 0; while (cnt < n) { 1 + nth( as , cnt ) Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); 1 + getAid() 1 Int id=idFut.get; if (aid == id) { 1 getAccount( as , aid ) = 3 + length( as ) + while(0 , n , aid , as ) n = as result = a; } cnt = cnt+1; 1 } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 21 / 54

  13. Basic approach (for Sequential Code) 2 Perform size analysis and generate abstract representation • Abstract data structures to an integer representation of their size • Abstract method calls to cost functions • Generate a cost equation for each block of code Account getAccount(Int aid) { ◮ The list as is abstracted to its length Account result = null ; Int n = length(as); 3 Int cnt = 0; while (cnt < n) { 1 + nth( as , cnt ) Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); 1 + getAid() 1 Int id=idFut.get; if (aid == id) { 1 getAccount( as , aid ) = 3 + length( as ) + while(0 , n , aid , as ) n = as result = a; while( cnt , n , aid , as ) = 4 + nth( as , cnt ) + getAid( a )+ } if( cnt , n , aid , id ) + while( cnt + 1 , n , aid , as ) cnt < n cnt = cnt+1; 1 while( cnt , n , aid , as ) = 0 cnt ≥ n } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 21 / 54

  14. Basic approach (for Sequential Code) 2 Perform size analysis and generate abstract representation • Abstract data structures to an integer representation of their size • Abstract method calls to cost functions • Generate a cost equation for each block of code Account getAccount(Int aid) { ◮ The list as is abstracted to its length Account result = null ; Int n = length(as); 3 Int cnt = 0; while (cnt < n) { 1 + nth( as , cnt ) Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); 1 + getAid() 1 Int id=idFut.get; if (aid == id) { 1 getAccount( as , aid ) = 3 + length( as ) + while(0 , n , aid , as ) n = as result = a; while( cnt , n , aid , as ) = 4 + nth( as , cnt ) + getAid( a )+ } if( cnt , n , aid , id ) + while( cnt + 1 , n , aid , as ) cnt < n cnt = cnt+1; 1 while( cnt , n , aid , as ) = 0 cnt ≥ n } if( cnt , n , aid , id ) = 1 id = aid return result; if( cnt , n , aid , id ) = 0 id � = aid } R. H¨ ahnle (TUD) Analysis of ESMs 21 / 54

  15. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + length( as ) + while(0 , n , aid , as ) n = as while( cnt , n , aid , as ) = 4 + nth( as , cnt ) + getAid( a )+ if( cnt , n , aid , id ) + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  16. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + as + while(0 , n , aid , as ) n = as while( cnt , n , aid , as ) = 4 + cnt + 1+ if( cnt , n , aid , id ) + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid Assuming the following costs: length( as ) = as nth( as , cnt ) = cnt getAid( a ) = 1 R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  17. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + as + while(0 , n , aid , as ) n = as while( cnt , n , aid , as ) = 4 + cnt + 1+ 1 + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid ◮ An upper bound of if( cnt , n , aid , id ) = 1 R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  18. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + as + while(0 , n , aid , as ) n = as while( cnt , n , aid , as ) = 4 + cnt + 1+ 1 + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid ◮ An upper bound of if( cnt , n , aid , id ) = 1 ◮ The cost of any iteration of while 6 + cnt is smaller than 6 + n R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  19. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + as + while(0 , n , aid , as ) n = as while( cnt , n , aid , as ) = 4 + cnt + 1+ 1 + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid ◮ An upper bound of if( cnt , n , aid , id ) = 1 ◮ The cost of any iteration of while 6 + cnt is smaller than 6 + n ◮ while can iterate at most n times R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  20. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + as + n 2 + 6 n n = as while( cnt , n , aid , as ) = 4 + cnt + 1+ 1 + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid ◮ An upper bound of if( cnt , n , aid , id ) = 1 ◮ The cost of any iteration of while 6 + cnt is smaller than 6 + n ◮ while can iterate at most n times ◮ An upper bound of while( cnt , n , aid , as ) = n 2 + 6 n R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  21. Basic approach (for sequential models) 3 Solve the system of cost equations: getAccount( as , aid ) = 3 + as + n 2 + 6 n n = as while( cnt , n , aid , as ) = 4 + cnt + 1+ 1 + while( cnt + 1 , n , aid , as ) cnt < n while( cnt , n , aid , as ) = 0 cnt ≥ n if( cnt , n , aid , id ) = 1 id = aid if( cnt , n , aid , id ) = 0 id � = aid ◮ An upper bound of if( cnt , n , aid , id ) = 1 ◮ The cost of any iteration of while 6 + cnt is smaller than 6 + n ◮ while can iterate at most n times ◮ An upper bound of while( cnt , n , aid , as ) = n 2 + 6 n ◮ An upper bound of getAccount( as , aid ) = as 2 + 7 as + 3 R. H¨ ahnle (TUD) Analysis of ESMs 22 / 54

  22. Analyzing Concurrent Models ◮ Concurrency increases the degree of non-determinism ◮ In ABS, fields can be modified by other methods during release points Consider the following modification of our example: Account getAccount(Int aid) { Account result = null ; Int cnt = 0; while (cnt < length(as)) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 23 / 54

  23. Analyzing Concurrent Models ◮ Concurrency increases the degree of non-determinism ◮ In ABS, fields can be modified by other methods during release points Consider the following modification of our example: ◮ Direct comparison with the Account getAccount(Int aid) { Account result = null ; length of as Int cnt = 0; while (cnt < length(as)) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 23 / 54

  24. Analyzing Concurrent Models ◮ Concurrency increases the degree of non-determinism ◮ In ABS, fields can be modified by other methods during release points Consider the following modification of our example: ◮ Direct comparison with the Account getAccount(Int aid) { Account result = null ; length of as Int cnt = 0; while (cnt < length(as)) { ◮ Wait for idFut without Account a = nth(as,cnt); blocking the object Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 23 / 54

  25. Analyzing Concurrent Models ◮ Concurrency increases the degree of non-determinism ◮ In ABS, fields can be modified by other methods during release points Consider the following modification of our example: ◮ Direct comparison with the Account getAccount(Int aid) { Account result = null ; length of as Int cnt = 0; while (cnt < length(as)) { ◮ Wait for idFut without Account a = nth(as,cnt); blocking the object Fut<Int>idFut = a!getAid(); await idFut; Problems Int id=idFut.get; ◮ as could be increased during await by if (aid == id) { result = a; another method } ◮ Then the initial value of as is not a cnt = cnt+1; } bound on the number of iterations return result; } R. H¨ ahnle (TUD) Analysis of ESMs 23 / 54

  26. Analyzing Concurrent Models: Class Invariants Use class invariants to capture the required information R. H¨ ahnle (TUD) Analysis of ESMs 24 / 54

  27. Analyzing Concurrent Models: Class Invariants Use class invariants to capture the required information Class invariants An ABS class invariant is a predicate over the fields of a class that holds at every release point Account getAccount(Int aid) { Account result = null ; Int cnt = 0; while (cnt < length(as)) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 24 / 54

  28. Analyzing Concurrent Models: Class Invariants Use class invariants to capture the required information Class invariants An ABS class invariant is a predicate over the fields of a class that holds at every release point ◮ Annotate the method with [as<=max(as)] Account getAccount(Int aid) { [as<=max(as)] at its release Account result = null ; points Int cnt = 0; while (cnt < length(as)) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; [as<=max(as)] Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 24 / 54

  29. Analyzing Concurrent Models: Class Invariants Use class invariants to capture the required information Class invariants An ABS class invariant is a predicate over the fields of a class that holds at every release point ◮ Annotate the method with [as<=max(as)] Account getAccount(Int aid) { [as<=max(as)] at its release Account result = null ; points Int cnt = 0; while (cnt < length(as)) { ◮ Now it is guaranteed that the Account a = nth(as,cnt); loop does not iterate more than Fut<Int>idFut = a!getAid(); await idFut; [as<=max(as)] max(as) times Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 24 / 54

  30. Analyzing Concurrent Models: Class Invariants Use class invariants to capture the required information Class invariants An ABS class invariant is a predicate over the fields of a class that holds at every release point ◮ Annotate the method with [as<=max(as)] Account getAccount(Int aid) { [as<=max(as)] at its release Account result = null ; points Int cnt = 0; while (cnt < length(as)) { ◮ Now it is guaranteed that the B u t h a v e t o p r o v e t h a t t h e Account a = nth(as,cnt); i n v a r i a loop does not iterate more than n t h o l d s ! Fut<Int>idFut = a!getAid(); await idFut; [as<=max(as)] max(as) times Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 24 / 54

  31. Rely-Guarantee Reasoning (for Termination) Adapt a rely-guarantee approach for proving termination as follows: ◮ Given a loop, assume its fields are not modified during release points ◮ Attempt to prove termination of the loop Observation If a loop terminates when its fields are not modified, it also terminates if the fields are modified a finite number of times ◮ Prove that the instructions that modify the fields involved in the termination proof (in between release points) are modified a finite number of times ◮ To do so, use same procedure in the loops that contain such instructions ◮ We fail if we find a circular dependency A similar approach can be used to obtain upper bounds R. H¨ ahnle (TUD) Analysis of ESMs 25 / 54

  32. Rely-Guarantee Reasoning: Example To apply this procedure, we need a complete program— add a main method that: { Account a; DB db = new cog DBImpl(); Int max = 10; Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 26 / 54

  33. Rely-Guarantee Reasoning: Example To apply this procedure, we need a complete program— add a main method that: ◮ creates a database ( DBImpl ) { Account a; DB db = new cog DBImpl(); Int max = 10; Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 26 / 54

  34. Rely-Guarantee Reasoning: Example To apply this procedure, we need a complete program— add a main method that: ◮ creates a database ( DBImpl ) { ◮ adds 10 new accounts to the database Account a; DB db = new cog DBImpl(); (sequentially) Int max = 10; Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 26 / 54

  35. Rely-Guarantee Reasoning: Example To apply this procedure, we need a complete program— add a main method that: ◮ creates a database ( DBImpl ) { ◮ adds 10 new accounts to the database Account a; DB db = new cog DBImpl(); (sequentially) Int max = 10; ◮ calls method getAccount Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 26 / 54

  36. Rely-Guarantee Reasoning: Example To apply this procedure, we need a complete program— add a main method that: ◮ creates a database ( DBImpl ) { ◮ adds 10 new accounts to the database Account a; DB db = new cog DBImpl(); (sequentially) Int max = 10; ◮ calls method getAccount Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = Assume insertAccount modifies the db!insertAccount(a); await aFut?; field as of the database as expected i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 26 / 54

  37. Rely-Guarantee Reasoning: Example Method applied to to getAccount : Account getAccount(Int aid) { Account result = null ; Int cnt = 0; while (cnt < length(as)) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 27 / 54

  38. Rely-Guarantee Reasoning: Example Method applied to to getAccount : 1 assume as is unmodified during await Account getAccount(Int aid) { Account result = null ; Int cnt = 0; while (cnt < length(as)) { Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 27 / 54

  39. Rely-Guarantee Reasoning: Example Method applied to to getAccount : 1 assume as is unmodified during await Account getAccount(Int aid) { Account result = null ; 2 obtain that as is an upper bound on Int cnt = 0; while (cnt < length(as)) { the number of iterations Account a = nth(as,cnt); Fut<Int>idFut = a!getAid(); await idFut; Int id=idFut.get; if (aid == id) { result = a; } cnt = cnt+1; } return result; } R. H¨ ahnle (TUD) Analysis of ESMs 27 / 54

  40. Rely-Guarantee Reasoning: Example Method applied to to getAccount : 1 assume as is unmodified during await { 2 obtain that as is an upper bound on Account a; DB db = new cog DBImpl(); the number of iterations Int max = 10; Int i = 1; 3 examine the program points where as while (i <= max){ can be modified a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 27 / 54

  41. Rely-Guarantee Reasoning: Example Method applied to to getAccount : 1 assume as is unmodified during await { 2 obtain that as is an upper bound on Account a; DB db = new cog DBImpl(); the number of iterations Int max = 10; Int i = 1; 3 examine the program points where as while (i <= max){ can be modified a = new cog AccountImpl(i,0); Fut<Unit> aFut = 4 all instances of insertAccount db!insertAccount(a); must have finished when we execute await aFut?; i = i+1; getAccount } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 27 / 54

  42. Rely-Guarantee Reasoning: Example Method applied to to getAccount : 1 assume as is unmodified during await { 2 obtain that as is an upper bound on Account a; DB db = new cog DBImpl(); the number of iterations Int max = 10; Int i = 1; 3 examine the program points where as while (i <= max){ can be modified a = new cog AccountImpl(i,0); Fut<Unit> aFut = 4 all instances of insertAccount db!insertAccount(a); must have finished when we execute await aFut?; i = i+1; getAccount } 5 therefore, the upper bound is correct db!getAccount(3); } and we are done! R. H¨ ahnle (TUD) Analysis of ESMs 27 / 54

  43. Rely-Guarantee Reasoning: Example(2) Consider the following modification: { Account a; DB db = new cog DBImpl(); Int max = 10; Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 28 / 54

  44. Rely-Guarantee Reasoning: Example(2) Consider the following modification: 4 without the await, some instances of insertAccount might execute in { parallel with getAccount Account a; DB db = new cog DBImpl(); Int max = 10; Int i = 1; while (i <= max){ a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 28 / 54

  45. Rely-Guarantee Reasoning: Example(2) Consider the following modification: 4 without the await, some instances of insertAccount might execute in { parallel with getAccount Account a; DB db = new cog DBImpl(); 5 we need to prove that the number of Int max = 10; instances of insertAccount is Int i = 1; while (i <= max){ finite a = new cog AccountImpl(i,0); Fut<Unit> aFut = db!insertAccount(a); await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 28 / 54

  46. Rely-Guarantee Reasoning: Example(2) Consider the following modification: 4 without the await, some instances of insertAccount might execute in { parallel with getAccount Account a; DB db = new cog DBImpl(); 5 we need to prove that the number of Int max = 10; instances of insertAccount is Int i = 1; while (i <= max){ finite a = new cog AccountImpl(i,0); Fut<Unit> aFut = 6 apply rely-guarantee procedure to the db!insertAccount(a); while loop in the main block await aFut?; i = i+1; } db!getAccount(3); } R. H¨ ahnle (TUD) Analysis of ESMs 28 / 54

  47. Rely-Guarantee Reasoning: Example(2) Consider the following modification: 4 without the await, some instances of insertAccount might execute in { parallel with getAccount Account a; DB db = new cog DBImpl(); 5 we need to prove that the number of Int max = 10; instances of insertAccount is Int i = 1; while (i <= max){ finite a = new cog AccountImpl(i,0); Fut<Unit> aFut = 6 apply rely-guarantee procedure to the db!insertAccount(a); while loop in the main block await aFut?; i = i+1; 7 that loop terminates without any } additional asumptions (it has at most db!getAccount(3); } 10 iterations) R. H¨ ahnle (TUD) Analysis of ESMs 28 / 54

  48. Rely-Guarantee Reasoning: Example(2) Consider the following modification: 4 without the await, some instances of insertAccount might execute in { parallel with getAccount Account a; DB db = new cog DBImpl(); 5 we need to prove that the number of Int max = 10; instances of insertAccount is Int i = 1; while (i <= max){ finite a = new cog AccountImpl(i,0); Fut<Unit> aFut = 6 apply rely-guarantee procedure to the db!insertAccount(a); while loop in the main block await aFut?; i = i+1; 7 that loop terminates without any } additional asumptions (it has at most db!getAccount(3); } 10 iterations) 8 we are done! R. H¨ ahnle (TUD) Analysis of ESMs 28 / 54

  49. Part III Deadlock Analyis of ABS Models R. H¨ ahnle (TUD) Analysis of ESMs 29 / 54

  50. Introduction The ABS concurrency model excludes race conditions, but not deadlocks Definition (Deadlock) A deadlock situation is a state of a concurrent model in which one or more tasks are waiting for each others’ termination and none of them can make any progress. In ABS, the main entities involved in deadlocks are: ◮ COGs, that represent the units of concurrency (processors) ◮ Method executions (a.k.a. tasks) ◮ Synchronization statements ( await g and get ) R. H¨ ahnle (TUD) Analysis of ESMs 30 / 54

  51. ABS Deadlock Example main { a= new cog A(); b= new cog B(); c= new cog C(); b!blk_c(c,a); a!blk_b(b); } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  52. ABS Deadlock Example main B { a= new cog A(); b= new cog B(); c= new cog C(); b!blk_c(c,a); a!blk_b(b); } A C R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  53. ABS Deadlock Example main B { class B{ a= new cog A(); blk_c(C c,A a){ b= new cog B(); f=c!wait(a); c= new cog C(); f.get; b!blk_c(c,a); } a!blk_b(b); empt2(){} } } A C class A{ blk_b(B b){ f=b!empt2(); f.get; } empt(){} } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  54. ABS Deadlock Example main B { class B{ a= new cog A(); blk_c(C c,A a){ b= new cog B(); f=c!wait(a); c= new cog C(); f.get; b!blk_c(c,a); } a!blk_b(b); empt2(){} } } A C class A{ class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  55. ABS Deadlock Example main B { class B{ a= new cog A(); blk_c(C c,A a){ b= new cog B(); f=c!wait(a); c= new cog C(); f.get; b!blk_c(c,a); } a!blk_b(b); empt2(){} } } A C class A{ class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  56. ABS Deadlock Example main B e p e n d e n c i e s : D { class B{ 1 B → C . wait a= new cog A(); blk_c(C c,A a){ b= new cog B(); f=c!wait(a); c= new cog C(); f.get; b!blk_c(c,a); } a!blk_b(b); empt2(){} } } A C class A{ class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  57. ABS Deadlock Example main B e p e n d e n c i e s : D { class B{ 1 B → C . wait a= new cog A(); blk_c(C c,A a){ 2 A → B . empt 2 b= new cog B(); f=c!wait(a); c= new cog C(); f.get; 3 B . empt 2 → B b!blk_c(c,a); } (wait for B ’s lock) a!blk_b(b); empt2(){} } } A C class A{ class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  58. ABS Deadlock Example main B : D e p e n d e n c i e s { class B{ 1 B → C . wait a= new cog A(); blk_c(C c,A a){ 2 A → B . empt 2 b= new cog B(); f=c!wait(a); c= new cog C(); f.get; 3 B . empt 2 → B b!blk_c(c,a); } (wait for B ’s lock) a!blk_b(b); empt2(){} } } A C class A{ class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  59. ABS Deadlock Example main B : D e p e n d e n c i e s { class B{ 1 B → C . wait a= new cog A(); blk_c(C c,A a){ 2 A → B . empt 2 b= new cog B(); f=c!wait(a); c= new cog C(); f.get; 3 B . empt 2 → B b!blk_c(c,a); } (wait for B ’s lock) a!blk_b(b); empt2(){} } } 4 C . wait → A . empt 5 A . empt → A (wait for A ’s lock) A C class A{ class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  60. ABS Deadlock Example main B : D e p e n d e n c i e s { class B{ 1 B → C . wait a= new cog A(); blk_c(C c,A a){ 2 A → B . empt 2 b= new cog B(); f=c!wait(a); c= new cog C(); f.get; 3 B . empt 2 → B b!blk_c(c,a); } (wait for B ’s lock) a!blk_b(b); empt2(){} } } 4 C . wait → A . empt 5 A . empt → A (wait for A ’s lock) A C class A{ Deadlock! class C{ blk_b(B b){ wait(A a){ f=b!empt2(); f=a!empt(); f.get; await f?; } } empt(){} } } R. H¨ ahnle (TUD) Analysis of ESMs 31 / 54

  61. Idea for Deadlock Analysis Approximate statically “dependencies” that occur at runtime Dependencies Dependencies are created by tasks and COGs that wait for each other at synchronization points ( await g or get ) R. H¨ ahnle (TUD) Analysis of ESMs 32 / 54

  62. Idea for Deadlock Analysis Approximate statically “dependencies” that occur at runtime Dependencies Dependencies are created by tasks and COGs that wait for each other at synchronization points ( await g or get ) Which tasks/COGs wait for which other tasks/COGs? R. H¨ ahnle (TUD) Analysis of ESMs 32 / 54

  63. Idea for Deadlock Analysis Approximate statically “dependencies” that occur at runtime Dependencies Dependencies are created by tasks and COGs that wait for each other at synchronization points ( await g or get ) Which tasks/COGs wait for which other tasks/COGs? This is our plan: ◮ Obtain a finite representation (approximation) of all possible objects, COGs and tasks that can be created ◮ Analyse the future variables dependencies at synchronization points ◮ Approximate this information through a points-to analysis R. H¨ ahnle (TUD) Analysis of ESMs 32 / 54

  64. Abstract Dependencies Definition (Kinds of dependencies in an abstract representation of ABS) COG-task dependencies, when a task waits for the termination of another task but keeps the COG’s lock (using get ) task-task dependencies, when a task waits for the termination of another task with a non-blocking operation ( await g ) or with a blocking operation (using get ) task-COG dependencies between a task and the COG it belongs to R. H¨ ahnle (TUD) Analysis of ESMs 33 / 54

  65. Abstract Dependencies Definition (Kinds of dependencies in an abstract representation of ABS) COG-task dependencies, when a task waits for the termination of another task but keeps the COG’s lock (using get ) task-task dependencies, when a task waits for the termination of another task with a non-blocking operation ( await g ) or with a blocking operation (using get ) task-COG dependencies between a task and the COG it belongs to Cycles within dependencies can indicate deadlock situations R. H¨ ahnle (TUD) Analysis of ESMs 33 / 54

  66. Building the Abstract Dependency Graph main B { class B{ a= new cog A(); blk_c(C c,A a){ b= new cog B(); f=c!wait(a); c= new cog C(); f.get; b!blk_c(c,a); } a!blk_b(b); empt2(){} } } s : b s t r a c t C O G A A ◮ main , A , B , and C C class A{ class C{ blk_b(B b){ c t i o n s : z a t i o n i n s t r u S y n c h r o n i wait(A a){ f=b!empt2(); f=a!empt(); ◮ f.get in B f.get; await f?; } ◮ f.get in A } empt(){} } ◮ await f? in C } R. H¨ ahnle (TUD) Analysis of ESMs 34 / 54

  67. Building the Abstract Dependency Graph main B B { class B{ main a= new cog A(); blk_c(C c,A a){ B . blk_c b= new cog B(); f=c!wait(a); A b s t r a c t C O G s c= new cog C(); f.get; & t a s k s b!blk_c(c,a); } a!blk_b(b); empt2(){} B . empt2 } } s : b s t r a c t C O G A A ◮ main , A , B , and C A C C class A{ class C{ A . blk_b blk_b(B b){ c t i o n s : z a t i o n i n s t r u S y n c h r o n i C . wait wait(A a){ f=b!empt2(); f=a!empt(); ◮ f.get in B f.get; await f?; } ◮ f.get in A } A . empt empt(){} } ◮ await f? in C } R. H¨ ahnle (TUD) Analysis of ESMs 34 / 54

  68. Building the Abstract Dependency Graph B main B . blk_c COG-Task A A b b s s t t r r a a c c t t C C O O G G s s & & t t a a s s k k s s B . empt2 s : b s t r a c t C O G A ◮ main , A , B , and C A C A . blk_b c t i o n s : z a t i o n i n s t r u S y n c h r o n i C . wait ◮ f.get in B ◮ f.get in A A . empt ◮ await f? in C R. H¨ ahnle (TUD) Analysis of ESMs 34 / 54

  69. Building the Abstract Dependency Graph B main B . blk_c COG-Task A A b b s s t t r r a a c c t t C C O O G G s s & & Task-Task t t a a s s k k s s B . empt2 s : b s t r a c t C O G A ◮ main , A , B , and C A C A . blk_b c t i o n s : z a t i o n i n s t r u S y n c h r o n i C . wait ◮ f.get in B ◮ f.get in A A . empt ◮ await f? in C R. H¨ ahnle (TUD) Analysis of ESMs 34 / 54

  70. Building the Abstract Dependency Graph B main B . blk_c COG-Task A A b b s s t t r r a a c c t t C C O O G G Task-COG s s & & Task-Task t t a a s s k k s s B . empt2 s : b s t r a c t C O G A ◮ main , A , B , and C A C A . blk_b c t i o n s : z a t i o n i n s t r u S y n c h r o n i C . wait ◮ f.get in B ◮ f.get in A A . empt ◮ await f? in C R. H¨ ahnle (TUD) Analysis of ESMs 34 / 54

  71. Building the Abstract Dependency Graph B main B . blk_c COG-Task Deadlock A A b b s s t t r r a a c c t t C C O O G G Task-COG s s & & Task-Task Cycle t t a a s s k k s s B . empt2 s : b s t r a c t C O G A ◮ main , A , B , and C A C A . blk_b c t i o n s : z a t i o n i n s t r u S y n c h r o n i C . wait ◮ f.get in B ◮ f.get in A A . empt ◮ await f? in C R. H¨ ahnle (TUD) Analysis of ESMs 34 / 54

  72. Abstraction Is Too Coarse main B n i z a t i o n A d d s y n c h r o { class B{ a= new A(); ◮ Dependency cycle blk_c(C c,A a){ b= new B(); f=c!wait(a); remains in abstract c= new C(); f.get; graph f=b!blk_c(c,a); } await f?; ◮ But program is empt2(){} a!blk_b(b); } deadlock-free } ◮ Not all depen- dencies can occur A C C C simultaneously class A{ class C{ class C{ class C{ blk_b(B b){ wait(A a){ wait(A a){ wait(A a){ f=b!empt2(); f=a!empt(); f=a!empt(); f=a!empt(); f.get; await f?; await f?; await f?; } } } } empt(){} } } } } R. H¨ ahnle (TUD) Analysis of ESMs 35 / 54

  73. May-Happen-in-Parallel Information Problem Analysis ◮ Dependencies abstract away from all possible synchronizations ◮ A cycle only represents a real deadlock risk when synchronizations may occur simultaneously ◮ Annotate each dependency with the program point that causes it ◮ A may-happen-in-parallel (MHP) analysis tells whether two program points can be executed in parallel R. H¨ ahnle (TUD) Analysis of ESMs 36 / 54

  74. May-Happen-in-Parallel Information Problem Analysis ◮ Dependencies abstract away from all possible synchronizations ◮ A cycle only represents a real deadlock risk when synchronizations may occur simultaneously ◮ Annotate each dependency with the program point that causes it ◮ A may-happen-in-parallel (MHP) analysis tells whether two program points can be executed in parallel Definition (Feasible Cycle) A cycle (in the abstract dependency graph) is feasible if all program points in the edge annotations can happen in parallel. R. H¨ ahnle (TUD) Analysis of ESMs 36 / 54

  75. Applying MHP to Modified Example main B { class B{ a= new A(); l t o f M H P : R e s u blk_c(C c,A a){ b= new B(); f=c!wait(a); ◮ await f? in c= new C(); f.get; f=b!blk_c(c,a); main enforces } await f?; completion of empt2(){} a!blk_b(b); } blk_c in B } ◮ f.get in A �� f.get in B A C C C class A{ class C{ class C{ class C{ blk_b(B b){ wait(A a){ wait(A a){ wait(A a){ f=b!empt2(); f=a!empt(); f=a!empt(); f=a!empt(); f.get; await f?; await f?; await f?; } } } } empt(){} } } } } R. H¨ ahnle (TUD) Analysis of ESMs 37 / 54

  76. Applying MHP to Annotated Dependency Graph main B B . blk_c The cycle is unfeasible. f.get in A �� f.get in B f.get in B B . empt2 f.get in A A C A . blk_b C . wait A . empt R. H¨ ahnle (TUD) Analysis of ESMs 38 / 54

Recommend


More recommend