-
Notifications
You must be signed in to change notification settings - Fork 0
/
nachos.go
92 lines (75 loc) · 2.07 KB
/
nachos.go
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.
package main
import (
"flag"
"os"
"os/signal"
"github.com/yashsriv/go-nachos/enums"
"github.com/yashsriv/go-nachos/global"
"github.com/yashsriv/go-nachos/machine"
"github.com/yashsriv/go-nachos/threads"
"github.com/yashsriv/go-nachos/userprog"
"github.com/yashsriv/go-nachos/utils"
)
func initialize() {
var randomYield = false
var debugArgs utils.StringFlag
var seed utils.Int64Flag
flag.Var(&debugArgs, "d", "set debug flags")
flag.Var(&seed, "rs", "seed random number generator")
var singleStep = flag.Bool("s", false, "debug the user program step by step")
flag.Parse()
if debugArgs.IsSet {
if debugArgs.Value == "" {
utils.InitDebug("+")
} else {
utils.InitDebug(debugArgs.Value)
}
}
if seed.IsSet {
utils.RandomInit(seed.Value)
randomYield = true
}
global.Stats = utils.Statistics{}
global.Interrupt = &machine.Interrupt{}
global.Interrupt.Init()
global.Scheduler = &threads.Scheduler{}
global.Scheduler.Init()
global.Timer = &machine.Timer{}
global.Timer.Init(func(arg interface{}) {
if global.Interrupt.GetStatus() != enums.IdleMode {
global.Interrupt.YieldOnReturn()
}
}, nil, randomYield)
userprog.Init()
global.Machine = &machine.Machine{}
if *singleStep {
global.Machine.EnableDebugging()
}
// We didn't explicitly allocate the current thread we are running in.
// But if it ever tries to yield, we better have a thread object to save
// its state.
global.CurrentThread = &threads.Thread{}
global.CurrentThread.Init("main")
global.CurrentThread.SetStatus(enums.Running)
global.Interrupt.Enable()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for _ = range c {
// sig is a ^C, handle it
utils.Cleanup()
}
}()
}
func main() {
var program utils.StringFlag
flag.Var(&program, "x", "runs a user program")
initialize()
if program.IsSet {
userprog.LaunchUserProcess(program.Value)
}
global.CurrentThread.FinishThread()
utils.Assert(false, "This point of code can never be reached")
}