AMemMan (メモリ管理)

(0)

(1)

(2)

(3) ver.1.00 [2024.09.13] (242行)

#include "acl1Tiny.c"
AClass(AM) {
    void *alc, *fre, *rlc, *arp, *rls, *dst, *p0, *p1; AInt n, total;
};

AInlineStatic void AM_arp(AM *w, void *f, void *v0, void *v1, void *v2)
{
    void (*arp)(void *, void *, void *, void *, void *);
    arp = w->arp; arp(w, f, v0, v1, v2);
}

AInlineStatic void AM_fre(AM *w, void *p, AInt sz)
{
    if (p != 0) {
        void (*fre)(void *, void *, AInt);
        fre = w->fre; fre(w, p, sz);
    }
}

AStatic void *AM_alc(AM *w, int f, AInt sz)
// f= 1:arp, 2:clr, 4:err
{
    void *(*alc)(void *, AInt);
    alc = w->alc; void *p = alc(w, sz); // nやtotalは下位が管理する.
    if (p == 0) {
        if ((f & 4) == 0) aErrExit("AM_alc: out of memory");
        return 0;
    }
    if ((f & 2) != 0) memset(p, 0, sz);
    if ((f & 1) != 0) AM_arp(w, w->fre, w, p, (void *) sz);
    return p;
}

AStatic void *AM_rlc(AM *w, AInt f, void *p, AInt sz0, AInt sz1)
{
    void *(*rlc)(void *, void *, AInt, AInt);
    rlc = w->rlc; p = rlc(w, p, sz0, sz1);
    if (p == 0) {
        if ((f & 4) == 0) aErrExit("AM_rlc: out of memory");
        return 0;
    }
    if ((f & 2) != 0 && sz0 < sz1) memset(((char *) p) + sz0, 0, sz1 - sz0);
    // rlcはarpに対応しない.
    return p;
}

AInlineStatic void AM_rls(AM *w) { void (*rls)(void *); rls = w->rls; rls(w); }
AInlineStatic void AM_dst(AM *w) { void (*dst)(void *); dst = w->dst; dst(w); }

AInlineStatic void *AM0_alc(AM *w, AInt sz)
{
    void *p = malloc(sz);
    #if (ADbgLv >= 1)
        if (p != 0) { w->n++; w->total += sz; }
    #endif
    return p;
}

AInlineStatic void AM0_fre(AM *w, void *p, AInt sz)
{
    free(p);
    #if (ADbgLv >= 1)
        w->n--; w->total -= sz;
    #endif
}

AInlineStatic void *AM0_rlc(AM *w, void *p, AInt sz0, AInt sz1)
{
    void *q = realloc(p, sz1);
    #if (ADbgLv >= 1)
        if (q != 0) {
            if (p != 0) { w->n--; w->total -= sz0; }
            w->n++; w->total += sz1;
        }
    #endif
    return q;
}

AClass(AM0_Sub) { void *f, *v0, *v1, *v2, *n; };

AInlineStatic void AM0_arp(AM *w, void *f, void *v0, void *v1, void *v2)
{
    AM0_Sub *s = AM_alc(w, 0, sizeof (AM0_Sub));
    s->f = f;
    s->v0 = v0;
    s->v1 = v1;
    s->v2 = v2;
    s->n = w->p0;
    w->p0 = s;
}

AStatic void AM0_rls(AM *w)
{
    void (*f)(void *, void *, void *);
    void *v0, *v1, *v2;
    AM0_Sub *s, *n;
    for (s = w->p0; s != 0; s = n) {
        f = s->f;
        v0 = s->v0;
        v1 = s->v1;
        v2 = s->v2;
        n = s->n;
        AM_fre(w, s, sizeof (AM0_Sub)); // 逆順にこだわるので、Subのfreの方が先.
        f(v0, v1, v2);
    }
    w->p0 = 0;
}

AInlineStatic void AM0_dst(AM *w)
{
    AM_rls(w);
    #if (ADbgLv >= 1)
        if (w->n != 0 || w->total != 0) aErrExit("AM0_dst: error(n=%d, total=%d)", w->n, w->total);
    #endif
}

AStatic AM am0[1] = { AM0_alc, AM0_fre, AM0_rlc, AM0_arp, AM0_rls, AM0_dst, 0, 0, 0, 0 };

