~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/vnet/libxutil/kernel_stream.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU Lesser General Public License as published by
 
6
 * the Free Software Foundation; either version 2.1 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public License
 
15
 * along with this library; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 */
 
18
 
 
19
/** @file
 
20
 * An IOStream implementation using printk() for output.
 
21
 * Input is not implemented.
 
22
 */
 
23
#ifdef __KERNEL__
 
24
 
 
25
#include <linux/config.h>
 
26
#include <linux/module.h>
 
27
#include <linux/kernel.h>
 
28
#include <linux/types.h>
 
29
#include <linux/errno.h>
 
30
#include <linux/slab.h>
 
31
#include <linux/spinlock.h>
 
32
 
 
33
#include "kernel_stream.h"
 
34
#include "allocate.h"
 
35
 
 
36
/** Number of characters in the output buffer.
 
37
 * The kernel uses 1024 for printk, so that should suffice.
 
38
 */
 
39
#define BUF_N 1024
 
40
 
 
41
/** State for a kernel stream. */
 
42
typedef struct KernelData {
 
43
    /** Stream lock. We need a lock to serialize access to the stream. */
 
44
    spinlock_t lock;
 
45
    /** Saved flags for locking. */
 
46
    unsigned long flags;
 
47
    /** Size of the output buffer. */
 
48
    int buf_n;
 
49
    /** Output buffer. */
 
50
    char buf[BUF_N];
 
51
} KernelData;
 
52
 
 
53
static int kernel_write(IOStream *s, const void *msg, size_t n);
 
54
static void kernel_free(IOStream *s);
 
55
static void kernel_stream_lock(IOStream *s);
 
56
static void kernel_stream_unlock(IOStream *s);
 
57
 
 
58
/** Methods for a kernel stream. Output only. */
 
59
static const IOMethods kernel_methods = {
 
60
    write:  kernel_write,
 
61
    free:   kernel_free,
 
62
    lock:   kernel_stream_lock,
 
63
    unlock: kernel_stream_unlock,
 
64
};
 
65
 
 
66
/** Shared state for kernel streams.
 
67
 * All implementations write using printk, so we can use
 
68
 * shared state and avoid allocating it.
 
69
 */
 
70
static const KernelData kernel_data = {
 
71
    lock:  SPIN_LOCK_UNLOCKED,
 
72
    flags: 0,
 
73
    buf_n: BUF_N,
 
74
};
 
75
 
 
76
/** Stream for kernel printk. */
 
77
static IOStream iokernel = {
 
78
    methods: &kernel_methods,
 
79
    data:    &kernel_data,
 
80
    nofree:  1,
 
81
};
 
82
 
 
83
/** Stream for kernel printk. */
 
84
IOStream *iostdout = &iokernel;
 
85
 
 
86
/** Stream for kernel printk. */
 
87
IOStream *iostdin = &iokernel;
 
88
 
 
89
/** Stream for kernel printk. */
 
90
IOStream *iostderr = &iokernel;
 
91
 
 
92
/** Get an output-only stream implementation using
 
93
 * printk(). The stream uses static storage, and must not be freed.
 
94
 *
 
95
 * @return kernel stream
 
96
 */
 
97
IOStream get_stream_kernel(void){
 
98
    return iokernel;
 
99
}
 
100
 
 
101
/** Obtain the lock on the stream state.
 
102
 *
 
103
 * @param kdata stream state
 
104
 */
 
105
static inline void KernelData_lock(KernelData *kdata){
 
106
    spin_lock_irqsave(&kdata->lock, kdata->flags);
 
107
}
 
108
 
 
109
/** Release the lock on the stream state.
 
110
 *
 
111
 * @param kdata stream state
 
112
 */
 
113
static inline void KernelData_unlock(KernelData *kdata){
 
114
    spin_unlock_irqrestore(&kdata->lock, kdata->flags);
 
115
}
 
116
 
 
117
/** Get the stream state.
 
118
 *
 
119
 * @param s kernel stream
 
120
 * @return stream state
 
121
 */
 
122
static inline KernelData *get_kernel_data(IOStream *s){
 
123
    return (KernelData*)s->data;
 
124
}
 
125
 
 
126
/** Obtain the lock on the stream state.
 
127
 *
 
128
 * @param s stream
 
129
 */
 
130
void kernel_stream_lock(IOStream *s){
 
131
    KernelData_lock(get_kernel_data(s));
 
132
}
 
133
 
 
134
/** Release the lock on the stream state.
 
135
 *
 
136
 * @param s stream
 
137
 */
 
138
void kernel_stream_unlock(IOStream *s){
 
139
    KernelData_unlock(get_kernel_data(s));
 
140
}
 
141
 
 
142
/** Write to a kernel stream.
 
143
 *
 
144
 * @param stream kernel stream
 
145
 * @param format print format
 
146
 * @param args print arguments
 
147
 * @return result of the print
 
148
 */
 
149
static int kernel_write(IOStream *stream, const void *buf, size_t n){
 
150
    KernelData *kdata = get_kernel_data(stream);
 
151
    int k;
 
152
    k = kdata->buf_n - 1;
 
153
    if(n < k) k = n;
 
154
    memcpy(kdata->buf, buf, k);
 
155
    kdata->buf[k] = '\0';
 
156
    printk(kdata->buf);
 
157
    return k;
 
158
}
 
159
 
 
160
/** Free a kernel stream.
 
161
 * Frees the internal state of the stream.
 
162
 * Do not call this unless the stream was dynamically allocated.
 
163
 * Do not call this on a stream returned from get_stream_kernel().
 
164
 *
 
165
 * @param io stream to free
 
166
 */
 
167
static void kernel_free(IOStream *io){
 
168
    KernelData *kdata;
 
169
    if(io == &iokernel) return;
 
170
    kdata = get_kernel_data(io);
 
171
    memset(kdata, 0, sizeof(*kdata));
 
172
    deallocate(kdata);
 
173
}
 
174
#endif /* __KERNEL__ */
 
175
 
 
176
 
 
177
 
 
178