OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [expvar/] [expvar.go] - Blame information for rev 848

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Package expvar provides a standardized interface to public variables, such
6
// as operation counters in servers. It exposes these variables via HTTP at
7
// /debug/vars in JSON format.
8
//
9
// Operations to set or modify these public variables are atomic.
10
//
11
// In addition to adding the HTTP handler, this package registers the
12
// following variables:
13
//
14
//      cmdline   os.Args
15
//      memstats  runtime.Memstats
16
//
17
// The package is sometimes only imported for the side effect of
18
// registering its HTTP handler and the above variables.  To use it
19
// this way, link this package into your program:
20
//      import _ "expvar"
21
//
22
package expvar
23
 
24
import (
25
        "bytes"
26
        "encoding/json"
27
        "fmt"
28
        "log"
29
        "net/http"
30
        "os"
31
        "runtime"
32
        "strconv"
33
        "sync"
34
)
35
 
36
// Var is an abstract type for all exported variables.
37
type Var interface {
38
        String() string
39
}
40
 
41
// Int is a 64-bit integer variable that satisfies the Var interface.
42
type Int struct {
43
        i  int64
44
        mu sync.Mutex
45
}
46
 
47
func (v *Int) String() string { return strconv.FormatInt(v.i, 10) }
48
 
49
func (v *Int) Add(delta int64) {
50
        v.mu.Lock()
51
        defer v.mu.Unlock()
52
        v.i += delta
53
}
54
 
55
func (v *Int) Set(value int64) {
56
        v.mu.Lock()
57
        defer v.mu.Unlock()
58
        v.i = value
59
}
60
 
61
// Float is a 64-bit float variable that satisfies the Var interface.
62
type Float struct {
63
        f  float64
64
        mu sync.Mutex
65
}
66
 
67
func (v *Float) String() string { return strconv.FormatFloat(v.f, 'g', -1, 64) }
68
 
69
// Add adds delta to v.
70
func (v *Float) Add(delta float64) {
71
        v.mu.Lock()
72
        defer v.mu.Unlock()
73
        v.f += delta
74
}
75
 
76
// Set sets v to value.
77
func (v *Float) Set(value float64) {
78
        v.mu.Lock()
79
        defer v.mu.Unlock()
80
        v.f = value
81
}
82
 
83
// Map is a string-to-Var map variable that satisfies the Var interface.
84
type Map struct {
85
        m  map[string]Var
86
        mu sync.RWMutex
87
}
88
 
89
// KeyValue represents a single entry in a Map.
90
type KeyValue struct {
91
        Key   string
92
        Value Var
93
}
94
 
95
func (v *Map) String() string {
96
        v.mu.RLock()
97
        defer v.mu.RUnlock()
98
        b := new(bytes.Buffer)
99
        fmt.Fprintf(b, "{")
100
        first := true
101
        for key, val := range v.m {
102
                if !first {
103
                        fmt.Fprintf(b, ", ")
104
                }
105
                fmt.Fprintf(b, "\"%s\": %v", key, val)
106
                first = false
107
        }
108
        fmt.Fprintf(b, "}")
109
        return b.String()
110
}
111
 
112
func (v *Map) Init() *Map {
113
        v.m = make(map[string]Var)
114
        return v
115
}
116
 
117
func (v *Map) Get(key string) Var {
118
        v.mu.RLock()
119
        defer v.mu.RUnlock()
120
        return v.m[key]
121
}
122
 
123
func (v *Map) Set(key string, av Var) {
124
        v.mu.Lock()
125
        defer v.mu.Unlock()
126
        v.m[key] = av
127
}
128
 
129
func (v *Map) Add(key string, delta int64) {
130
        v.mu.RLock()
131
        av, ok := v.m[key]
132
        v.mu.RUnlock()
133
        if !ok {
134
                // check again under the write lock
135
                v.mu.Lock()
136
                if _, ok = v.m[key]; !ok {
137
                        av = new(Int)
138
                        v.m[key] = av
139
                }
140
                v.mu.Unlock()
141
        }
142
 
143
        // Add to Int; ignore otherwise.
144
        if iv, ok := av.(*Int); ok {
145
                iv.Add(delta)
146
        }
147
}
148
 
