kernel timer

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • martinm69x@hotmail.com

    kernel timer

    Hey all,

    I've been working on the code for a kernel timer which will report real
    time, CPU time, user time and kernel time on the operation of fibonacci
    method.

    The way im doing it is keeping track of the parent and two child times
    (using fork()).

    I can get parent times to come up, however i do not think they are
    correct, and i can not get child times to come up at all. I think in
    the signal handler methods i have to somehow restart the timer or
    signal, but i am not entirely sure how to.

    All the code is below, can someone please assist me. Don't worry about
    the delta_time method.

    Thanks in advance for any help.
    Michael M

    #include <sys/time.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>

    long unsigned int fibonacci(unsig ned int n);
    long unsigned int elapsed_usecs(l ong, long);
    long unsigned int delta_time(stru ct itimerval, struct itimerval);
    void p_handler(int);
    void c1_handler(int) ;
    void c2_handler(int) ;

    /* These variables are used to record the accumulated times. They
    are set by the signal handlers and read by the processes when
    they report the results */
    static long p_realt_secs = 0, c1_realt_secs = 0, c2_realt_secs = 0;
    static long p_virtt_secs = 0, c1_virtt_secs = 0, c2_virtt_secs = 0;
    static long p_proft_secs = 0, c1_proft_secs = 0, c2_proft_secs = 0;
    static struct itimerval p_realt, c1_realt, c2_realt;
    static struct itimerval p_virtt, c1_virtt, c2_virtt;
    static struct itimerval p_proft, c1_proft, c2_proft;

    main(int argc, char **argv) {
    long unsigned fib = 0;
    int pid1, pid2;
    unsigned int fibarg;
    int status;

    // Get command line argument, fibarg (N)
    if(argc != 2) {
    printf("usage: $./a.out <number>\n");
    exit(EXIT_FAILU RE);
    }
    fibarg = (int)strtoul(ar gv[1], NULL, 10);
    printf("Fib is: %u\n", fibarg);


    // Initialize parent, child1 and child2 timer values
    p_realt.it_inte rval.tv_sec = 1; //change
    p_realt.it_inte rval.tv_usec = 0; // change
    p_realt.it_valu e.tv_sec = 1; // change
    p_realt.it_valu e.tv_usec = 0; // change

    c1_realt.it_int erval.tv_sec = 0; //change
    c1_realt.it_int erval.tv_usec = 0; // change
    c1_realt.it_val ue.tv_sec = 0; // change
    c1_realt.it_val ue.tv_usec = 0; // change

    c2_realt.it_int erval.tv_sec = 0; //change
    c2_realt.it_int erval.tv_usec = 0; // change
    c2_realt.it_val ue.tv_sec = 0; // change
    c2_realt.it_val ue.tv_usec = 0; // change

    p_virtt.it_inte rval.tv_sec = 1; //change
    p_virtt.it_inte rval.tv_usec = 0; // change
    p_virtt.it_valu e.tv_sec = 1; // change
    p_virtt.it_valu e.tv_usec = 0; // change

    c1_virtt.it_int erval.tv_sec = 0; //change
    c1_virtt.it_int erval.tv_usec = 0; // change
    c1_virtt.it_val ue.tv_sec = 0; // change
    c1_virtt.it_val ue.tv_usec = 0; // change

    c2_virtt.it_int erval.tv_sec = 0; //change
    c2_virtt.it_int erval.tv_usec = 0; // change
    c2_virtt.it_val ue.tv_sec = 0; // change
    c2_virtt.it_val ue.tv_usec = 0; // change

    p_proft.it_inte rval.tv_sec = 1; //change
    p_proft.it_inte rval.tv_usec = 0; // change
    p_proft.it_valu e.tv_sec = 1; // change
    p_proft.it_valu e.tv_usec = 0; // change

    c1_proft.it_int erval.tv_sec = 0; //change
    c1_proft.it_int erval.tv_usec = 0; // change
    c1_proft.it_val ue.tv_sec = 0; // change
    c1_proft.it_val ue.tv_usec = 0; // change

    c2_proft.it_int erval.tv_sec = 0; //change
    c2_proft.it_int erval.tv_usec = 0; // change
    c2_proft.it_val ue.tv_sec = 0; // change
    c2_proft.it_val ue.tv_usec = 0; // change

    // Enable parents signal handlers
    signal(SIGALRM, p_handler); // change to own signal handlers
    signal(SIGVTALR M, p_handler); // change to own signal handlers
    signal(SIGPROF, p_handler); // change to own signal handlers

    // Set parents itimers
    if(setitimer(IT IMER_REAL, &p_realt, NULL) == -1)
    perror("parent real timer set error");
    if(setitimer(IT IMER_VIRTUAL, &p_virtt, NULL) == -1)
    perror("parent virtual timer set error");
    if(setitimer(IT IMER_PROF, &p_proft, NULL) == -1)
    perror("parent profile timer set error");

    pid1 = fork();
    if(pid1 == 0) {
    // Enable child1 signal handlers (disable parent handlers)
    signal(SIGALRM, c1_handler); // change to own signal handlers
    signal(SIGVTALR M, c1_handler); // change to own signal
    handlers
    signal(SIGPROF, c1_handler);

    // enable child1 signal handlers

    // Set child1 itimers
    if(setitimer(IT IMER_REAL, &c1_realt, NULL) == -1)
    perror("child1 real timer set error");
    if(setitimer(IT IMER_VIRTUAL, &c1_virtt, NULL) == -1)
    perror("child1 virtual timer set error");
    if(setitimer(IT IMER_PROF, &c1_proft, NULL) == -1)
    perror("child1 profile timer set error");

    // Start child1 itimer on the fibonacci program
    fib = fibonacci(fibar g);

    // Read child1 itimer values and report them
    getitimer(ITIME R_PROF, &c1_proft);
    getitimer(ITIME R_REAL, &c1_realt);
    getitimer(ITIME R_VIRTUAL, &c1_virtt);
    printf("\n");
    printf("Child 1 fib = %ld, real time = %ld sec, %ld msec\n", fib,
    c1_realt_secs, elapsed_usecs(c 1_realt.it_valu e.tv_sec,
    c1_realt.it_val ue.tv_usec)/1000);

    printf("Child 1 fib = %ld, cpu time = %ld sec, %ld msec\n", fib,
    c1_proft_secs, elapsed_usecs(c 1_proft.it_valu e.tv_sec,
    c1_proft.it_val ue.tv_usec)/1000);

    printf("Child 1 fib = %ld, user time = %ld sec, %ld msec\n", fib,
    c1_virtt_secs, elapsed_usecs(c 1_virtt.it_valu e.tv_sec,
    c1_virtt.it_val ue.tv_usec)/1000);

    printf("Child 1 fib = %ld, kernel time = %ld sec, %ld msec\n", fib,
    delta_time(c1_p roft, c1_virtt),
    (elapsed_usecs( c1_proft.it_val ue.tv_sec,
    c1_proft.it_val ue.tv_usec)/1000) -
    (elapsed_usecs( c1_virtt.it_val ue.tv_sec, c1_virtt.it_val ue.tv_usec)
    /1000));

    fflush(stdout);
    exit(0);
    } else {
    pid2 = fork();
    if(pid2 == 0) {
    // Enable child2 signal handlers
    signal(SIGALRM, c2_handler); // change to own signal handlers
    signal(SIGVTALR M, c2_handler); // change to own signal
    handlers
    signal(SIGPROF, c2_handler);

    // Set child2 itimers
    if(setitimer(IT IMER_REAL, &c2_realt, NULL) == -1)
    perror("child 2 real timer set error");
    if(setitimer(IT IMER_VIRTUAL, &c2_virtt, NULL) == -1)
    perror("child 2 virtual timer set error");
    if(setitimer(IT IMER_PROF, &c2_proft, NULL) == -1)
    perror("child 2 profile timer set error");

    // Start child2 on the fibonacci program
    fib = fibonacci(fibar g);

    // Read child2 itimer vlues and report them
    getitimer(ITIME R_PROF, &c2_proft);
    getitimer(ITIME R_REAL, &c2_realt);
    getitimer(ITIME R_VIRTUAL, &c2_virtt);
    printf("\n");
    printf("Child 2 fib = %ld, real time = %ld sec, %ld msec\n", fib,
    c2_realt_secs, elapsed_usecs(c 2_realt.it_valu e.tv_sec,
    c2_realt.it_val ue.tv_usec)/1000);

    printf("Child 2 fib = %ld, cpu time = %ld sec, %ld msec\n", fib,
    c2_proft_secs, elapsed_usecs(c 2_proft.it_valu e.tv_sec,
    c2_proft.it_val ue.tv_usec)/1000);

    printf("Child 2 fib = %ld, user time = %ld sec, %ld msec\n", fib,
    c2_virtt_secs, elapsed_usecs(c 2_virtt.it_valu e.tv_sec,
    c2_virtt.it_val ue.tv_usec)/1000);

    printf("Child 2 fib = %ld, kernel time = %ld sec, %ld msec\n",
    fib,
    delta_time(c2_p roft, c2_virtt),
    (elapsed_usecs( c2_proft.it_val ue.tv_sec,
    c2_proft.it_val ue.tv_usec)/1000) -
    (elapsed_usecs( c2_virtt.it_val ue.tv_sec,
    c2_virtt.it_val ue.tv_usec)
    /1000));

    fflush(stdout);
    exit(0);


    } else { /* this is the parent */

    // Start parent on the fibonacci program
    fib = fibonacci(fibar g);

    // Wait for children to terminate
    waitpid(0, &status, 0);
    waitpid(0, &status, 0);

    // Read parent itimer values and report them
    getitimer(ITIME R_PROF, &p_proft);
    getitimer(ITIME R_REAL, &p_realt);
    getitimer(ITIME R_VIRTUAL, &p_virtt);
    printf("\n");
    printf("Parent fib = %ld, real time = %ld sec, %ld msec\n", fib,
    p_realt_secs, elapsed_usecs(p _realt.it_value .tv_sec,
    p_realt.it_valu e.tv_usec)/1000);

    printf("Parent fib = %ld, cpu time = %ld sec, %ld msec\n", fib,
    p_proft_secs, elapsed_usecs(p _proft.it_value .tv_sec,
    p_proft.it_valu e.tv_usec)/1000);

    printf("Parent fib = %ld, user time = %ld sec, %ld msec\n", fib,
    p_virtt_secs, elapsed_usecs(p _virtt.it_value .tv_sec,
    p_virtt.it_valu e.tv_usec)/1000);

    printf("Parent fib = %ld, kernel time = %ld sec, %ld msec\n", fib,
    delta_time(p_pr oft, p_virtt),
    (elapsed_usecs( p_proft.it_valu e.tv_sec,
    p_proft.it_valu e.tv_usec)/1000) -
    (elapsed_usecs( p_virtt.it_valu e.tv_sec, p_virtt.it_valu e.tv_usec)
    /1000));

    fflush(stdout);
    exit(0);

    }
    printf("this line should never be printed\n");
    }
    }

    long unsigned int fibonacci(unsig ned int n) {
    if(n == 0)
    return 0;
    else if ( n == 1 || n == 2)
    return 1;
    else
    return (fibonacci(n-1) + fibonacci(n-2));
    }

    long unsigned int elapsed_usecs(l ong sec, long usec)
    {
    return ((sec*1000000) + usec);
    }

    long unsigned int delta_time(stru ct itimerval n, struct itimerval m)
    {
    return m.it_value.tv_s ec + n.it_value.tv_s ec;
    }

    void p_handler(int signo)
    {
    switch(signo) {
    case SIGALRM:
    p_realt_secs++;
    signal(SIGALRM, p_handler); // change to own signal handlers
    break;
    case SIGVTALRM:
    p_virtt_secs++;
    signal(SIGVTALR M, p_handler); // change to own signal handlers
    break;
    case SIGPROF:
    p_proft_secs++;
    signal(SIGPROF, p_handler);
    break;
    }
    return;
    }

    void c1_handler(int signo)
    {
    switch(signo) {
    case SIGALRM:
    c1_realt_secs++ ;
    signal(SIGALRM, c1_handler); // change to own signal handlers
    break;
    case SIGVTALRM:
    c1_virtt_secs++ ;
    signal(SIGVTALR M, c1_handler); // change to own signal handlers
    break;
    case SIGPROF:
    c1_proft_secs++ ;
    signal(SIGPROF, c1_handler);
    break;
    }
    return;
    }

    void c2_handler(int signo)
    {
    switch(signo) {
    case SIGALRM:
    c2_realt_secs++ ;
    break;
    case SIGVTALRM:
    c2_virtt_secs++ ;
    break;
    case SIGPROF:
    c2_proft_secs++ ;
    break;
    }
    return;
    }

  • Fao, Sean

    #2
    Re: kernel timer

    martinm69x@hotm ail.com wrote:[color=blue]
    > I've been working on the code for a kernel timer which will report real
    > time, CPU time, user time and kernel time on the operation of fibonacci
    > method.
    >
    > The way im doing it is keeping track of the parent and two child times
    > (using fork()).[/color]

    [...]

    I think you might be looking for comp.unix.progr ammer.

    By the way, may I suggest splitting up your main() into more functions?

    --
    Sean

    Comment

    Working...