Re: SVGAlib and pthreads

Search this archive.

From: Chris Atenasio (root@lilo.dyn.ml.org)
Date: Tue 29 Sep 1998 - 22:42:39 IST


On Tue, 29 Sep 1998, Ryan Drake wrote:

> Anyone have any experience getting SVGAlib to work with libpthreads?
> pthread_create() throws my prog back into text mode...
> 

Yes!  I had the exact same problem at one point.  Only problem is I dont
remember how I fixed it... :)(maybe that I moved the pthread_create()s to
before vga_init()... *shrug*)  You can see my (functioning) program
though(attached)...  Its a cute little mandelbrot zoomer.  Have fun!

- Chris
--------------------------------------------------------------------------------
Chris Atenasio (chrisa@ultranet.com) -- Friends don't let friends use Windows.
Send me mail with subject "send pgp key" or "word of the day" for auto-response.

Running on a debian hamm system(glibc + svgalib1.2.13)

Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.2.3/specs
gcc version 2.7.2.3

<the makefile>
mandel: mandel.c Makefile
	gcc -g -Wall mandel.c -o mandel -lvga -lpthread
opt: mandel.c Makefile
	pgcc -g -Wall mandel.c -o mandel -lvga -O6 -march=pentiumpro -ffast-math -funroll-all-loops -lpthread


<asm.h>
static inline void outb(int port, int value)
{
    __asm__ volatile ("outb %0,%1"
	      ::"a" ((unsigned char) value), "d"((unsigned short) port));
}

static inline int inb(int port)
{
    unsigned char value;
    __asm__ volatile ("inb %1,%0"
		      :"=a" (value)
		      :"d"((unsigned short) port));
    return value;
}


<mandel.c>
#define _REENTRANT
#include <stdlib.h>
#include <pthread.h>
#include <vga.h>
#include "asm.h"

int iterations;
unsigned char *vidmem;
double xmin=-1.5, ymin=-1.1;
double xmax=.7, ymax=1.1;
volatile int global_sync=0;

unsigned char mandel(double a, double b)
{
    int i=iterations;
    double ta, na=0, nb=0, sa, sb;
    while(i--)
    {
        na += a;
        nb += b;

        if((sa=na*na) + (sb=nb*nb) > 4)
            return 255-i;

        ta = na;
        na = sa - sb;
        nb = ta*nb;
        nb += nb;
    }
        return 0;
}

void *calculate(void *off) 
{
    int x,y, ys;
    double xadd, yadd, xval, yval, ystart, yend;
    int local_sync=0;


    while(1)
    {
        if(local_sync != global_sync)
        {
            if((int)off)
            {
                ys = 100;
                ystart = (ymax - ymin) / 2.0 + ymin;
                yend = ymax;
            }
            else
            {
                ys=0;
                ystart = ymin;
                yend = (ymax - ymin) / 2.0 + ymin;
            }
            yval = ystart;
            xadd = (xmax-xmin) / 320.0;
            yadd = (yend-ystart) / 100.0;

            for(y=ys;y<ys+100;y++)
            {
                xval = xmin;
                for(x=0;x<320;x++)
                {
                    vidmem[(y<<6)+(y<<8)+x]=mandel(xval,yval);
                    xval += xadd;
                }
                yval += yadd;
            }
            local_sync++;
        }
    }
}
void set_pal()
{
    int i;
    float r,g,b;

    outb(0x3c8,1);

    r = 63;
    g = 0;
    b = 0;

    for(i=0;i<42;i++)
    {
        g += 63.0 / 42.0;
        outb(0x3c9,(int)r);
        outb(0x3c9,(int)g);
        outb(0x3c9,(int)b);
    }

    for(i=0;i<42;i++)
    {
        r -= 63.0 / 42.0;
        outb(0x3c9,(int)r);
        outb(0x3c9,(int)g);
        outb(0x3c9,(int)b);
    }

    for(i=0;i<42;i++)
    {
        b += 63.0 / 42.0;
        outb(0x3c9,(int)r);
        outb(0x3c9,(int)g);
        outb(0x3c9,(int)b);
    }

    for(i=0;i<42;i++)
    {
        g -= 63.0 / 42.0;
        outb(0x3c9,(int)r);
        outb(0x3c9,(int)g);
        outb(0x3c9,(int)b);
    }

    for(i=0;i<42;i++)
    {
        r += 63.0 / 42.0;
        outb(0x3c9,(int)r);
        outb(0x3c9,(int)g);
        outb(0x3c9,(int)b);
    }

    for(i=0;i<42;i++)
    {
        b -= 63.0 / 42.0;
        outb(0x3c9,(int)r);
        outb(0x3c9,(int)g);
        outb(0x3c9,(int)b);
    }
}
int main(int argc, char **argv)
{
    pthread_t t1, t2;
    if(argc>1)
        iterations = atoi(argv[1]);
    else
        iterations = 256;
    pthread_create(&t1, NULL, calculate, 0);
    pthread_create(&t2, NULL, calculate, 1);
    vga_init();
    vga_setmode(G320x200x256);
    set_pal();
    vidmem = vga_getgraphmem();
    global_sync++;

    while(1)
    {
        char k;
        switch(k = getchar())
        {
            double change;
            case '8':
                change = (ymax - ymin) / 10;
                ymin -= change;
                ymax -= change;
                break;
            case '2':
                change = (ymax - ymin) / 10;
                ymin += change;
                ymax += change;
                break;
            case '4':
                change = (xmax - xmin) / 10;
                xmin -= change;
                xmax -= change;
                break;
            case '6':
                change = (xmax - xmin) / 10;
                xmin += change;
                xmax += change;
                break;
            case '5':
                change = (xmax - xmin) / 10;
                xmin += change;
                xmax -= change;
                change = (ymax - ymin) / 10;
                ymin += change;
                ymax -= change;
                break;
            case ' ':
                change = (xmax - xmin) / 10;
                xmin -= change;
                xmax += change;
                change = (ymax - ymin) / 10;
                ymin -= change;
                ymax += change;
                break;
            case '+':
                iterations++;
                break;
            case '-':
                iterations--;
                break;
            case 'q':
            case 'Q':
            vga_setmode(TEXT);
            pthread_kill(t1,9);
            pthread_kill(t2,9);
                exit(1);
        }
        global_sync++;
    }
    return 0;
}


This archive was generated by hypermail 2.1.4 : Wed 21 Jan 2004 - 22:10:22 IST