tags:

views:

104

answers:

2

I have this c code, where i need to calculate a dobule from a long.

double result;
long t2_value;

t2_value = 72;
result = t2_value * 1.2;

Now this code crashes at "result = t2_value * 1.2;" only with the error "Vector 0000000006".

Here is the strange thing, if i replace

result = t2_value * 1.2;

with

result = 72 * 1.2;

evything works just as it should, i have tryed type casting t2_value as an double

result = ((double)t2_value * 1.2);

or making it an int istead of a long, but nothing helps.

All the code, see the main method /*! \file * \brief The first user program - * */

#include <scwrapper.h>


long thread_1_empty_semaphore_handle;
long thread_1_mutex_semaphore_handle;
long thread_1_full_semaphore_handle;
long thread_2_empty_semaphore_handle;
long thread_2_mutex_semaphore_handle;
long thread_2_full_semaphore_handle;

int debug;

long value_thread_1;
long value_thread_2;


long send_port;

void thread_1(void)
{
    while(1)
    {
        long value;

        if (ALL_OK != semaphoredown(thread_1_full_semaphore_handle))
            break;

        if (ALL_OK != semaphoredown(thread_1_mutex_semaphore_handle))
            break;

        // Generating some random number here and save it in value_thread_1
        value_thread_1 = 91;
        if(debug == 1) prints("Writing thread 1!\n");

        if (ALL_OK != semaphoreup(thread_1_mutex_semaphore_handle))
            break;

        if (ALL_OK != semaphoreup(thread_1_empty_semaphore_handle))
            break;
    }
    terminate();
}
void thread_2(void)
{
    while(1)
    {
        long value;

        if (ALL_OK != semaphoredown(thread_2_full_semaphore_handle))
            break;

        if (ALL_OK != semaphoredown(thread_2_mutex_semaphore_handle))
            break;

        // Generating some random number here and save it in value_thread_1
        value_thread_2 = 72;
        if(debug == 1) prints("Writing thread 2!\n");

        if (ALL_OK != semaphoreup(thread_2_mutex_semaphore_handle))
            break;

        if (ALL_OK != semaphoreup(thread_2_empty_semaphore_handle))
            break;
    }
    terminate();
}

int create_thread_1()
{
    if(debug == 1)
        prints("Creating thread 1!\n");
    register long  thread_stack;
    thread_1_empty_semaphore_handle=createsemaphore(16);
    if (thread_1_empty_semaphore_handle<0)
        return -1;
    thread_1_full_semaphore_handle=createsemaphore(0);
    if (thread_1_full_semaphore_handle<0)
        return -1;
    thread_1_mutex_semaphore_handle=createsemaphore(1);
    if (thread_1_mutex_semaphore_handle<0)
        return -1;
    thread_stack=alloc(4096, 0);
    if (0 >= thread_stack)
        return -1;
    if (ALL_OK != createthread(thread_1, thread_stack+4096))
        return -1;
    return 1;
}
long read_tread_1()
{
    long value = 0;

    if (ALL_OK != semaphoredown(thread_1_empty_semaphore_handle))
        return -1;

    if (ALL_OK != semaphoredown(thread_1_mutex_semaphore_handle))
        return -1;

    value = value_thread_1;
    if(debug == 1)
        prints("Reading thread 1!\n");

    if (ALL_OK != semaphoreup(thread_1_mutex_semaphore_handle))
        return -1;

    if (ALL_OK != semaphoreup(thread_1_full_semaphore_handle))
        return -1;

    return value;
}

int create_thread_2()
{
    if(debug == 1)
        prints("Creating thread 2!\n");
    register long  thread_stack;
    thread_2_empty_semaphore_handle=createsemaphore(16);
    if (thread_2_empty_semaphore_handle<0)
        return -1;
    thread_2_full_semaphore_handle=createsemaphore(0);
    if (thread_2_full_semaphore_handle<0)
        return -1;
    thread_2_mutex_semaphore_handle=createsemaphore(1);
    if (thread_2_mutex_semaphore_handle<0)
        return -1;
    thread_stack=alloc(4096, 0);
    if (0 >= thread_stack)
        return -1;
    if (ALL_OK != createthread(thread_2, thread_stack+4096))
        return -1;
    return 1;
}
long read_tread_2()
{
    long value = 0;

    if (ALL_OK != semaphoredown(thread_2_empty_semaphore_handle))
        return -1;

    if (ALL_OK != semaphoredown(thread_2_mutex_semaphore_handle))
        return -1;

    value = value_thread_2;
    if(debug == 1)
        prints("Reading thread 2!\n");

    if (ALL_OK != semaphoreup(thread_2_mutex_semaphore_handle))
        return -1;

    if (ALL_OK != semaphoreup(thread_2_full_semaphore_handle))
        return -1;

    return value;
}

