mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-12 09:01:16 +00:00
280 lines
8.0 KiB
Tcl
280 lines
8.0 KiB
Tcl
# See the file LICENSE for redistribution information.
|
|
#
|
|
# Copyright (c) 1996, 1997, 1998
|
|
# Sleepycat Software. All rights reserved.
|
|
#
|
|
# @(#)lock.tcl 10.6 (Sleepycat) 4/10/98
|
|
#
|
|
# Test driver for lock tests.
|
|
# General Multi Random
|
|
# Options are:
|
|
# -dir <directory in which to store mpool> Y Y Y
|
|
# -iterations <iterations> Y N Y
|
|
# -ldegree <number of locks per iteration> N N Y
|
|
# -maxlocks <locks in table> Y Y Y
|
|
# -objs <number of objects> N N Y
|
|
# -procs <number of processes to run> N N Y
|
|
# -reads <read ratio> N N Y
|
|
# -seeds <list of seed values for processes> N N Y
|
|
# -wait <wait interval after getting locks> N N Y
|
|
# -conflicts <conflict matrix; a list of lists> Y Y Y
|
|
proc lock_usage {} {
|
|
puts stderr "randomlock\n\t-dir <dir>\n\t-iterations <iterations>"
|
|
puts stderr "\t-conflicts <conflict matrix>"
|
|
puts stderr "\t-ldegree <locks per iteration>\n\t-maxlocks <n>"
|
|
puts stderr "\t-objs <objects>\n\t-procs <nprocs>\n\t-reads <%reads>"
|
|
puts stderr "\t-seeds <list of seeds>\n\t-wait <max wait interval>"
|
|
return
|
|
}
|
|
|
|
proc locktest { args } {
|
|
source ./include.tcl
|
|
|
|
|
|
# Set defaults
|
|
set conflicts { 0 0 0 0 0 1 0 1 1}
|
|
set iterations 1000
|
|
set ldegree 5
|
|
set maxlocks 1000
|
|
set objs 75
|
|
set procs 5
|
|
set reads 65
|
|
set seeds {}
|
|
set wait 5
|
|
for { set i 0 } { $i < [llength $args] } {incr i} {
|
|
switch -regexp -- [lindex $args $i] {
|
|
-c.* { incr i; set conflicts [linkdex $args $i] }
|
|
-d.* { incr i; set testdir [lindex $args $i] }
|
|
-i.* { incr i; set iterations [lindex $args $i] }
|
|
-l.* { incr i; set ldegree [lindex $args $i] }
|
|
-m.* { incr i; set maxlocks [lindex $args $i] }
|
|
-o.* { incr i; set objs [lindex $args $i] }
|
|
-p.* { incr i; set procs [lindex $args $i] }
|
|
-r.* { incr i; set reads [lindex $args $i] }
|
|
-s.* { incr i; set seeds [lindex $args $i] }
|
|
-w.* { incr i; set wait [lindex $args $i] }
|
|
default {
|
|
lock_usage
|
|
return
|
|
}
|
|
}
|
|
}
|
|
set nmodes [isqrt [llength $conflicts]]
|
|
|
|
if { [file exists $testdir] != 1 } {
|
|
exec $MKDIR $testdir
|
|
} elseif { [file isdirectory $testdir ] != 1 } {
|
|
error "$testdir is not a directory"
|
|
}
|
|
|
|
# Cleanup
|
|
lock_cleanup $testdir
|
|
|
|
# Open the lock
|
|
lock001 $maxlocks $nmodes $conflicts
|
|
# Now open the region we'll use for testing.
|
|
set lp [lock_open "" $DB_CREATE 0644 \
|
|
-maxlocks $maxlocks -nmodes $nmodes -conflicts $conflicts]
|
|
lock002 $lp $iterations $nmodes
|
|
error_check_good lock_close [$lp close] 0
|
|
set ret [ lock_unlink $testdir 0 ]
|
|
error_check_good lock_unlink $ret 0
|
|
|
|
lock003 $nmodes $conflicts
|
|
lock004 $maxlocks $conflicts
|
|
lock005 $testdir $iterations $maxlocks $procs $ldegree $objs \
|
|
$reads $wait $conflicts $seeds
|
|
}
|
|
|
|
# Make sure that we can create a region; destroy it, attach to it,
|
|
# detach from it, etc.
|
|
|
|
proc lock001 { maxl nmodes conf } {
|
|
source ./include.tcl
|
|
puts "Lock001: open/close test"
|
|
|
|
# Lock without create should fail.
|
|
set lp [lock_open "" 0 0644 -maxlocks $maxl -nmodes $nmodes \
|
|
-conflicts $conf]
|
|
error_check_good lock_open $lp NULL
|
|
|
|
# Now try to do open and create the region
|
|
set lp [lock_open "" $DB_CREATE 0644 \
|
|
-maxlocks $maxl -nmodes $nmodes -conflicts $conf]
|
|
error_check_bad lock_open $lp NULL
|
|
|
|
# Now try closing the region
|
|
set ret [ $lp close ]
|
|
error_check_good lock_close $ret 0
|
|
|
|
# Try reopening the region
|
|
set lp [lock_open "" 0 0644 -maxlocks $maxl -nmodes $nmodes \
|
|
-conflicts $conf]
|
|
error_check_bad lock_open $lp NULL
|
|
|
|
# Try unlinking without force (should fail)
|
|
set ret [ lock_unlink $testdir 0 ]
|
|
error_check_good lock_unlink $ret -1
|
|
|
|
# Close the region
|
|
error_check_good lock_close [$lp close] 0
|
|
|
|
# Create/open a new region
|
|
set lp [lock_open "" $DB_CREATE 0644 \
|
|
-maxlocks $maxl -nmodes $nmodes -conflicts $conf]
|
|
error_check_bad lock_open $lp NULL
|
|
|
|
# Close the region
|
|
set ret [$lp close]
|
|
error_check_good close $ret 0
|
|
|
|
# Finally, try unlinking the region without force and no live processes
|
|
set ret [ lock_unlink $testdir 0 ]
|
|
error_check_good lock_unlink $ret 0
|
|
|
|
# Now try creating the region in a different directory
|
|
if { [file exists $testdir/MYLOCK] != 1 } {
|
|
exec $MKDIR $testdir/MYLOCK
|
|
}
|
|
set lp [lock_open MYLOCK $DB_CREATE 0644 \
|
|
-maxlocks $maxl -nmodes $nmodes -conflicts $conf]
|
|
error_check_bad lock_open $lp NULL
|
|
error_check_good lock_close [$lp close] 0
|
|
error_check_good lock_unlink [lock_unlink $testdir/MYLOCK 0] 0
|
|
}
|
|
|
|
# Make sure that the basic lock tests work. Do some simple gets and puts for
|
|
# a single locker.
|
|
proc lock002 {lp iter nmodes} {
|
|
source ./include.tcl
|
|
puts "Lock002: test basic lock operations"
|
|
set locker 999
|
|
|
|
# Get and release each type of lock
|
|
for {set i 0} { $i < $nmodes } {incr i} {
|
|
set obj obj$i
|
|
set lockp [$lp get $locker $obj $i 0]
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
set ret [ $lockp put ]
|
|
error_check_good lock_put $ret 0
|
|
}
|
|
|
|
# Get a bunch of locks for the same locker; these should work
|
|
set obj OBJECT
|
|
for {set i 0} { $i < $nmodes } {incr i} {
|
|
set lockp [$lp get $locker $obj $i 0]
|
|
lappend locklist $lockp
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
}
|
|
release_list $locklist
|
|
|
|
set locklist {}
|
|
# Check that reference counted locks work
|
|
for {set i 0} { $i < 10 } {incr i} {
|
|
set lockp [$lp get $locker $obj $DB_LOCK_WRITE 1]
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
lappend locklist $lockp
|
|
}
|
|
release_list $locklist
|
|
|
|
# Finally try some failing locks
|
|
set locklist {}
|
|
for {set i 0} { $i < $nmodes } {incr i} {
|
|
set lockp [$lp get $locker $obj $i 0]
|
|
lappend locklist $lockp
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
}
|
|
|
|
# Change the locker
|
|
set locker [incr locker]
|
|
set blocklist {}
|
|
# Skip NO_LOCK lock.
|
|
for {set i 1} { $i < $nmodes } {incr i} {
|
|
set lockp [$lp get $locker $obj $i $DB_LOCK_NOWAIT ]
|
|
error_check_good lock_get [is_substr $lockp $lp] 0
|
|
error_check_good lock_get [is_blocked $lockp] 1
|
|
}
|
|
|
|
# Now release original locks
|
|
release_list $locklist
|
|
|
|
# Now re-acquire blocking locks
|
|
set locklist {}
|
|
for {set i 1} { $i < $nmodes } {incr i} {
|
|
set lockp [$lp get $locker $obj $i $DB_LOCK_NOWAIT ]
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
lappend locklist $lockp
|
|
}
|
|
|
|
# Now release new locks
|
|
release_list $locklist
|
|
}
|
|
|
|
proc lock003 { nmodes conflicts } {
|
|
source ./include.tcl
|
|
puts "Lock003: lock region grow test"
|
|
set lp [lock_open "" $DB_CREATE 0644 \
|
|
-maxlocks 10 -nmodes $nmodes -conflicts $conflicts ]
|
|
error_check_bad lock_open $lp NULL
|
|
|
|
# First, cause to grow because of locks
|
|
set locker 12345
|
|
set obj too_many_locks
|
|
set locklist {}
|
|
for {set i 0} { $i < 15 } { incr i } {
|
|
set lockp [$lp get $locker $obj $DB_LOCK_READ 0]
|
|
lappend locklist $lockp
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
}
|
|
release_list $locklist
|
|
|
|
# Next, cause to grow because of objects
|
|
set locklist {}
|
|
for {set i 0} { $i < 30 } { incr i } {
|
|
set lockp [$lp get $locker $obj$i $DB_LOCK_WRITE 0]
|
|
lappend locklist $lockp
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
}
|
|
release_list $locklist
|
|
|
|
# Finally, cause to grow because of string space; that means we need
|
|
# to lock objects with very long names
|
|
#
|
|
# XXX
|
|
# The loop end points, 50, and immediately below, 10, are for HPUX 9.05.
|
|
# If we grow the region more than 4 times on those systems, they crash.
|
|
set locker 12345
|
|
set longobj ""
|
|
for {set i 0} { $i < 50} {incr i} {
|
|
set longobj $longobj$obj
|
|
}
|
|
|
|
set locklist {}
|
|
for {set i 0} { $i < 10 } { incr i } {
|
|
set lockp [$lp get $locker $longobj$i $DB_LOCK_WRITE 0]
|
|
lappend locklist $lockp
|
|
error_check_good lock_get [is_blocked $lockp] 0
|
|
error_check_good lock_get [is_substr $lockp $lp] 1
|
|
}
|
|
release_list $locklist
|
|
|
|
error_check_good lock_close [$lp close] 0
|
|
}
|
|
|
|
|
|
# Blocked locks appear as lockmgrN.lockM\nBLOCKED
|
|
proc is_blocked { l } {
|
|
if { [string compare $l BLOCKED ] == 0 } {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|