threads branch status update

Andy Dougherty doughera at lafayette.edu
Mon Apr 23 11:50:41 UTC 2012


On Fri, 20 Apr 2012, Stefan Seifert wrote:

> On Tuesday 17 April 2012 17:06:00 you wrote:
> 
> > Here's what I found on Solaris 11/x86 with Sun's compiler:
> > 
> > First, I needed to apply this patch (void functions can't return a
> > value):
> 
> Thanks, applied and commited.
> 
> > Next, I needed to apply this patch to the generated file
> > src/pmc/proxy.c.  I know it is generated, but I can't find where the
> > erroneous lines come from.  These are all more instances of void
> > functions trying to return a value.
> 
> Code for these is generated in lib/Parrot/Pmc2c/PMC/Proxy.pm
> Fixed and committed.
> 
> > Then, the tests hung on t/pmc/task.t.  Here's the specific output:
> > ./parrot t/pmc/task.t
> > 1..6
> > ok 1 - initialized
> > ok 2 task1 ran
> > ok 3 task2 ran
> > ok 4 sub1 ran
> > 
> > [At this point it hangs].

> Could you run parrot in a debugger and send me a stacktrace of all threads of 
> these hangs?

In this test, the main thread is stuck waiting in the pause() command in
Parrot_cx_outer_runloop(PARROT_INTERP).  alarm_count = 1.

            /* Nothing to do except to wait for the next alarm to
             * expire */
            if (alarm_count > 0)
                pause();
            Parrot_thread_notify_threads(interp);
#endif
            Parrot_cx_check_alarms(interp, interp->scheduler);
        }


(dbx) where
=>[1] Parrot_thread_outer_runloop(arg = 0x8228e6c), line 319 in "thread.c"
  [2] _thrp_setup(0xd0a80a40), at 0xcf96d673 
  [3] _lwp_start(0xd0f7cf59, 0x0, 0x0, 0x0, 0x822c694, 0x8228dcc), at 0xcf96d920 
(dbx) where t at 1
=>[1] __pause(0x805352c, 0xd1174548, 0x80478ec, 0xd0f7b7f1, 0xd1174548, 0xd0f7b639), at 0xcf972415 
  [2] pause(0xd1174548, 0xd0f7b639, 0x8191d34, 0x1, 0x1, 0x1), at 0xcf95e64f 
  [3] Parrot_cx_outer_runloop(interp = 0x808aab8), line 171 in "scheduler.c"
  [4] Parrot_cx_begin_execution(interp = 0x808aab8, main = 0x813de4c, argv = 0x813db04), line 110 in "scheduler.c"
  [5] Parrot_pf_execute_bytecode_program(interp = 0x808aab8, pbc = 0x8146df4, args = 0x813db04), line 2678 in "api.c"
  [6] Parrot_api_run_bytecode(interp_pmc = 0x81382a0, pbc = 0x8146df4, args = 0x813db04), line 161 in "bytecode.c"
  [7] main(argc = 2, argv = 0x8047a14), line 171 in "main.c" 

Each of the 4 worker threads is stuck in an infinte loop here in 
threads.c:

(dbx) where t at 2
=>[1] Parrot_thread_outer_runloop(arg = 0x81d379c), line 319 in "thread.c"
  [2] _thrp_setup(0xd0a80240), at 0xcf96d673 
  [3] _lwp_start(0xd0f7cf59, 0x0, 0x0, 0x0, 0x81d6fc4, 0x81d36fc), at 0xcf96d920 

Here's the function.  The call to VTABLE_get_integer(interp, scheduler) always
returns 0.  The next statement, 
        alarm_count = VTABLE_get_integer(interp, sched->alarms);
also returns 0, and the process repeats indefinitely.

static void*
Parrot_thread_outer_runloop(ARGIN_NULLOK(void *arg))
{
    ASSERT_ARGS(Parrot_thread_outer_runloop)
    PMC * const      self    = (PMC*) arg;
    PMC             *ret_val = PMCNULL;
    Parrot_Interp    interp  =
       (Parrot_Interp)((Parrot_ParrotInterpreter_attributes 
*)PMC_data(self))->interp;

    PMC * const scheduler = interp->scheduler;
    Parrot_Scheduler_attributes * const sched = PARROT_SCHEDULER(scheduler);
    INTVAL alarm_count;
    char dummy;
    int              lo_var_ptr;

    /* need to set it here because argument passing can trigger GC */
    interp->lo_var_ptr = &lo_var_ptr;

    do {
        while (VTABLE_get_integer(interp, scheduler) > 0) {
            /* there can be no active runloops at this point, so it should be save
             * to start counting at 0 again. This way the continuation in the next
             * task will find a runloop with id 1 when encountering an exception */
            interp->current_runloop_level = 0;
            reset_runloop_id_counter(interp);

            Parrot_cx_next_task(interp, scheduler);

            /* add expired alarms to the task queue */
            Parrot_cx_check_alarms(interp, interp->scheduler);
        }

        alarm_count = VTABLE_get_integer(interp, sched->alarms);
        if (alarm_count > 0) {
#ifdef _WIN32
            /* TODO: Implement on Windows */
#else
            /* Nothing to do except to wait for the next alarm to expire 
*/
            read(interp->thread_data->notifierfd[0], &dummy, 1);
#endif
            Parrot_cx_check_alarms(interp, interp->scheduler);
        }
    } while (1);


I didn't have time to investigate all the other failures; I figure I
should start with the simplest one first.  If there's a simpler test
to look at, I could do so, but since this is my first foray into
debugging threads on Solaris, and since it's also my first foray into
threads on Parrot, it takes a long time to make any progress.

-- 
    Andy Dougherty		doughera at lafayette.edu


More information about the parrot-dev mailing list