Ignore:
Timestamp:
Sep 15, 2020, 2:55:26 PM (5 years ago)
Author:
bird
Message:

kash: Cache one pstack_block since parsecmd seems to be called for each statement line in a script. Also, mark pstack blocks as 'done' before returning from parsecmd and prevent them from becoming current (curpstack) again upon popping.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/memalloc.c

    r3458 r3461  
    371371                TRACE2((NULL, "pstackrelease: %p - %u refs (%s)\n", pst, refs, caller)); K_NOREF(caller);
    372372                if (refs == 0) {
    373                         shinstance * const psh = shthread_get_shell();
    374373                        struct stack_block *top;
    375374                        while ((top = pst->top) != &pst->first)
     
    382381                        pst->nextbyte = NULL;
    383382                        pst->top = NULL;
    384                         /** @todo push into an alloc cache rather than freeing it */
    385                         sh_free(psh, pst);
     383
     384                        if (!psh->freepstack)
     385                                psh->freepstack = pst;
     386                        else
     387                                sh_free(psh, pst);
    386388                }
    387389        } else
     
    395397        while (target < psh->pstacksize) {
    396398                unsigned idx = --psh->pstacksize;
    397                 pstack_block *psk = psh->pstack[idx];
     399                pstack_block *pst = psh->pstack[idx];
    398400                psh->pstack[idx] = NULL;
    399                 if (psh->curpstack == psk)
    400                     psh->curpstack = idx > 0 ? psh->pstack[idx - 1] : NULL;
    401                 pstackrelease(psh, psk, "popstackmark");
     401                if (psh->curpstack == pst) {
     402                        pstack_block *pstnext;
     403                        if (idx <= 0 || (pstnext = psh->pstack[idx - 1])->done)
     404                                psh->curpstack = NULL;
     405                        else
     406                                psh->curpstack = pstnext;
     407                }
     408                pstackrelease(psh, pst, "popstackmark");
    402409        }
    403410
     
    454461         * Allocate and initialize it.
    455462         */
    456         pst = (pstack_block *)ckmalloc(psh, blocksize);
     463        pst = psh->freepstack;
     464        if (pst)
     465                psh->freepstack = NULL;
     466        else
     467                pst = (pstack_block *)ckmalloc(psh, blocksize);
    457468        pst->nextbyte          = &pst->first.space[0];
    458469        pst->avail             = blocksize - offsetof(pstack_block, first.space);
    459470        pst->topsize           = blocksize - offsetof(pstack_block, first.space);
     471        pst->top               = &pst->first;
    460472        pst->strleft           = 0;
    461         pst->top               = &pst->first;
    462473        pst->allocations       = 0;
    463474        pst->bytesalloced      = 0;
     
    468479        pst->fragmentation     = 0;
    469480        pst->refs              = 1;
    470         pst->padding           = 42;
     481        pst->done              = K_FALSE;
    471482        pst->first.prev        = NULL;
    472483
     
    480491        TRACE2((psh, "pstackallocpush: %p - entry %u\n", pst, psh->pstacksize - 1));
    481492        return pst;
     493}
     494
     495/**
     496 * Marks the block as done, preventing it from being marked current again.
     497 */
     498void pstackmarkdone(pstack_block *pst)
     499{
     500        pst->done = K_TRUE;
    482501}
    483502
Note: See TracChangeset for help on using the changeset viewer.