int send_message(double message)
{
    struct message msg;

    if(debug == 1)
        prints("Canculation message");
    // We are multiplying the integer with 1000, and thorws all the decimals away
    long temp = (long)(message * 1000.0);
    msg.quad_0 = temp;
    msg.quad_1 = 0;
    msg.quad_2=0;
    msg.quad_3=0;
    msg.quad_4=0;
    msg.quad_5=0;
    msg.quad_6=0;
    msg.quad_7=0;

    prints("0: ");
    printhex(msg.quad_0);
    prints("\n");
    prints("1: ");
    printhex(msg.quad_1);
    prints("\n");

    if (ALL_OK != send(send_port, &msg))
        return -1;
    return 1;
}
void administrat_medicin(double amount)
{
}

void
    main(int argc, char* argv[])
{
    debug = 0;
    long my_pid = getpid();

    create_thread_1();
    create_thread_2();

    /* Launch instances of program_1 */
    if (ALL_OK != createprocess(1))
    {
        if(debug == 1)
            prints("Unable to launch program 1 in a new process\n");
        debugger();
    }

    // Finding a send port
    send_port = findport(0,1);
    if (send_port < 0)
    {
        if(debug == 1)
            prints("process 1: finding a send port in process 0 failed\n");
        terminate();
    }

    /* This is the producer. */
    long t1_value; // Puls
    long t2_value; // Blod sugar
    double result;
    double ration = 1.2;
    while(1)
    {
        t1_value = read_tread_1();
        if(-1 == t1_value)
        {
            if(debug == 1)
                prints("Error reading t1");
            break;
        }

        t2_value = read_tread_2();
        if(-1 == t2_value)
        {
            if(debug == 1)
                prints("Error reading t2");
            break;
        }

        // If there are no date yet, no point in sending it
        // This will also skip if there are no pulse
        if(t1_value > 0 && t2_value > 0)
        {
            // Calculate the medicine to give.
            prints("Calculating\n");
            result = (t2_value * ration);
            prints("Result: ");
            printhex(result);
            prints("\n");

            if(debug == 1)
                prints("Sending message\n");
            if(-1 == send_message(result))
            {
                if(debug == 1)
                prints("Message send failed");
            }
            if(debug == 1)
                prints("Message sendt");
        }
    }
}

Make file

# The following line holds compiler options
CFLAGS = -fno-exceptions -fno-common -Isrc/include

# Do not change the following line. You will not be able to compile without it
PREFIX := "${PWD}/../../support_software/bin/bin"

bochs_boot: boot/kernel
    ${PREFIX}/genext2fs -b 1440 -d boot bochs_stuff/b.img
    (cd bochs_stuff; nice -20 ${PREFIX}/bochs)

kernel: boot/kernel

src/include/scwrapper.h: src/include/sysdefines.h

src/kernel/kernel.h: src/include/sysdefines.h

boot/kernel: objects/kernel/boot32.o objects/kernel/boot64.o objects/kernel/enter.o src/kernel/kernel_link.ld objects/program_0/executable.o objects/program_1/executable.o objects/program_2/executable.o binary_kernel/binary_kernel.o
    ${PREFIX}/x86_64-pc-elf-ld --no-warn-mismatch -Tsrc/kernel/binary_kernel_link.ld -o boot/kernel objects/kernel/boot32.o objects/kernel/boot64.o objects/kernel/enter.o binary_kernel/binary_kernel.o objects/program_0/executable.o objects/program_1/executable.o objects/program_2/executable.o

objects/kernel/boot32.o: src/kernel/boot32.s
    ${PREFIX}/x86_64-pc-elf-as --32 -o objects/kernel/boot32.o src/kernel/boot32.s

objects/kernel/boot64.o: src/kernel/boot64.s
    ${PREFIX}/x86_64-pc-elf-as --64 -o objects/kernel/boot64.o src/kernel/boot64.s

objects/kernel/enter.o: src/kernel/enter.s
    ${PREFIX}/x86_64-pc-elf-as --64 -o objects/kernel/enter.o src/kernel/enter.s

objects/program_startup_code/startup.o: src/program_startup_code/startup.s
    ${PREFIX}/x86_64-pc-elf-as --64 -o objects/program_startup_code/startup.o src/program_startup_code/startup.s

