Deleted Added
full compact
tty_inq.c (181905) tty_inq.c (182471)
1/*-
2 * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Portions of this software were developed under sponsorship from Snow
6 * B.V., the Netherlands.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Portions of this software were developed under sponsorship from Snow
6 * B.V., the Netherlands.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/kern/tty_inq.c 181905 2008-08-20 08:31:58Z ed $");
31__FBSDID("$FreeBSD: head/sys/kern/tty_inq.c 182471 2008-08-30 09:18:27Z ed $");
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/lock.h>
36#include <sys/queue.h>
37#include <sys/sysctl.h>
38#include <sys/systm.h>
39#include <sys/tty.h>

--- 44 unchanged lines hidden (view full) ---

84 char tib_data[TTYINQ_DATASIZE];
85};
86
87static uma_zone_t ttyinq_zone;
88
89void
90ttyinq_setsize(struct ttyinq *ti, struct tty *tp, size_t size)
91{
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/lock.h>
36#include <sys/queue.h>
37#include <sys/sysctl.h>
38#include <sys/systm.h>
39#include <sys/tty.h>

--- 44 unchanged lines hidden (view full) ---

84 char tib_data[TTYINQ_DATASIZE];
85};
86
87static uma_zone_t ttyinq_zone;
88
89void
90ttyinq_setsize(struct ttyinq *ti, struct tty *tp, size_t size)
91{
92 unsigned int nblocks;
93 struct ttyinq_block *tib;
94
92 struct ttyinq_block *tib;
93
95 nblocks = howmany(size, TTYINQ_DATASIZE);
94 ti->ti_quota = howmany(size, TTYINQ_DATASIZE);
96
95
97 while (nblocks > ti->ti_nblocks) {
96 while (ti->ti_quota > ti->ti_nblocks) {
98 /*
99 * List is getting bigger.
100 * Add new blocks to the tail of the list.
101 *
102 * We must unlock the TTY temporarily, because we need
103 * to allocate memory. This won't be a problem, because
104 * in the worst case, another thread ends up here, which
105 * may cause us to allocate too many blocks, but this
106 * will be caught by the loop below.
107 */
108 tty_unlock(tp);
109 tib = uma_zalloc(ttyinq_zone, M_WAITOK);
110 tty_lock(tp);
111
97 /*
98 * List is getting bigger.
99 * Add new blocks to the tail of the list.
100 *
101 * We must unlock the TTY temporarily, because we need
102 * to allocate memory. This won't be a problem, because
103 * in the worst case, another thread ends up here, which
104 * may cause us to allocate too many blocks, but this
105 * will be caught by the loop below.
106 */
107 tty_unlock(tp);
108 tib = uma_zalloc(ttyinq_zone, M_WAITOK);
109 tty_lock(tp);
110
112 if (tty_gone(tp))
113 return;
114
115 TAILQ_INSERT_TAIL(&ti->ti_list, tib, tib_list);
116 ti->ti_nblocks++;
117 }
111 TAILQ_INSERT_TAIL(&ti->ti_list, tib, tib_list);
112 ti->ti_nblocks++;
113 }
114}
118
115
119 while (nblocks < ti->ti_nblocks) {
120 /*
121 * List is getting smaller. Remove unused blocks at the
122 * end. This means we cannot guarantee this routine
123 * shrinks buffers properly, when we need to reclaim
124 * more space than there is available.
125 *
126 * XXX TODO: Two solutions here:
127 * - Throw data away
128 * - Temporarily hit the watermark until enough data has
129 * been flushed, so we can remove the blocks.
130 */
116void
117ttyinq_free(struct ttyinq *ti)
118{
119 struct ttyinq_block *tib;
120
121 ttyinq_flush(ti);
122 ti->ti_quota = 0;
131
123
132 if (ti->ti_end == 0)
133 tib = TAILQ_FIRST(&ti->ti_list);
134 else
135 tib = TAILQ_NEXT(ti->ti_lastblock, tib_list);
136 if (tib == NULL)
137 break;
124 while ((tib = TAILQ_FIRST(&ti->ti_list)) != NULL) {
138 TAILQ_REMOVE(&ti->ti_list, tib, tib_list);
139 uma_zfree(ttyinq_zone, tib);
140 ti->ti_nblocks--;
141 }
125 TAILQ_REMOVE(&ti->ti_list, tib, tib_list);
126 uma_zfree(ttyinq_zone, tib);
127 ti->ti_nblocks--;
128 }
129
130 MPASS(ti->ti_nblocks == 0);
142}
143
144int
145ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
146 size_t rlen, size_t flen)
147{
148
149 MPASS(rlen <= uio->uio_resid);

--- 62 unchanged lines hidden (view full) ---

212 * userspace. We may need to flush trailing
213 * bytes, like EOF characters.
214 */
215 tty_unlock(tp);
216 error = uiomove(tib->tib_data + cbegin,
217 clen - flen, uio);
218 tty_lock(tp);
219
131}
132
133int
134ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
135 size_t rlen, size_t flen)
136{
137
138 MPASS(rlen <= uio->uio_resid);

--- 62 unchanged lines hidden (view full) ---

201 * userspace. We may need to flush trailing
202 * bytes, like EOF characters.
203 */
204 tty_unlock(tp);
205 error = uiomove(tib->tib_data + cbegin,
206 clen - flen, uio);
207 tty_lock(tp);
208
220 if (tty_gone(tp)) {
221 /* Something went bad - discard this block. */
209 /* Block can now be readded to the list. */
210 if (ti->ti_quota <= ti->ti_nblocks) {
222 uma_zfree(ttyinq_zone, tib);
211 uma_zfree(ttyinq_zone, tib);
223 return (ENXIO);
212 } else {
213 TAILQ_INSERT_TAIL(&ti->ti_list, tib, tib_list);
214 ti->ti_nblocks++;
224 }
215 }
225 /* Block can now be readded to the list. */
226 /*
227 * XXX: we could remove the blocks here when the
228 * queue was shrunk, but still in use. See
229 * ttyinq_setsize().
230 */
231 TAILQ_INSERT_TAIL(&ti->ti_list, tib, tib_list);
232 ti->ti_nblocks++;
233 if (error != 0)
234 return (error);
235 } else {
236 char ob[TTYINQ_DATASIZE - 1];
237 atomic_add_long(&ttyinq_nslow, 1);
238
239 /*
240 * Slow path: store data in a temporary buffer.
241 */
242 memcpy(ob, tib->tib_data + cbegin, clen - flen);
243 ti->ti_begin += clen;
244 MPASS(ti->ti_begin < TTYINQ_DATASIZE);
245
246 /* Temporary unlock and copy the data to userspace. */
247 tty_unlock(tp);
248 error = uiomove(ob, clen - flen, uio);
249 tty_lock(tp);
216 } else {
217 char ob[TTYINQ_DATASIZE - 1];
218 atomic_add_long(&ttyinq_nslow, 1);
219
220 /*
221 * Slow path: store data in a temporary buffer.
222 */
223 memcpy(ob, tib->tib_data + cbegin, clen - flen);
224 ti->ti_begin += clen;
225 MPASS(ti->ti_begin < TTYINQ_DATASIZE);
226
227 /* Temporary unlock and copy the data to userspace. */
228 tty_unlock(tp);
229 error = uiomove(ob, clen - flen, uio);
230 tty_lock(tp);
250
251 if (error != 0)
252 return (error);
253 if (tty_gone(tp))
254 return (ENXIO);
255 }
231 }
232
233 if (error != 0)
234 return (error);
235 if (tty_gone(tp))
236 return (ENXIO);
256 }
257
258 return (0);
259}
260
261static __inline void
262ttyinq_set_quotes(struct ttyinq_block *tib, size_t offset,
263 size_t length, int value)

--- 239 unchanged lines hidden ---
237 }
238
239 return (0);
240}
241
242static __inline void
243ttyinq_set_quotes(struct ttyinq_block *tib, size_t offset,
244 size_t length, int value)

--- 239 unchanged lines hidden ---