Re: patch: fast console output ioctl(PIO_DISPLAY)

Tuukka Toivonen (tuukkat@ees2.oulu.fi)
Mon, 20 Jul 1998 18:09:57 +0300 (EET DST)


On Fri, 17 Jul 1998, Perry Harrington wrote:

>> The problem: Linux 2.0.34 text console is extremely slow. The hardware
>
>It isn't the console code, it's the dialog program. Just try Midnight

It is the console code. To prove that, I have attached a short test
program that fills my screen 10 times. By measuring the time I see
that it takes 1 second to fill the screen. I have P120; imagine
low-end 386sx: filling the screen takes almost 30 seconds or half a
minute!!

It's true, though, that people using 386 might not use as high
resolutions as I do and my test programs shows the worst case anyway.
But it is still slow, as by writing directly to screen it would be
easy to redraw screen 70 times a second on the same 386.
That is 2000 times faster!!!

>commander or Minicom, they are both color console apps and are fast.

They use special control codes to scroll part of the display (probably).
That helps in many cases, but there are many situations where that can
not be used.

>Have a look at /dev/vcsa* It's a byte-for-byte image of the display
>memory of the console. Just mmap it to get memory addressable access.

I think mmapping doesn't work because mmap entry in vcsa_fops in
drivers/char/vc_screen.c is NULL (haven't tried, though). However, using
write() works fine and is almost twice faster than my new ioctl() was.
Thanks a lot for the tip!

Now the test program:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

/* Your screen width and height. Modify them to suit. */
#define WIDTH 116
#define HEIGHT 51

#define ESC "\033"

int main(int argc, char **argv)
{
int fd;
char *dev = "/dev/console";
char *prog;
int i,sz,r=0;
unsigned char *buffer, *buf2;
/* set up everything */
prog = argv[0];
sz = WIDTH*HEIGHT*12+6;
buffer = malloc(sz+1);
fd = open(dev, O_WRONLY|O_NOCTTY);
if (fd == -1) goto gen_error;
/* set up buffer */
buf2 = buffer;
strcpy(buf2, ESC"[H"ESC"[J");
buf2 += 6;
for (i=0; i<(WIDTH*HEIGHT/2); i++) {
strcpy(buf2, "x"ESC"[00;36;30my"ESC"[00;01;44m");
buf2 += 12*2;
}
for (i=0; i<10; i++) {
r = write(fd, buffer, sz);
if (r != sz) goto gen_error;
}
if (close(fd) != 0) goto gen_error;
return 0;

gen_error:
fprintf(stderr, "%s: failed, r=%i\n", prog, r);
return 1;
}

--
| Tuukka Toivonen <tuukkat@ee.oulu.fi>       [PGP public key
| Homepage: http://www.ee.oulu.fi/~tuukkat/       available]
| Try also finger -l tuukkat@ee.oulu.fi
| Studying information engineering at the University of Oulu
+-----------------------------------------------------------

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html