File: zune.pml

package info (click to toggle)
spin 6.4.5%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,636 kB
  • ctags: 2,878
  • sloc: ansic: 40,035; yacc: 996; makefile: 37; sh: 5
file content (70 lines) | stat: -rw-r--r-- 1,473 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
 * input: days elapsed since Jan 1, 1980
 * intended output: year and daynr in current year
 *
 * a bug caused all Zune-30 players to freeze on Dec 31, 2008
 * http://www.zuneboards.com/forums/zune-news/38143-cause-zune-30-leapyear-problem-isolated.html
 *
 * Wikepedia:
 * The bug was in the firmware clock-driver, which was written by Freescale
 * for their MC13783 PMIC processor. The same bug froze up Toshiba Gigabeat S
 * media players that share the same hardware and driver.
 */

#define IsLeapYear(y)	(((y%4 == 0) && (y%100 != 0)) || (y%400 == 0))

chan q = [0] of { short };

active proctype zune()
{	short year = 1980;
	short days;

end:	do
	:: q?days ->
S:		do
		:: days > 365 ->
			if
			:: IsLeapYear(year) ->
				if
				:: days > 366 ->
					days = days - 366;
					year++
				:: else
#ifdef FIX
					-> break
#endif
				fi
			:: else ->
				days = days - 365;
				year++
			fi
		:: else ->
			break
		od;
E:		printf("Year: %d, Day %d\n", year, days)
	od;
	/* check that the date is in a valid range */
	assert(days >= 1 && days <= 366);
	assert(days < 366 || IsLeapYear(year))
}

init {
	/* jan 1, 2008 */
	short days = (2008 - 1980) * 365 + (2008-1980)/4;

	if
	:: q!days + 365
	:: q!days + 366
	:: q!days + 367
	fi
}

ltl p1 { [] (( zune@S ) -> ( <> zune@E ) ) }

/* sample analysis:
	spin -a zune.pml	# spin version 6 or later
	cc -o pan pan.c		# compile
	./pan -a -N p1		# find matches of formula
	spin -t -p -l zune.pml	# replay error sequence
 */