objects/program_0/main.o: src/program_0/main.c src/include/scwrapper.h
    ${PREFIX}/x86_64-pc-elf-gcc -fPIE -m64 $(CFLAGS) -c -O3 -o objects/program_0/main.o src/program_0/main.c

objects/program_0/executable: objects/program_startup_code/startup.o objects/program_0/main.o
    ${PREFIX}/x86_64-pc-elf-ld -static -Tsrc/program_startup_code/program_link.ld -o objects/program_0/executable objects/program_startup_code/startup.o objects/program_0/main.o

objects/program_0/executable.o: objects/program_0/executable
    ${PREFIX}/x86_64-pc-elf-strip objects/program_0/executable
    ${PREFIX}/x86_64-pc-elf-objcopy  -I binary -O elf32-i386 -B i386 --set-section-flags .data=alloc,contents,load,readonly,data objects/program_0/executable objects/program_0/executable.o

objects/program_1/main.o: src/program_1/main.c src/include/scwrapper.h
    ${PREFIX}/x86_64-pc-elf-gcc -fPIE -m64 $(CFLAGS) -c -O3 -o objects/program_1/main.o src/program_1/main.c

objects/program_1/executable: objects/program_startup_code/startup.o objects/program_1/main.o
    ${PREFIX}/x86_64-pc-elf-ld -static -Tsrc/program_startup_code/program_link.ld -o objects/program_1/executable objects/program_startup_code/startup.o objects/program_1/main.o

objects/program_1/executable.o: objects/program_1/executable
    ${PREFIX}/x86_64-pc-elf-strip objects/program_1/executable
    ${PREFIX}/x86_64-pc-elf-objcopy  -I binary -O elf32-i386 -B i386 --set-section-flags .data=alloc,contents,load,readonly,data objects/program_1/executable objects/program_1/executable.o

objects/program_2/main.o: src/program_2/main.c src/include/scwrapper.h
    ${PREFIX}/x86_64-pc-elf-gcc -fPIE -m64 $(CFLAGS) -c -O3 -o objects/program_2/main.o src/program_2/main.c

objects/program_2/executable: objects/program_startup_code/startup.o objects/program_2/main.o
    ${PREFIX}/x86_64-pc-elf-ld -static -Tsrc/program_startup_code/program_link.ld -o objects/program_2/executable objects/program_startup_code/startup.o objects/program_2/main.o

objects/program_2/executable.o: objects/program_2/executable
    ${PREFIX}/x86_64-pc-elf-strip objects/program_2/executable
    ${PREFIX}/x86_64-pc-elf-objcopy  -I binary -O elf32-i386 -B i386 --set-section-flags .data=alloc,contents,load,readonly,data objects/program_2/executable objects/program_2/executable.o

clean:
    -rm -rf objects
    -rm boot/kernel
    -rm bochs_stuff/b.img
    mkdir objects
    mkdir objects/kernel
    mkdir objects/program_startup_code
    mkdir objects/program_0
    mkdir objects/program_1
    mkdir objects/program_2

compile: boot/kernel

Here is prints and printhex void

prints(const char* string)
{
 /* Loop until we have found the null character. */
 while(1)
 {
  register const char curr = *string++;

  if (curr)
  {
   outb(0xe9, curr);
  }
  else
  {
   return;
  }
 }
}

void
printhex(const register long value)
{
 const static char hex_helper[16]="0123456789abcdef";
 register int      i;

 /* Print each character of the hexadecimal number. This is a very inefficient
    way of printing hexadecimal numbers. It is, however, very compact in terms
    of the number of source code lines. */
 for(i=15; i>=0; i--)
 {
  outb(0xe9, hex_helper[(value>>(i*4))&15]);
 }
}
+2  A: 

Ignacio Vazquez-Abrams's comment may have hit upon something. Since this is not a standard environment, do you know that floating point operations are even supported? And are they really necessary or advisable? You will most probably get acceptable results from:

long result;     // integer type
long t2_value;

t2_value = 72;
result = ((t2_value * 10) * 12) / 100 ; // result = 86

If you need more significant figures then for example:

result = ((t2_value * 100) * 120) / 1000 ; // result = 864

here result is a value in 1/10ths of the real world unit.

Clifford
Thank you this workes like charm, you must be right that the system dose not support floating point operations.
DoomStone
A: 

I'm hazarding a guess here, but I'm pretty sure SSE instructions are not allowed in most kernels (If I remember correctly there may be a config option to allow it, though). Even when not using vectors of data, compilers will often use the SSE extensions to do floating point computations. Try adding -mno-sse (or whatever the equivalent is to your compiler) to your Makefile flags.

Matt B.