149
// AddFloat adds delta to the *Float value stored under the given map key.
150
func (v *Map) AddFloat(key string, delta float64) {
151
        v.mu.RLock()
152
        av, ok := v.m[key]
153
        v.mu.RUnlock()
154
        if !ok {
155
                // check again under the write lock
156
                v.mu.Lock()
157
                if _, ok = v.m[key]; !ok {
158
                        av = new(Float)
159
                        v.m[key] = av
160
                }
161
                v.mu.Unlock()
162
        }
163
 
164
        // Add to Float; ignore otherwise.
165
        if iv, ok := av.(*Float); ok {
166
                iv.Add(delta)
167
        }
168
}
169
 
170
// Do calls f for each entry in the map.
171
// The map is locked during the iteration,
172
// but existing entries may be concurrently updated.
173
func (v *Map) Do(f func(KeyValue)) {
174
        v.mu.RLock()
175
        defer v.mu.RUnlock()
176
        for k, v := range v.m {
177
                f(KeyValue{k, v})
178
        }
179
}
180
 
181
// String is a string variable, and satisfies the Var interface.
182
type String struct {
183
        s string
184
}
185
 
186
func (v *String) String() string { return strconv.Quote(v.s) }
187
 
188
func (v *String) Set(value string) { v.s = value }
189
 
190
// Func implements Var by calling the function
191
// and formatting the returned value using JSON.
192
type Func func() interface{}
193
 
194
func (f Func) String() string {
195
        v, _ := json.Marshal(f())
196
        return string(v)
197
}
198
 
199
// All published variables.
200
var (
201
        mutex sync.RWMutex
202
        vars  map[string]Var = make(map[string]Var)
203
)
204
 
205
// Publish declares a named exported variable. This should be called from a
206
// package's init function when it creates its Vars. If the name is already
207
// registered then this will log.Panic.
208
func Publish(name string, v Var) {
209
        mutex.Lock()
210
        defer mutex.Unlock()
211
        if _, existing := vars[name]; existing {
212
                log.Panicln("Reuse of exported var name:", name)
213
        }
214
        vars[name] = v
215
}
216
 
217
// Get retrieves a named exported variable.
218
func Get(name string) Var {
219
        mutex.RLock()
220
        defer mutex.RUnlock()
221
        return vars[name]
222
}
223
 
224
// Convenience functions for creating new exported variables.
225
 
226
func NewInt(name string) *Int {
227
        v := new(Int)
228
        Publish(name, v)
229
        return v
230
}
231
 
232
func NewFloat(name string) *Float {
233
        v := new(Float)
234
        Publish(name, v)
235
        return v
236
}
237
 
238
func NewMap(name string) *Map {
239
        v := new(Map).Init()
240
        Publish(name, v)
241
        return v
242
}
243
 
244
func NewString(name string) *String {
245
        v := new(String)
246
        Publish(name, v)
247
        return v
248
}
249
 
250
// Do calls f for each exported variable.
251
// The global variable map is locked during the iteration,
252
// but existing entries may be concurrently updated.
253
func Do(f func(KeyValue)) {
254
        mutex.RLock()
255
        defer mutex.RUnlock()
256
        for k, v := range vars {
257
                f(KeyValue{k, v})
258
        }
259
}
260
 
261
func expvarHandler(w http.ResponseWriter, r *http.Request) {
262
        w.Header().Set("Content-Type", "application/json; charset=utf-8")
263
        fmt.Fprintf(w, "{\n")
264
        first := true
265
        Do(func(kv KeyValue) {
266
                if !first {
267
                        fmt.Fprintf(w, ",\n")
268
                }
269
                first = false
270
                fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
271
        })
272
        fmt.Fprintf(w, "\n}\n")
273
}
274
 
275
func cmdline() interface{} {
276
        return os.Args
277
}
278
 
279
func memstats() interface{} {
280
        stats := new(runtime.MemStats)
281
        runtime.ReadMemStats(stats)
282
        return *stats
283
}
284
 
285
func init() {
286
        http.HandleFunc("/debug/vars", expvarHandler)
287
        Publish("cmdline", Func(cmdline))
288
        Publish("memstats", Func(memstats))
289
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.