lkml.org 
[lkml]   [1996]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectConsole speedup patch
Date
Here is a patch I've made to implement the put_char() and flush_chars()
routines for the console device. The result is that con_write is not
called for each character and the console output is quite a bit faster.
I wrote a test program to output blocks of 'a's to the screen and the
result on 8K blocks is that the new console code is 5.9 times faster
(423280 chars/sec vrs 71813 chars/sec). Also the speedup seems fairly
consistant in that using 4K blocks its also about 6 times faster.

I had noticed when installing Caldera (which uses a text/color/boxes/...
kind of install) that even with the Pentium 120 I was installing on I
could watch the redrawing of the screen as Caldera was installing the
packages. It looked kind of strange and made the system look slow. I
hope this patch will fix that kind of thing. Let me know if this patch
works well for you!

--- linux/drivers/char/console.c.orig Tue Sep 3 16:25:46 1996
+++ linux/drivers/char/console.c Wed Sep 4 01:25:26 1996
@@ -308,7 +308,7 @@
if (i >= MAX_NR_CONSOLES)
return -ENXIO;
if (!vc_cons[i].d) {
- long p, q;
+ long p, q, b;

/* prevent users from taking too much memory */
if (i >= MAX_NR_USER_CONSOLES && !suser())
@@ -325,10 +325,18 @@
kfree_s((char *) q, video_screen_size);
return -ENOMEM;
}
+ b = get_free_page(GFP_KERNEL);
+ if (!b) {
+ kfree_s((char *) p, structsize);
+ kfree_s((char *) q, video_screen_size);
+ return -ENOMEM;
+ }

vc_cons[i].d = (struct vc_data *) p;
p += sizeof(struct vc_data);
vt_cons[i] = (struct vt_struct *) p;
+ vt_cons[i]->xmit_buf = (unsigned char *)b;
+ vt_cons[i]->xmit_cnt = 0;
vc_scrbuf[i] = (unsigned short *) q;
vc_cons[i].d->vc_kmalloced = 1;
vc_cons[i].d->vc_screenbuf_size = video_screen_size;
@@ -1828,16 +1836,51 @@
return n;
}

+static void con_put_char(struct tty_struct * tty, unsigned char ch)
+{
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+ unsigned long flags;
+
+ if (!tty || !vt || !vt->xmit_buf)
+ return;
+
+ save_flags(flags); cli();
+ vt->xmit_buf[vt->xmit_cnt++] = ch;
+ if (vt->xmit_cnt >= CON_XMIT_SIZE) {
+ con_write(tty, 0, vt->xmit_buf, vt->xmit_cnt);
+ vt->xmit_cnt = 0;
+ }
+
+ restore_flags(flags);
+}
+
+static void con_flush_chars(struct tty_struct *tty)
+{
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+ unsigned long flags;
+
+ if (vt->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+ !vt->xmit_buf)
+ return;
+
+ save_flags(flags); cli();
+ con_write(tty, 0, vt->xmit_buf, vt->xmit_cnt);
+ vt->xmit_cnt = 0;
+ restore_flags(flags);
+}
+
static int con_write_room(struct tty_struct *tty)
{
- if (tty->stopped)
- return 0;
- return 4096; /* No limit, really; we're not buffering */
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+ return CON_XMIT_SIZE - vt->xmit_cnt;
}

static int con_chars_in_buffer(struct tty_struct *tty)
{
- return 0; /* we're not buffering */
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+ return vt->xmit_cnt;
}

void poke_blanked_console(void)
@@ -2013,6 +2056,8 @@

console_driver.open = con_open;
console_driver.write = con_write;
+ console_driver.put_char = con_put_char;
+ console_driver.flush_chars = con_flush_chars;
console_driver.write_room = con_write_room;
console_driver.chars_in_buffer = con_chars_in_buffer;
console_driver.ioctl = vt_ioctl;
@@ -2050,6 +2095,9 @@
kmem_start += sizeof(struct vc_data);
vt_cons[currcons] = (struct vt_struct *) kmem_start;
kmem_start += sizeof(struct vt_struct);
+ vt_cons[currcons]->xmit_buf = (unsigned char *) kmem_start;
+ vt_cons[currcons]->xmit_cnt = 0;
+ kmem_start += CON_XMIT_SIZE;
vc_scrbuf[currcons] = (unsigned short *) kmem_start;
kmem_start += video_screen_size;
kmalloced = 0;
--- linux/drivers/char/vt_kern.h.orig Tue Sep 3 16:25:53 1996
+++ linux/drivers/char/vt_kern.h Wed Sep 4 01:26:13 1996
@@ -18,6 +18,11 @@
*/
#define BROKEN_GRAPHICS_PROGRAMS 1

+/*
+ * The console transmit buffer is set to one page (is this always 4096?)
+ */
+#define CON_XMIT_SIZE PAGE_SIZE
+
extern struct vt_struct {
int vc_num; /* The console number */
unsigned char vc_mode; /* KD_TEXT, ... */
@@ -28,6 +33,9 @@
int vt_pid;
int vt_newvt;
struct wait_queue *paste_wait;
+
+ unsigned char *xmit_buf;
+ int xmit_cnt;
} *vt_cons[MAX_NR_CONSOLES];

void (*kd_mksound)(unsigned int hz, unsigned int ticks);
======================================================================
Brad Pepers Proud supporter of Linux and
Ramparts Management Group Ltd. Caldera in Canada!
ramparts@agt.net
http://www.agt.net/public/ramparts Linux rules!
\
 
 \ /
  Last update: 2005-03-22 13:38    [W:0.034 / U:0.136 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site