AInlineStatic void *AM1_alc(AM *w, AInt sz)
{
    AM *v = w->p1;
    void *(*alc)(void *, AInt);
    alc = v->alc; void *p = alc(v, sz);
    #if (ADbgLv >= 1)
        if (p != 0) { w->n++; w->total += sz; }
    #endif
    return p;
}

AInlineStatic void AM1_fre(AM *w, void *p, AInt sz)
{
    AM *v = w->p1;
    void (*fre)(void *, void *, AInt);
    fre = v->fre; fre(v, p, sz);
    #if (ADbgLv >= 1)
        w->n--; w->total -= sz;
    #endif
}

AInlineStatic void *AM1_rlc(AM *w, void *p, AInt sz0, AInt sz1)
{
    AM *v = w->p1;
    void *(*rlc)(void *, void *, AInt, AInt);
    rlc = v->rlc; void *q = rlc(v, p, sz0, sz1);
    #if (ADbgLv >= 1)
        if (q != 0) {
            if (p != 0) { w->n--; w->total -= sz0; }
            w->n++; w->total += sz1;
        }
    #endif
    return q;
}

AStatic AM *AM1_opn(int f, AM *m)
{
    AM *w = AM_alc(m, f, sizeof (AM));
    if (w == 0) return 0;
    w->alc = AM1_alc;
    w->fre = AM1_fre;
    w->rlc = AM1_rlc;
    w->arp = AM0_arp;
    w->rls = AM0_rls;
    w->dst = AM0_dst;
    w->n = w->total = 0;
    w->p0 = 0;
    w->p1 = m;
    if ((f & 1) != 0) AM_arp(m, AM0_dst, w, 0, 0);
    return w;
}

AClass(AM2) {
    void *alc, *fre, *rlc, *arp, *rls, *dst, *p0, *p1; AInt n, total;
    AInt sz, nn, *p2;
};

AInlineStatic void AM2_fre(AM2 *w, void *p, AInt sz)
{
     *(void **) p = w->p2; w->p2 = p;
     #if (ADbgLv >= 1)
         w->n--; w->total -= w->sz;
     #endif
}

AStatic int AM2_alcSub(AM2 *w)
{
    char *p = AM_alc(w->p1, 5, w->sz * w->nn);
    if (p == 0) return 1;
    AInt i;
    #if (ADbgLv >= 1)
        w->n += w->nn; w->total += w->nn * w->sz;
    #endif
    for (i = (w->nn - 1) * w->sz; i >= 0; i -= w->sz)
        AM2_fre(w, p + i, 0);
    return 0;
}

AInlineStatic void *AM2_alc(AM2 *w, AInt sz)
{
    if (w->p2 == 0 && AM2_alcSub(w) != 0) return 0;
    void *p = w->p2; w->p2 = *(void **) p;
    #if (ADbgLv >= 1)
        w->n++; w->total += w->sz;
    #endif
    return p;
}

AInlineStatic void *AM2_rlc(AM2 *w, void *p, AInt sz0, AInt sz1) { return p; }

AInlineStatic void AM2_dst(AM *w)
{
    AM *w1 = w->p1, *m = w1->p1;
    AM_rls(w);
    #if (ADbgLv >= 1)
        if (w->n != 0 || w->total != 0) aErrExit("AM2_dst: error(n=%d, total=%d)", w->n, w->total);
    #endif
    AM_dst(w1);
    AM_fre(m, w1, sizeof (AM));
}

AStatic AM *AM2_opn(int f, AM *m, AInt sz, AInt nn)
{
    AM2 *w2 = AM_alc(m, f, sizeof (AM2));
    if (w2 == 0) return 0;
    AM *w1 = AM1_opn(f & 4, m);
    if (w1 == 0) {
        if ((f & 1) == 0) AM_fre(m, w2, sizeof (AM2));
        return 0;
    }
    w2->alc = AM2_alc;
    w2->fre = AM2_fre;
    w2->rlc = AM2_rlc;
    w2->arp = AM0_arp;
    w2->rls = AM0_rls;
    w2->dst = AM2_dst;
    w2->n = w2->total = 0;
    w2->p0 = 0;
    w2->p1 = w1;
    w2->p2 = 0;
    w2->sz = sz;
    w2->nn = nn;
    if ((f & 1) != 0) AM_arp(m, AM2_dst, w2, 0, 0);
    return (AM *) w2;
}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS