mutex.tcl
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. # See the file LICENSE for redistribution information.
  2. #
  3. # Copyright (c) 1996, 1997, 1998, 1999, 2000
  4. # Sleepycat Software.  All rights reserved.
  5. #
  6. # $Id: mutex.tcl,v 11.18 2000/09/01 19:24:59 krinsky Exp $
  7. #
  8. # Exercise mutex functionality.
  9. # Options are:
  10. # -dir <directory in which to store mpool>
  11. # -iter <iterations>
  12. # -mdegree <number of mutexes per iteration>
  13. # -nmutex <number of mutexes>
  14. # -procs <number of processes to run>
  15. # -wait <wait interval after getting locks>
  16. proc mutex_usage {} {
  17. puts stderr "mutexnt-dir <dir>nt-iter <iterations>"
  18. puts stderr "t-mdegree <locks per iteration>nt-nmutex <n>"
  19. puts stderr "t-procs <nprocs>"
  20. puts stderr "nt-wait <max wait interval>"
  21. return
  22. }
  23. proc mutex { args } {
  24. source ./include.tcl
  25. set dir db
  26. set iter 500
  27. set mdegree 3
  28. set nmutex 20
  29. set procs 5
  30. set wait 2
  31. for { set i 0 } { $i < [llength $args] } {incr i} {
  32. switch -regexp -- [lindex $args $i] {
  33. -d.* { incr i; set testdir [lindex $args $i] }
  34. -i.* { incr i; set iter [lindex $args $i] }
  35. -m.* { incr i; set mdegree [lindex $args $i] }
  36. -n.* { incr i; set nmutex [lindex $args $i] }
  37. -p.* { incr i; set procs [lindex $args $i] }
  38. -w.* { incr i; set wait [lindex $args $i] }
  39. default {
  40. puts -nonewline "FAIL:[timestamp] Usage: "
  41. mutex_usage
  42. return
  43. }
  44. }
  45. }
  46. if { [file exists $testdir/$dir] != 1 } {
  47. file mkdir $testdir/$dir
  48. } elseif { [file isdirectory $testdir/$dir ] != 1 } {
  49. error "$testdir/$dir is not a directory"
  50. }
  51. # Basic sanity tests
  52. mutex001 $testdir $nmutex
  53. # Basic synchronization tests
  54. mutex002 $testdir $nmutex
  55. # Multiprocess tests
  56. mutex003 $testdir $iter $nmutex $procs $mdegree $wait
  57. }
  58. proc mutex001 { dir nlocks } {
  59. source ./include.tcl
  60. puts "Mutex001: Basic functionality"
  61. env_cleanup $dir
  62. # Test open w/out create; should fail
  63. error_check_bad 
  64.     env_open [catch {berkdb env -lock -home $dir} env] 0
  65. # Now open for real
  66. set env [berkdb env -create -mode 0644 -lock -home $dir]
  67. error_check_good env_open [is_valid_env $env] TRUE
  68. set m [$env mutex 0644 $nlocks]
  69. error_check_good mutex_init [is_valid_mutex $m $env] TRUE
  70. # Get, set each mutex; sleep, then get Release
  71. for { set i 0 } { $i < $nlocks } { incr i } {
  72. set r [$m get $i ]
  73. error_check_good mutex_get $r 0
  74. set r [$m setval $i $i]
  75. error_check_good mutex_setval $r 0
  76. }
  77. tclsleep 5
  78. for { set i 0 } { $i < $nlocks } { incr i } {
  79. set r [$m getval $i]
  80. error_check_good mutex_getval $r $i
  81. set r [$m release $i ]
  82. error_check_good mutex_get $r 0
  83. }
  84. error_check_good mutex_close [$m close] 0
  85. error_check_good env_close [$env close] 0
  86. puts "Mutex001: completed successfully."
  87. }
  88. # Test basic synchronization
  89. proc mutex002 { dir nlocks } {
  90. source ./include.tcl
  91. puts "Mutex002: Basic synchronization"
  92. env_cleanup $dir
  93. # Fork off child before we open any files.
  94. set f1 [open |$tclsh_path r+]
  95. puts $f1 "source $test_path/test.tcl"
  96. flush $f1
  97. # Open the environment and the mutex locally
  98. set local_env [berkdb env -create -mode 0644 -lock -home $dir]
  99. error_check_good env_open [is_valid_env $local_env] TRUE
  100. set local_mutex [$local_env mutex 0644 $nlocks]
  101. error_check_good 
  102.     mutex_init [is_valid_mutex $local_mutex $local_env] TRUE
  103. # Open the environment and the mutex remotely
  104. set remote_env [send_cmd $f1 "berkdb env -lock -home $dir"]
  105. error_check_good remote:env_open [is_valid_env $remote_env] TRUE
  106. set remote_mutex [send_cmd $f1 "$remote_env mutex 0644 $nlocks"]
  107. error_check_good 
  108.     mutex_init [is_valid_mutex $remote_mutex $remote_env] TRUE
  109. # Do a get here, then set the value to be pid.
  110. # On the remote side fire off a get and getval.
  111. set r [$local_mutex get 1]
  112. error_check_good lock_get $r 0
  113. set r [$local_mutex setval 1 [pid]]
  114. error_check_good lock_get $r 0
  115. # Now have the remote side request the lock and check its
  116. # value. Then wait 5 seconds, release the mutex and see
  117. # what the remote side returned.
  118. send_timed_cmd $f1 1 "$remote_mutex get 1"
  119. send_timed_cmd $f1 1 "set ret [$remote_mutex getval 1]"
  120. # Now sleep before resetting and releasing lock
  121. tclsleep 5
  122. set newv [expr [pid] - 1]
  123. set r [$local_mutex setval 1 $newv]
  124. error_check_good mutex_setval $r 0
  125. set r [$local_mutex release 1]
  126. error_check_good mutex_release $r 0
  127. # Now get the result from the other script
  128. # Timestamp
  129. set result [rcv_result $f1]
  130. error_check_good lock_get:remote_time [expr $result > 4] 1
  131. # Timestamp
  132. set result [rcv_result $f1]
  133. # Mutex value
  134. set result [send_cmd $f1 "puts $ret"]
  135. error_check_good lock_get:remote_getval $result $newv
  136. # Close down the remote
  137. set ret [send_cmd $f1 "$remote_mutex close" 5]
  138. # Not sure why we need this, but we do... an extra blank line
  139. # someone gets output somewhere
  140. gets $f1 ret
  141. error_check_good remote:mutex_close $ret 0
  142. set ret [send_cmd $f1 "$remote_env close"]
  143. error_check_good remote:env_close $ret 0
  144. catch { close $f1 } result
  145. set ret [$local_mutex close]
  146. error_check_good local:mutex_close $ret 0
  147. set ret [$local_env close]
  148. error_check_good local:env_close $ret 0
  149. puts "Mutex002: completed successfully."
  150. }
  151. # Generate a bunch of parallel
  152. # testers that try to randomly obtain locks.
  153. proc mutex003 { dir iter nmutex procs mdegree wait } {
  154. source ./include.tcl
  155. puts "Mutex003: Multi-process random mutex test ($procs processes)"
  156. env_cleanup $dir
  157. # Now open the region we'll use for multiprocess testing.
  158. set env [berkdb env -create -mode 0644 -lock -home $dir]
  159. error_check_good env_open [is_valid_env $env] TRUE
  160. set mutex [$env mutex 0644 $nmutex]
  161. error_check_good mutex_init [is_valid_mutex $mutex $env] TRUE
  162. error_check_good mutex_close [$mutex close] 0
  163. # Now spawn off processes
  164. set proclist {}
  165. for { set i 0 } {$i < $procs} {incr i} {
  166. puts "$tclsh_path
  167.     $test_path/mutexscript.tcl $dir
  168.     $iter $nmutex $wait $mdegree > $testdir/$i.mutexout &"
  169. set p [exec $tclsh_path $test_path/wrap.tcl 
  170.     mutexscript.tcl $testdir/$i.mutexout $dir
  171.     $iter $nmutex $wait $mdegree &]
  172. lappend proclist $p
  173. }
  174. puts "Mutex003: $procs independent processes now running"
  175. watch_procs
  176. error_check_good env_close [$env close] 0
  177. # Remove output files
  178. for { set i 0 } {$i < $procs} {incr i} {
  179. fileremove -f $dir/$i.mutexout
  180. }
  181. }