return extraChildrenExecs;
    public void computeMinLatencySchedule(        PipelineSchedulingUtility utility,        int childrenExecs[],        int dataInBuffers[],        int lastStreamMaxExecPerPhase)    {        /*        // if only one child, just add all the appropriate phases!        // BUGBUG this is a HACK!        if (getNumChildren() == 1)        {            PhasingSchedule phase = new PhasingSchedule(this);            while (childrenExecs[0] != 0)            {                phase.appendPhase(                    utility.getChildNextPhase(getHierarchicalChild(0)));                utility.advanceChildSchedule(getHierarchicalChild(0));                childrenExecs[0]--;            }            utility.addSchedulePhase(phase);            return;        }        */        // compute how many child executions were requested:        int totalChildrenExecs = 0;        {            for (int nChild = 0; nChild < getNumChildren(); nChild++)            {                totalChildrenExecs += childrenExecs[nChild];            }        }        // execute the children however many times is necessary        // keep track of how many executions are "requested" and        // how many are extra to keep the pull algorithm happy.        int extraChildrenExecs = 0;        while (totalChildrenExecs > 0)        {            // reset the number of data items output from the pipeline            dataInBuffers[getNumChildren()] = 0;            // allocate the items borrowed table            int dataBorrowed[] = new int[getNumChildren() + 1];            // and the number of times every stream gets executed            // per phase            int phaseChildrenExecs[] = new int[getNumChildren()];            // go from bottom to top, pulling data            {                // first the bottom-most child:                int nChild = getNumChildren() - 1;                // figure out how many times I want to execute the last child.                // I want to execute the last child at least once, and no more                // than lastStreamMaxExecPerPhase and no more than                // childrenExecs[nChild] (unless it's 0)                lastStreamMaxExecPerPhase =                    MIN(childrenExecs[nChild], lastStreamMaxExecPerPhase);                lastStreamMaxExecPerPhase = MAX(lastStreamMaxExecPerPhase, 1);                while (phaseChildrenExecs[nChild] < lastStreamMaxExecPerPhase                    && dataInBuffers[nChild + 1] == 0)                {                    utility.advanceOnePhase(                        nChild,                        phaseChildrenExecs[nChild],                        dataInBuffers,                        dataBorrowed);                    phaseChildrenExecs[nChild]++;                }                // now all the other children                for (nChild--; nChild >= 0; nChild--)                {                    // push data into the downstream channel                    // until no more data has been borrowed from it                    while (dataBorrowed[nChild + 1] > 0)                    {                        utility.advanceOnePhase(                            nChild,                            phaseChildrenExecs[nChild],                            dataInBuffers,                            dataBorrowed);                        phaseChildrenExecs[nChild]++;                    }                }            }            // now go from top to bottom, and push the data down            // skip the first child, in case it is a source!            for (int nChild = 1; nChild < getNumChildren(); nChild++)            {                StreamInterface child = getHierarchicalChild(nChild);                // while there's enough data in buffer to execute the next phase                                while (dataInBuffers[nChild]                    >= utility                        .getChildPhase(child, phaseChildrenExecs[nChild])                        .getOverallPeek())                {                    utility.advanceOnePhase(                        nChild,                        phaseChildrenExecs[nChild],                        dataInBuffers,                        dataBorrowed);                    phaseChildrenExecs[nChild]++;                }            }            // okay, now just construct the phase and be done!            {                PhasingSchedule phase = new PhasingSchedule(this);                for (int nChild = 0; nChild < getNumChildren(); nChild++)                {                    StreamInterface child = getHierarchicalChild(nChild);                                        phase.appendPhase(getChildPhases(child, phaseChildrenExecs[nChild]));                                        if (childrenExecs[nChild] >= phaseChildrenExecs[nChild])                    {                        childrenExecs[nChild] -= phaseChildrenExecs[nChild];                        totalChildrenExecs -= phaseChildrenExecs[nChild];                    } else {                        totalChildrenExecs-= childrenExecs[nChild];                        extraChildrenExecs += (phaseChildrenExecs[nChild] - childrenExecs[nChild]);                        childrenExecs[nChild] = 0;                    }                }                utility.addSchedulePhase(phase);            }        }    }