1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1996,2008 Oracle.  All rights reserved.
4#
5# $Id: mpoolscript.tcl,v 12.7 2008/01/08 20:58:53 bostic Exp $
6#
7# Random multiple process mpool tester.
8# Usage: mpoolscript dir id numiters numfiles numpages sleepint
9# dir: lock directory.
10# id: Unique identifier for this process.
11# maxprocs: Number of procs in this test.
12# numiters: Total number of iterations.
13# pgsizes: Pagesizes for the different files.  Length of this item indicates
14#		how many files to use.
15# numpages: Number of pages per file.
16# sleepint: Maximum sleep interval.
17# flags: Flags for env open
18
19source ./include.tcl
20source $test_path/test.tcl
21source $test_path/testutils.tcl
22
23set usage \
24   "mpoolscript dir id maxprocs numiters pgsizes numpages sleepint flags"
25
26# Verify usage
27if { $argc != 8 } {
28	puts stderr "FAIL:[timestamp] Usage: $usage"
29	puts $argc
30	exit
31}
32
33# Initialize arguments
34set dir [lindex $argv 0]
35set id [lindex $argv 1]
36set maxprocs [lindex $argv 2]
37set numiters [ lindex $argv 3 ]
38set pgsizes [ lindex $argv 4 ]
39set numpages [ lindex $argv 5 ]
40set sleepint [ lindex $argv 6 ]
41set flags [ lindex $argv 7]
42
43# Initialize seed
44global rand_init
45berkdb srand $rand_init
46
47# Give time for all processes to start up.
48tclsleep 10
49
50puts -nonewline "Beginning execution for $id: $maxprocs $dir $numiters"
51puts " $pgsizes $numpages $sleepint"
52flush stdout
53
54# Figure out how small/large to make the cache
55set max 0
56foreach i $pgsizes {
57	if { $i > $max } {
58		set max $i
59	}
60}
61
62set cache [list 0 [expr $maxprocs * ([lindex $pgsizes 0] + $max)] 1]
63set env_cmd {berkdb_env -lock -cachesize $cache -home $dir}
64set e [eval $env_cmd $flags]
65error_check_good env_open [is_valid_env $e] TRUE
66
67# Now open files
68set mpools {}
69set nfiles 0
70foreach psize $pgsizes {
71	set mp [$e mpool -create -mode 0644 -pagesize $psize file$nfiles]
72	error_check_good memp_fopen:$nfiles [is_valid_mpool $mp $e] TRUE
73	lappend mpools $mp
74	incr nfiles
75}
76
77puts "Establishing long-term pin on file 0 page $id for process $id"
78
79# Set up the long-pin page
80set locker [$e lock_id]
81set lock [$e lock_get write $locker 0:$id]
82error_check_good lock_get [is_valid_lock $lock $e] TRUE
83
84set mp [lindex $mpools 0]
85set master_page [$mp get -create -dirty $id]
86error_check_good mp_get:$master_page [is_valid_page $master_page $mp] TRUE
87
88set r [$master_page init MASTER$id]
89error_check_good page_init $r 0
90
91# Release the lock but keep the page pinned
92set r [$lock put]
93error_check_good lock_put $r 0
94
95# Main loop.  On each iteration, we'll check every page in each of
96# of the files.  On any file, if we see the appropriate tag in the
97# field, we'll rewrite the page, else we won't.  Keep track of
98# how many pages we actually process.
99set pages 0
100for { set iter 0 } { $iter < $numiters } { incr iter } {
101	puts "[timestamp]: iteration $iter, $pages pages set so far"
102	flush stdout
103	for { set fnum 1 } { $fnum < $nfiles } { incr fnum } {
104		if { [expr $fnum % 2 ] == 0 } {
105			set pred [expr ($id + $maxprocs - 1) % $maxprocs]
106		} else {
107			set pred [expr ($id + $maxprocs + 1) % $maxprocs]
108		}
109
110		set mpf [lindex $mpools $fnum]
111		for { set p 0 } { $p < $numpages } { incr p } {
112			set lock [$e lock_get write $locker $fnum:$p]
113			error_check_good lock_get:$fnum:$p \
114			    [is_valid_lock $lock $e] TRUE
115
116			# Now, get the page
117			set pp [$mpf get -create -dirty $p]
118			error_check_good page_get:$fnum:$p \
119			    [is_valid_page $pp $mpf] TRUE
120
121			if { [$pp is_setto $pred] == 0 || [$pp is_setto 0] == 0 } {
122				# Set page to self.
123				set r [$pp init $id]
124				error_check_good page_init:$fnum:$p $r 0
125				incr pages
126				set r [$pp put]
127				error_check_good page_put:$fnum:$p $r 0
128			} else {
129				error_check_good page_put:$fnum:$p [$pp put] 0
130			}
131			error_check_good lock_put:$fnum:$p [$lock put] 0
132		}
133	}
134	tclsleep [berkdb random_int 1 $sleepint]
135}
136
137# Now verify your master page, release its pin, then verify everyone else's
138puts "$id: End of run verification of master page"
139set r [$master_page is_setto MASTER$id]
140error_check_good page_check $r 1
141set r [$master_page put]
142error_check_good page_put $r 0
143
144set i [expr ($id + 1) % $maxprocs]
145set mpf [lindex $mpools 0]
146
147while { $i != $id } {
148	set p [$mpf get -create $i]
149	error_check_good mp_get [is_valid_page $p $mpf] TRUE
150
151	if { [$p is_setto MASTER$i] != 1 } {
152		puts "Warning: Master page $i not set."
153	}
154	error_check_good page_put:$p [$p put] 0
155
156	set i [expr ($i + 1) % $maxprocs]
157}
158
159# Close files
160foreach i $mpools {
161	set r [$i close]
162	error_check_good mpf_close $r 0
163}
164
165# Close environment system
166set r [$e close]
167error_check_good env_close $r 0
168
169puts "[timestamp] $id Complete"
170flush stdout
171