cvsuser     04/01/09 02:28:20

  Modified:    classes  timer.pmc
               dynoplibs myops.ops
               include/parrot events.h
               src      events.c
               t/pmc    timer.t
  Log:
  event-handling-16
  * repeat count for timers
  * del_timer
  
  Revision  Changes    Path
  1.9       +6 -8      parrot/classes/timer.pmc
  
  Index: timer.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/classes/timer.pmc,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -w -r1.8 -r1.9
  --- timer.pmc 7 Jan 2004 15:22:02 -0000       1.8
  +++ timer.pmc 9 Jan 2004 10:28:11 -0000       1.9
  @@ -1,7 +1,7 @@
   /* timer.pmc
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: timer.pmc,v 1.8 2004/01/07 15:22:02 leo Exp $
  + *     $Id: timer.pmc,v 1.9 2004/01/09 10:28:11 leo Exp $
    *  Overview:
    *     This is the Timer base class
    *  Data Structure and Algorithms:
  @@ -67,15 +67,15 @@
   add_timer(Parrot_Interp interpreter, PMC *pmc)
   {
       parrot_timer_event *t = pmc->cache.struct_val;
  -    /* TODO handle interval, repeat count */
       if (!PMC_IS_NULL(t->sub))
  -     Parrot_new_timer_event(interpreter, t->abs_time, 0, t->sub);
  +     Parrot_new_timer_event(interpreter, pmc, t->abs_time,
  +                     t->interval, t->repeat, t->sub);
   }
   
   static void
   del_timer(Parrot_Interp interpreter, PMC *pmc)
   {
  -    /* TODO find timer in queue, set inactive flag */
  +   Parrot_del_timer_event(interpreter, pmc);
   }
   
   
  @@ -141,14 +141,12 @@
        switch(key) {
            case PARROT_TIMER_SEC:
                return (INTVAL)t->abs_time;
  -             break;
            case PARROT_TIMER_USEC:
                return (t->abs_time - (INTVAL)t->abs_time) *1000000.0;
  -             break;
            case PARROT_TIMER_REPEAT:
  +             return (INTVAL) t->repeat;
            case PARROT_TIMER_RUNNING:
                return 0;
  -             break;
        }
        return -1;
       }
  @@ -187,7 +185,7 @@
                t->abs_time += value / 1000000.0;
                break;
            case PARROT_TIMER_REPEAT:
  -             /* t->repeat = value; */
  +             t->repeat = value;
                break;
            case PARROT_TIMER_RUNNING:
                if (value) {
  
  
  
  1.5       +2 -2      parrot/dynoplibs/myops.ops
  
  Index: myops.ops
  ===================================================================
  RCS file: /cvs/public/parrot/dynoplibs/myops.ops,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -w -r1.4 -r1.5
  --- myops.ops 16 Dec 2003 11:33:07 -0000      1.4
  +++ myops.ops 9 Jan 2004 10:28:13 -0000       1.5
  @@ -54,12 +54,12 @@
   =cut
   
   op alarm(in NUM, in PMC) {
  -     Parrot_new_timer_event(interpreter, $1, 0.0, $2);
  +     Parrot_new_timer_event(interpreter, NULL, $1, 0.0, 0, $2);
       goto NEXT();
   }
   
   op alarm(in NUM, in NUM, in PMC) {
  -     Parrot_new_timer_event(interpreter, $1, $2, $3);
  +     Parrot_new_timer_event(interpreter, NULL, $1, $2, -1, $3);
       goto NEXT();
   }
   
  
  
  
  1.8       +5 -2      parrot/include/parrot/events.h
  
  Index: events.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/events.h,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -w -r1.7 -r1.8
  --- events.h  18 Dec 2003 16:14:58 -0000      1.7
  +++ events.h  9 Jan 2004 10:28:15 -0000       1.8
  @@ -1,7 +1,7 @@
   /* events.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: events.h,v 1.7 2003/12/18 16:14:58 leo Exp $
  + *     $Id: events.h,v 1.8 2004/01/09 10:28:15 leo Exp $
    *  Overview:
    *     This api will handle parrot events
    *  Data Structure and Algorithms:
  @@ -33,6 +33,7 @@
   typedef struct {
       FLOATVAL                    abs_time;
       FLOATVAL                    interval;
  +    int                         repeat; /* 0 = once, -1 = forever */
       PMC*                        sub;    /* handler sub */
   } parrot_timer_event;
   
  @@ -61,10 +62,12 @@
   void* Parrot_do_check_events(Parrot_Interp, void*);
   void* Parrot_do_handle_events(Parrot_Interp, int, void*);
   
  -void Parrot_new_timer_event(Parrot_Interp, FLOATVAL, FLOATVAL,PMC*);
  +void Parrot_new_timer_event(Parrot_Interp, PMC*, FLOATVAL, FLOATVAL, int, PMC*);
  +void Parrot_del_timer_event(Parrot_Interp, PMC* timer);
   void Parrot_new_terminate_event(Parrot_Interp);
   void disable_event_checking(Parrot_Interp);
   void enable_event_checking(Parrot_Interp);
  +
   #endif
   
   /*
  
  
  
  1.17      +41 -7     parrot/src/events.c
  
  Index: events.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/events.c,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -w -r1.16 -r1.17
  --- events.c  27 Dec 2003 11:40:55 -0000      1.16
  +++ events.c  9 Jan 2004 10:28:17 -0000       1.17
  @@ -1,7 +1,7 @@
   /* events.c
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: events.c,v 1.16 2003/12/27 11:40:55 leo Exp $
  + *     $Id: events.c,v 1.17 2004/01/09 10:28:17 leo Exp $
    *  Overview:
    *     Event handling stuff
    *  Data Structure and Algorithms:
  @@ -147,20 +147,46 @@
    * interval running the passed sub
    */
   void
  -Parrot_new_timer_event(Parrot_Interp interpreter, FLOATVAL diff,
  -        FLOATVAL interval, PMC* sub)
  +Parrot_new_timer_event(Parrot_Interp interpreter, PMC* timer, FLOATVAL diff,
  +        FLOATVAL interval, int repeat, PMC* sub)
   {
       parrot_event* ev = mem_sys_allocate(sizeof(parrot_event));
       FLOATVAL now = Parrot_floatval_time();
       ev->type = EVENT_TYPE_TIMER;
  -    ev->data = NULL;
  +    ev->data = timer;
       ev->u.timer_event.abs_time = now + diff;
       ev->u.timer_event.interval = interval;
  +    ev->u.timer_event.repeat   = repeat;
  +    if (repeat && !interval)
  +        ev->u.timer_event.interval = diff;
       ev->u.timer_event.sub = sub;
       Parrot_schedule_event(interpreter, ev);
   }
   
   /*
  + * deactivate timer identified by timer PMC
  + */
  +void
  +Parrot_del_timer_event(Parrot_Interp interpreter, PMC* timer)
  +{
  +    QUEUE_ENTRY *entry;
  +    parrot_event* event;
  +
  +    LOCK(event_queue->queue_mutex);
  +    for (entry = event_queue->head; entry; entry = entry->next) {
  +        if (entry->type == QUEUE_ENTRY_TYPE_TIMED_EVENT) {
  +            event = entry->data;
  +            if (event->interp == interpreter && event->data == timer) {
  +                event->u.timer_event.interval = 0.0;
  +                event->type = EVENT_TYPE_NONE;
  +                break;
  +            }
  +        }
  +    }
  +    UNLOCK(event_queue->queue_mutex);
  +}
  +
  +/*
    * create a terminate event, interpreter will leave runloop
    * when this event arrives
    */
  @@ -258,9 +284,13 @@
                        * if event is repeated dup and reinsert it
                        */
                       if (event->u.timer_event.interval) {
  +                        if (event->u.timer_event.repeat) {
  +                            if (event->u.timer_event.repeat != -1)
  +                                event->u.timer_event.repeat--;
                           nosync_insert_entry(event_q,
                                   dup_entry_interval(entry, now));
                       }
  +                    }
                       break;
                   default:
                       internal_exception(1, "Unknown queue entry");
  @@ -268,10 +298,14 @@
               /*
                * TODO check for a stop event to do cleanup
                */
  +            assert(event);
  +            if (event->type == EVENT_TYPE_NONE) {
  +                mem_sys_free(entry);
  +                continue;
  +            }
               /*
                * now insert entry in interpreter task queue
                */
  -            assert(event);
               if (event->interp) {
                   Parrot_schedule_interp_qentry(event->interp, entry);
               }
  
  
  
  1.4       +61 -2     parrot/t/pmc/timer.t
  
  Index: timer.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/timer.t,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -r1.3 -r1.4
  --- timer.t   7 Jan 2004 15:22:04 -0000       1.3
  +++ timer.t   9 Jan 2004 10:28:20 -0000       1.4
  @@ -1,6 +1,6 @@
   #! perl -w
   
  -use Parrot::Test tests => 3;
  +use Parrot::Test tests => 5;
   use Test::More;
   
   output_is(<<'CODE', <<'OUT', "Timer setup");
  @@ -64,7 +64,7 @@
   OUT
   
   SKIP: {
  -  skip("No thread config yet", 1) unless ($^O eq 'linux' or $^O eq 'darwin');
  +  skip("No thread config yet", 3) unless ($^O eq 'linux' or $^O eq 'darwin');
   
   output_is(<<'CODE', <<'OUT', "Timer setup - initializer/start");
   .include "timer.pasm"
  @@ -89,6 +89,65 @@
       invoke P1
   CODE
   ok 1
  +ok 2
  +ok 3
  +OUT
  +
  +output_is(<<'CODE', <<'OUT', "Timer setup - initializer/start/stop");
  +.include "timer.pasm"
  +    bounds 1 # cant run with JIT core yet
  +    new P1, .SArray
  +    set P1, 6
  +    set P1[0], .PARROT_TIMER_NSEC
  +    set P1[1], 0.5
  +    set P1[2], .PARROT_TIMER_HANDLER
  +    find_global P2, "_timer_sub"
  +    set P1[3], P2
  +    set P1[4], .PARROT_TIMER_RUNNING
  +    set P1[5], 1
  +
  +    new P0, .Timer, P1
  +    print "ok 1\n"
  +    # stop the timer
  +    set P0[.PARROT_TIMER_RUNNING], 0
  +    sleep 1
  +    print "ok 2\n"
  +    end
  +.pcc_sub _timer_sub:
  +    print "never\n"
  +    invoke P1
  +CODE
  +ok 1
  +ok 2
  +OUT
  +
  +output_is(<<'CODE', <<'OUT', "Timer setup - initializer/start/repeat");
  +.include "timer.pasm"
  +    bounds 1 # cant run with JIT core yet
  +    new P1, .SArray
  +    set P1, 8
  +    set P1[0], .PARROT_TIMER_NSEC
  +    set P1[1], 0.2
  +    set P1[2], .PARROT_TIMER_HANDLER
  +    find_global P2, "_timer_sub"
  +    set P1[3], P2
  +    set P1[4], .PARROT_TIMER_REPEAT
  +    set P1[5], 2
  +    set P1[6], .PARROT_TIMER_RUNNING
  +    set P1[7], 1
  +
  +    new P0, .Timer, P1
  +    print "ok 1\n"
  +    sleep 1
  +    print "ok 3\n"
  +    end
  +.pcc_sub _timer_sub:
  +    print "ok 2\n"
  +    invoke P1
  +CODE
  +ok 1
  +ok 2
  +ok 2
   ok 2
   ok 3
   OUT
  
  
  

Reply via email to