Ignore:
Timestamp:
Sep 14, 2020, 11:46:32 PM (5 years ago)
Author:
bird
Message:

kash: Use reference counting of parser output in threaded-mode.

File:
1 edited

Legend:

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

    r3457 r3458  
    207207
    208208#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
    209         assert(mark->pstacksize <= psh->pstacksize);
    210         while (mark->pstacksize < psh->pstacksize) {
    211                 unsigned idx = --psh->pstacksize;
    212                 pstack_block *psk = psh->pstack[idx];
    213                 psh->pstack[idx] = NULL;
    214                 if (psh->curpstack == psk)
    215                     psh->curpstack = idx > 0 ? psh->pstack[idx - 1] : NULL;
    216                 pstackrelease(psh, psk);
    217         }
    218 
    219 # ifndef NDEBUG
    220         if (psh->curpstack) {
    221                 unsigned i;
    222                 for (i = 0; i < psh->pstacksize; i++)
    223                         if (psh->curpstack == psh->pstack[i])
    224                                 break;
    225                 assert(i < psh->pstacksize);
    226         }
    227 # endif
     209        pstackpop(psh, mark->pstacksize);
    228210#endif
    229211        INTON;
     
    382364#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
    383365
    384 unsigned pstackretain(pstack_block *pst)
    385 {
    386         unsigned refs = sh_atomic_inc(&pst->refs);
    387         assert(refs > 1);
    388         assert(refs < 256 /* bogus, but useful */);
    389         return refs;
    390 }
    391 
    392 unsigned pstackrelease(shinstance *psh, pstack_block *pst)
     366unsigned pstackrelease(shinstance *psh, pstack_block *pst, const char *caller)
    393367{
    394368        unsigned refs;
    395369        if (pst) {
    396370                refs = sh_atomic_dec(&pst->refs);
     371                TRACE2((NULL, "pstackrelease: %p - %u refs (%s)\n", pst, refs, caller)); K_NOREF(caller);
    397372                if (refs == 0) {
    398373                        shinstance * const psh = shthread_get_shell();
     
    407382                        pst->nextbyte = NULL;
    408383                        pst->top = NULL;
     384                        /** @todo push into an alloc cache rather than freeing it */
    409385                        sh_free(psh, pst);
    410386                }
     
    414390}
    415391
    416 pstack_block *pstackpush(shinstance *psh)
     392void pstackpop(shinstance *psh, unsigned target)
     393{
     394        assert(target <= psh->pstacksize);
     395        while (target < psh->pstacksize) {
     396                unsigned idx = --psh->pstacksize;
     397                pstack_block *psk = psh->pstack[idx];
     398                psh->pstack[idx] = NULL;
     399                if (psh->curpstack == psk)
     400                    psh->curpstack = idx > 0 ? psh->pstack[idx - 1] : NULL;
     401                pstackrelease(psh, psk, "popstackmark");
     402        }
     403
     404# ifndef NDEBUG
     405        if (psh->curpstack) {
     406                unsigned i;
     407                for (i = 0; i < psh->pstacksize; i++)
     408                        if (psh->curpstack == psh->pstack[i])
     409                                break;
     410                assert(i < psh->pstacksize);
     411        }
     412# endif
     413}
     414
     415
     416unsigned pstackretain(pstack_block *pst)
     417{
     418        unsigned refs = sh_atomic_inc(&pst->refs);
     419        assert(refs > 1);
     420        assert(refs < 256 /* bogus, but useful */);
     421        return refs;
     422}
     423
     424K_INLINE void pstackpush(shinstance *psh, pstack_block *pst)
     425{
     426        unsigned i = psh->pstacksize;
     427        if (i + 1 < psh->pstackalloced) {
     428                /* likely, except for the first time */
     429        } else {
     430                psh->pstack = (pstack_block **)ckrealloc(psh, psh->pstack, sizeof(psh->pstack[0]) * (i + 32));
     431                memset(&psh->pstack[i], 0, sizeof(psh->pstack[0]) * 32);
     432        }
     433        psh->pstack[i] = pst;
     434        psh->pstacksize = i + 1;
     435}
     436
     437/* Does not make it current! */
     438unsigned pstackretainpush(shinstance *psh, pstack_block *pst)
     439{
     440        unsigned refs = pstackretain(pst);
     441        pstackpush(psh, pst);
     442        TRACE2((psh, "pstackretainpush: %p - entry %u - %u refs\n", pst, psh->pstacksize - 1, refs));
     443        return refs;
     444}
     445
     446pstack_block *pstackallocpush(shinstance *psh)
    417447{
    418448        size_t const blocksize = offsetof(pstack_block, first.space) + MINSIZE;
    419449        pstack_block *pst;
    420         unsigned i;
    421450
    422451        INTOFF;
     
    443472
    444473        /*
    445          * Push it onto the stack.
     474         * Push it onto the stack and make it current.
    446475         */
    447         i = psh->pstacksize;
    448         if (i + 1 < psh->pstackalloced) {
    449                 /* likely, except for the first time */
    450         } else {
    451                 psh->pstack = (pstack_block **)ckrealloc(psh, psh->pstack, sizeof(psh->pstack[0]) * (i + 32));
    452                 memset(&psh->pstack[i], 0, sizeof(psh->pstack[0]) * 32);
    453         }
    454         psh->pstack[i] = pst;
    455         psh->pstacksize = i + 1;
     476        pstackpush(psh, pst);
    456477        psh->curpstack = pst;
    457478
    458479        INTON;
     480        TRACE2((psh, "pstackallocpush: %p - entry %u\n", pst, psh->pstacksize - 1));
    459481        return pst;
    460482}
     
    565587{
    566588#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
    567         pstack_block *pst = psh->curpstack;
     589        pstack_block * const pst = psh->curpstack;
     590        union node * const ret = (union node *)pstallocint(psh, pst, nbytes);
    568591        pst->nodesalloced++;
    569         return (union node *)pstallocint(psh, pst, nbytes);
     592        ret->pblock = pst;
     593        return ret;
    570594#else
    571595        return (union node *)pstalloc(psh, nbytes);
Note: See TracChangeset for help on using the changeset viewer.