cvsuser     03/12/16 03:33:18

  Modified:    .        MANIFEST
               dynoplibs alarm.pasm myops.ops
               config/init/hints linux.pl
               docs/dev events.pod
               include/parrot thr_pthread.h thread.h tsq.h
               src      events.c tsq.c
  Added:       dynoplibs alarm2.pasm
  Log:
  event-handling-8
  * thread creation macros
  * must now link with pthread lib - no test anymore
    this could break platforms that have pthread but dont link with it
  * insert multiple timer events according to abs_time
  * handle repeated timer events
  
  Revision  Changes    Path
  1.516     +1 -0      parrot/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /cvs/public/parrot/MANIFEST,v
  retrieving revision 1.515
  retrieving revision 1.516
  diff -u -w -r1.515 -r1.516
  --- MANIFEST  15 Dec 2003 15:12:36 -0000      1.515
  +++ MANIFEST  16 Dec 2003 11:33:04 -0000      1.516
  @@ -237,6 +237,7 @@
   dynclasses/subproxy.pmc                           [devel]
   dynoplibs/README                                  [devel]
   dynoplibs/alarm.pasm                              [devel]
  +dynoplibs/alarm2.pasm                             [devel]
   dynoplibs/myops.ops                               [devel]
   dynoplibs/test.pasm                               [devel]
   editor/Makefile                                   [devel]
  
  
  
  1.2       +5 -4      parrot/dynoplibs/alarm.pasm
  
  Index: alarm.pasm
  ===================================================================
  RCS file: /cvs/public/parrot/dynoplibs/alarm.pasm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- alarm.pasm        15 Dec 2003 15:12:42 -0000      1.1
  +++ alarm.pasm        16 Dec 2003 11:33:07 -0000      1.2
  @@ -3,16 +3,17 @@
   
       loadlib P1, "myops_ops"
       find_global P0, "_alarm"
  -    alarm 2.5, P0
  -    null I0
  +    alarm 3.5, P0
  +    set I0, 1
   loop:
       sleep 1
       print I0
       print "\n"
       inc I0
       # check_events
  -    branch loop
  +    le I0, 5, loop
  +    print "done.\n"
       end
   .pcc_sub _alarm:
       print "alarm\n"
  -    exit 0
  +    invoke P1
  
  
  
  1.4       +9 -0      parrot/dynoplibs/myops.ops
  
  Index: myops.ops
  ===================================================================
  RCS file: /cvs/public/parrot/dynoplibs/myops.ops,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -r1.3 -r1.4
  --- myops.ops 15 Dec 2003 15:12:42 -0000      1.3
  +++ myops.ops 16 Dec 2003 11:33:07 -0000      1.4
  @@ -47,10 +47,19 @@
   
   Call alarm handler sub $2 after $1 time has elapsed.
   
  +=item B<alarm>(in NUM, in NUM, in PMC)
  +
  +Call alarm handler sub $3 after $1 time has elapsed, repeat after $2.
  +
   =cut
   
   op alarm(in NUM, in PMC) {
        Parrot_new_timer_event(interpreter, $1, 0.0, $2);
  +    goto NEXT();
  +}
  +
  +op alarm(in NUM, in NUM, in PMC) {
  +     Parrot_new_timer_event(interpreter, $1, $2, $3);
       goto NEXT();
   }
   
  
  
  
  1.1                  parrot/dynoplibs/alarm2.pasm
  
  Index: alarm2.pasm
  ===================================================================
  # test program vor event handling
  # -b, -g, -S run cores only by now
  
      loadlib P1, "myops_ops"
      find_global P0, "_alarm3"
      alarm 3.3, 0.4, P0
      find_global P0, "_alarm2"
      alarm 2.2, P0
      find_global P0, "_alarm"
      alarm 1.5, 2.0, P0
      set I0, 1
  loop:
      sleep 1
      print I0
      print "\n"
      inc I0
      le I0, 5, loop
      print "done.\n"
      end
  .pcc_sub _alarm:
      print "alarm\n"
      invoke P1
  .pcc_sub _alarm2:
      print "alarm2\n"
      invoke P1
  .pcc_sub _alarm3:
      print "alarm3\n"
      invoke P1
  
  
  
  1.3       +1 -1      parrot/config/init/hints/linux.pl
  
  Index: linux.pl
  ===================================================================
  RCS file: /cvs/public/parrot/config/init/hints/linux.pl,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- linux.pl  15 Dec 2003 15:12:46 -0000      1.2
  +++ linux.pl  16 Dec 2003 11:33:09 -0000      1.3
  @@ -1,6 +1,6 @@
   my $libs = Configure::Data->get('libs');
   if ($libs !~ /-lpthread/) {
  -    $libs .= ' -pthread';
  +    $libs .= ' -lpthread';
   }
   
   Configure::Data->set(
  
  
  
  1.2       +0 -2      parrot/docs/dev/events.pod
  
  Index: events.pod
  ===================================================================
  RCS file: /cvs/public/parrot/docs/dev/events.pod,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- events.pod        15 Dec 2003 15:12:40 -0000      1.1
  +++ events.pod        16 Dec 2003 11:33:11 -0000      1.2
  @@ -78,8 +78,6 @@
   
   =item Insert timed events accoring to their abstime
   
  -=item Reinsert repeated events
  -
   =item Synchronous event API
   
   Sync events could be placed directly into the interpreters task queue.
  
  
  
  1.3       +16 -1     parrot/include/parrot/thr_pthread.h
  
  Index: thr_pthread.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/thr_pthread.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- thr_pthread.h     15 Dec 2003 15:12:57 -0000      1.2
  +++ thr_pthread.h     16 Dec 2003 11:33:16 -0000      1.3
  @@ -1,7 +1,7 @@
   /* thr_pthread.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: thr_pthread.h,v 1.2 2003/12/15 15:12:57 leo Exp $
  + *     $Id: thr_pthread.h,v 1.3 2003/12/16 11:33:16 leo Exp $
    *  Overview:
    *     POSIS pthread interface
    *  Data Structure and Algorithms:
  @@ -35,8 +35,23 @@
   #  define COND_INIT(c)    pthread_cond_init(&c, NULL);
   #  define COND_DESTROY(c) pthread_cond_destroy(&c)
   
  +#  define THREAD_CREATE_DETACHED(t, func, arg) do { \
  +        pthread_attr_t      attr;   \
  +        int rc = pthread_attr_init(&attr);      \
  +        assert(rc == 0);    \
  +        rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   \
  +        assert(rc == 0);    \
  +        rc = pthread_create(&t, &attr, func, arg); \
  +        assert(rc == 0);    \
  +        pthread_attr_destroy(&attr);        \
  +   } while (0)
  +
  +#  define THREAD_CREATE_JOINABLE(t, func, arg) \
  +        pthread_create(&t, NULL, func, arg)
  +
   typedef pthread_mutex_t Parrot_mutex;
   typedef pthread_cond_t Parrot_cond;
  +typedef pthread_t Parrot_thread;
   
   #endif
   
  
  
  
  1.9       +5 -1      parrot/include/parrot/thread.h
  
  Index: thread.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/thread.h,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -w -r1.8 -r1.9
  --- thread.h  15 Dec 2003 15:12:57 -0000      1.8
  +++ thread.h  16 Dec 2003 11:33:16 -0000      1.9
  @@ -1,7 +1,7 @@
   /* thread.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: thread.h,v 1.8 2003/12/15 15:12:57 leo Exp $
  + *     $Id: thread.h,v 1.9 2003/12/16 11:33:16 leo Exp $
    *  Overview:
    *     This is the api header for the thread primitives
    *  Data Structure and Algorithms:
  @@ -30,8 +30,12 @@
   #  define COND_INIT(c)
   #  define COND_DESTROY(c)
   
  +#  define THREAD_CREATE_DETACHED(t, func, arg)
  +#  define THREAD_CREATE_JOINABLE(t, func, arg)
  +
   #  define Parrot_mutex int
   #  define Parrot_cond int
  +#  define Parrot_thread int
   
   #  ifndef _STRUCT_TIMESPEC
   #  define _STRUCT_TIMESPEC
  
  
  
  1.8       +3 -1      parrot/include/parrot/tsq.h
  
  Index: tsq.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/tsq.h,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -w -r1.7 -r1.8
  --- tsq.h     15 Dec 2003 15:12:57 -0000      1.7
  +++ tsq.h     16 Dec 2003 11:33:16 -0000      1.8
  @@ -1,7 +1,7 @@
   /* tsq.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: tsq.h,v 1.7 2003/12/15 15:12:57 leo Exp $
  + *     $Id: tsq.h,v 1.8 2003/12/16 11:33:16 leo Exp $
    *  Overview:
    *     Defines the thread-safe queue system
    *  Data Structure and Algorithms:
  @@ -45,6 +45,8 @@
   PARROT_INLINE QUEUE_ENTRY *peek_entry(QUEUE *);
   QUEUE_ENTRY *wait_for_entry(QUEUE *);
   void push_entry(QUEUE *, QUEUE_ENTRY *);
  +void nosync_insert_entry(QUEUE *, QUEUE_ENTRY *);
  +void insert_entry(QUEUE *, QUEUE_ENTRY *);
   void queue_lock(QUEUE *);
   void queue_unlock(QUEUE *);
   void queue_signal(QUEUE *);
  
  
  
  1.10      +34 -29    parrot/src/events.c
  
  Index: events.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/events.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -w -r1.9 -r1.10
  --- events.c  15 Dec 2003 15:42:31 -0000      1.9
  +++ events.c  16 Dec 2003 11:33:17 -0000      1.10
  @@ -1,7 +1,7 @@
   /* events.c
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: events.c,v 1.9 2003/12/15 15:42:31 leo Exp $
  + *     $Id: events.c,v 1.10 2003/12/16 11:33:17 leo Exp $
    *  Overview:
    *     Event handling stuff
    *  Data Structure and Algorithms:
  @@ -70,11 +70,7 @@
   static void
   init_events_first(Parrot_Interp interpreter)
   {
  -#if defined(PARROT_HAS_HEADER_PTHREAD) && defined(PARROT_HAS_HEADER_LIB_PTHREAD)
  -    pthread_attr_t      attr;
  -    static pthread_t    the_thread;
  -    int rc;
  -#endif
  +    Parrot_thread    the_thread;
       /*
        * init event queue - be sure its done only once
        * we could use pthread_once for queue_init
  @@ -84,23 +80,7 @@
       /*
        * we start an event_handler thread
        */
  -#if defined(PARROT_HAS_HEADER_PTHREAD) && defined(PARROT_HAS_HEADER_LIB_PTHREAD)
  -    /* TODO use some macros */
  -
  -    /* init thread attributes */
  -    rc = pthread_attr_init(&attr);
  -    assert(rc == 0);
  -    /* we want a detached - non joinable thread */
  -    rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  -    assert(rc == 0);
  -
  -    /* now create the task thread */
  -    rc = pthread_create(&the_thread, &attr, event_thread, event_queue);
  -    assert(rc == 0);
  -
  -    /* destroy the thread attribute structure */
  -    pthread_attr_destroy(&attr);
  -#endif
  +    THREAD_CREATE_DETACHED(the_thread, event_thread, event_queue);
       /*
        * now set some sig handlers
        */
  @@ -139,16 +119,18 @@
   {
       QUEUE_ENTRY* entry = mem_sys_allocate(sizeof(QUEUE_ENTRY));
       entry->next = NULL;
  +    ev->interp = interpreter;
  +    entry->data = ev;
       switch (ev->type) {
           case EVENT_TYPE_TIMER:
               entry->type = QUEUE_ENTRY_TYPE_TIMED_EVENT;
  +            insert_entry(event_queue, entry);
               break;
           default:
               entry->type = QUEUE_ENTRY_TYPE_EVENT;
  -    }
  -    ev->interp = interpreter;
  -    entry->data = ev;
       push_entry(event_queue, entry);
  +            break;
  +    }
   }
   
   /*
  @@ -177,6 +159,24 @@
   }
   
   /*
  + * duplicate timed entry and add interval to abstime
  + */
  +static QUEUE_ENTRY*
  +dup_entry_interval(QUEUE_ENTRY* entry, FLOATVAL now)
  +{
  +    parrot_event *event;
  +    QUEUE_ENTRY *new_entry;
  +
  +    new_entry = mem_sys_allocate(sizeof(QUEUE_ENTRY));
  +    new_entry->next = NULL;
  +    new_entry->type = entry->type;
  +    new_entry->data = mem_sys_allocate(sizeof(parrot_event));
  +    mem_sys_memcopy(new_entry->data, entry->data, sizeof(parrot_event));
  +    event = new_entry->data;
  +    event->u.timer_event.abs_time = now + event->u.timer_event.interval;
  +    return new_entry;
  +}
  +/*
    * The event_thread is started by the first interpreter.
    * It handles all events for all interpreters.
    */
  @@ -227,14 +227,19 @@
                       now = Parrot_floatval_time();
                       /*
                        * if the timer_event isn't due yet, ignore the event
  -                     * (we where signalled on insert of the event)
  +                     * (we were signalled on insert of the event)
                        * wait until we get at it again when time has elapsed
                        */
                       if (now < event->u.timer_event.abs_time)
                           goto again;
                       entry = nosync_pop_entry(event_q);
  -                    /* TODO if event is repeated dup and reinsert it
  +                    /*
  +                     * if event is repeated dup and reinsert it
                       */
  +                    if (event->u.timer_event.interval) {
  +                        nosync_insert_entry(event_q,
  +                                dup_entry_interval(entry, now));
  +                    }
                       break;
                   default:
                       internal_exception(1, "Unknown queue entry");
  
  
  
  1.10      +54 -1     parrot/src/tsq.c
  
  Index: tsq.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/tsq.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -w -r1.9 -r1.10
  --- tsq.c     15 Dec 2003 15:13:05 -0000      1.9
  +++ tsq.c     16 Dec 2003 11:33:17 -0000      1.10
  @@ -1,7 +1,7 @@
   /* tsq.c
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: tsq.c,v 1.9 2003/12/15 15:13:05 leo Exp $
  + *     $Id: tsq.c,v 1.10 2003/12/16 11:33:17 leo Exp $
    *  Overview:
    *     Thread-safe queues
    *  Data Structure and Algorithms:
  @@ -11,6 +11,7 @@
    */
   
   #include "parrot/parrot.h"
  +#include <assert.h>
   
   /* A synchronized entry popper */
   QUEUE_ENTRY *
  @@ -77,6 +78,58 @@
           queue->tail = entry;
       }
       queue_signal(queue);
  +    queue_unlock(queue);
  +}
  +
  +/*
  + * insert a timed event according to abstime
  + * caller has to hold the queue mutex
  + */
  +void
  +nosync_insert_entry(QUEUE *queue, QUEUE_ENTRY *entry)
  +{
  +    QUEUE_ENTRY *cur = queue->head, *prev;
  +    parrot_event *event, *cur_event;
  +    FLOATVAL abs_time;
  +
  +    assert(entry->type == QUEUE_ENTRY_TYPE_TIMED_EVENT);
  +    /*
  +     * empty queue - just insert
  +     */
  +    if (!cur) {
  +        queue->head = entry;
  +        queue->tail = entry;
  +        return;
  +    }
  +
  +    prev = NULL;
  +    event = entry->data;
  +    abs_time = event->u.timer_event.abs_time;
  +    while (cur && cur->type == QUEUE_ENTRY_TYPE_TIMED_EVENT) {
  +        cur_event = cur->data;
  +        if (abs_time > cur_event->u.timer_event.abs_time) {
  +            prev = cur;
  +            cur = cur->next;
  +        }
  +        else
  +            break;
  +    }
  +    if (!prev)
  +        queue->head = entry;
  +    else {
  +        prev->next = entry;
  +        if (prev == queue->tail)
  +            queue->tail = entry;
  +    }
  +    entry->next = cur;
  +    queue_signal(queue);
  +}
  +
  +void
  +insert_entry(QUEUE *queue, QUEUE_ENTRY *entry)
  +{
  +    queue_lock(queue);
  +    nosync_insert_entry(queue, entry);
       queue_unlock(queue);
   }
   
  
  
  

Reply via email to