home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / tek / mem / initmmu.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-12  |  17.6 KB  |  723 lines

  1.  
  2. #include "tek/mem.h"
  3. #include "tek/kn/exec.h"
  4. #include "tek/msg.h"
  5. #include "tek/debug.h"
  6.  
  7. /* 
  8. **    TEKlib
  9. **    (C) 2001 TEK neoscientists
  10. **    all rights reserved.
  11. **
  12. **    TBOOL TInitMMU(TMMU *mmu, TAPTR allocator, TUINT mmutype, TTAGITEM *tags)
  13. **
  14. **    initialize a memory management unit.
  15. **
  16. **    TODO:    - change interface to using taglists
  17. **
  18. */
  19.  
  20. static TINT mmudestroyfunc(TMMU *mmu);
  21.  
  22. static TAPTR voidalloc(TAPTR x, TUINT size);
  23. static TAPTR voidrealloc(TAPTR x, TAPTR oldmem, TUINT newsize);
  24. static TVOID voidfree(TAPTR x, TAPTR mem);
  25. static TUINT voidgetsize(TAPTR x, TAPTR mem);
  26.  
  27. static TAPTR mmu_kernelalloc(TAPTR userdata, TUINT size);
  28. static TVOID mmu_kernelfree(TAPTR mmu, TAPTR mem);
  29. static TAPTR mmu_kernelrealloc(TAPTR userdata, TAPTR oldmem, TUINT newsize);
  30. static TUINT mmu_kernelgetsize(TAPTR userdata, TAPTR mem);
  31.  
  32. static TAPTR mmu_trackalloc(TMMU *mmu, TUINT size);
  33. static TAPTR mmu_trackrealloc(TMMU *mmu, TBYTE *oldmem, TUINT newsize);
  34. static TVOID mmu_trackfree(TMMU *mmu, TBYTE *mem);
  35. static TUINT mmu_trackgetsize(TMMU *mmu, TBYTE *mem);
  36. static TINT mmu_trackdestroy(TMMU *mmu);
  37.  
  38. static TAPTR mmu_taskalloc(TMMU *mmu, TUINT size);
  39. static TAPTR mmu_taskrealloc(TMMU *mmu, TBYTE *oldmem, TUINT newsize);
  40. static TVOID mmu_taskfree(TMMU *mmu, TBYTE *mem);
  41. static TUINT mmu_taskgetsize(TMMU *mmu, TBYTE *mem);
  42. static TINT mmu_taskdestroy(TMMU *mmu);
  43.  
  44. static TAPTR mmu_tasktrackalloc(TMMU *mmu, TUINT size);
  45. static TAPTR mmu_tasktrackrealloc(TMMU *mmu, TBYTE *oldmem, TUINT newsize);
  46. static TVOID mmu_tasktrackfree(TMMU *mmu, TBYTE *mem);
  47. static TUINT mmu_tasktrackgetsize(TMMU *mmu, TBYTE *mem);
  48. static TINT mmu_tasktrackdestroy(TMMU *mmu);
  49.  
  50. static TAPTR pooltaskalloc(TMMU *mmu, TUINT size);
  51. static TAPTR pooltaskrealloc(TMMU *mmu, TAPTR oldmem, TUINT newsize);
  52. static TVOID pooltaskfree(TMMU *mmu, TAPTR mem);
  53. static TUINT pooltaskgetsize(TMMU *mmu, TAPTR mem);
  54. static TINT pooltaskdestroy(TMMU *mmu);
  55.  
  56. static TAPTR msgpooltaskalloc(TMMU *mmu, TUINT size);
  57. static TAPTR msgpooltaskrealloc(TMMU *mmu, TAPTR oldmem, TUINT newsize);
  58. static TVOID msgpooltaskfree(TMMU *mmu, TAPTR mem);
  59. static TUINT msgpooltaskgetsize(TMMU *mmu, TAPTR mem);
  60. static TINT msgpooltaskdestroy(TMMU *mmu);
  61.  
  62.  
  63. TBOOL TInitMMU(TMMU *mmu, TAPTR allocator, TUINT mmutype, TTAGITEM *tags)
  64. {
  65.     if (mmu)
  66.     {
  67.         kn_memset(mmu, sizeof(TMMU), 0);
  68.         mmu->handle.destroyfunc = (TDESTROYFUNC) mmudestroyfunc;
  69.  
  70.         switch (mmutype)
  71.         {
  72.             case TMMUT_Kernel:
  73.     
  74.                 if (!allocator)
  75.                 {
  76.                     /*    kernel allocator MMU */
  77.  
  78.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) mmu_kernelalloc;
  79.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) mmu_kernelfree;
  80.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) mmu_kernelrealloc;
  81.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) mmu_kernelgetsize;
  82.                     mmu->type = mmutype;
  83.                     return TTRUE;
  84.                 }
  85.                 break;
  86.     
  87.             case TMMUT_Static:
  88.             
  89.                 if (allocator)
  90.                 {
  91.                     /*    static allocator MMU */
  92.  
  93.                     mmu->allocator = allocator;
  94.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) TStaticAlloc;
  95.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) TStaticFree;
  96.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) TStaticRealloc;
  97.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) TStaticGetSize;
  98.                     mmu->type = mmutype;
  99.                     return TTRUE;
  100.                 }
  101.                 break;
  102.     
  103.             case TMMUT_Pooled:
  104.             
  105.                 if (allocator)
  106.                 {
  107.                     /*    pool allocator MMU */
  108.  
  109.                     mmu->allocator = allocator;
  110.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) TPoolAlloc;
  111.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) TPoolFree;
  112.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) TPoolRealloc;
  113.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) TPoolGetSize;
  114.                     mmu->type = mmutype;
  115.                     return TTRUE;
  116.                 }
  117.                 break;
  118.     
  119.             case TMMUT_MMU:
  120.             
  121.                 if (allocator)
  122.                 {
  123.                     /*    MMU-via-MMU allocator, implementing no additional functionality. */
  124.  
  125.                     mmu->allocator = allocator;
  126.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) TMMUAlloc;
  127.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) TMMUFree;
  128.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) TMMURealloc;
  129.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) TMMUGetSize;
  130.                     mmu->type = mmutype;
  131.                     return TTRUE;
  132.                 }
  133.                 else
  134.                 {
  135.                     /*    MMU-via-NULL-MMU allocator. valid, because a NULL MMU is defined to be a kernel allocator */
  136.  
  137.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) mmu_kernelalloc;
  138.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) mmu_kernelfree;
  139.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) mmu_kernelrealloc;
  140.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) mmu_kernelgetsize;
  141.                     mmu->type = mmutype;
  142.                     return TTRUE;
  143.                 }
  144.             
  145.             case TMMUT_Tracking:
  146.     
  147.                 /*    memory-tracking allocator on top of a MMU. */
  148.     
  149.                 TInitList(&mmu->tracklist);
  150.                 mmu->allocator = mmu;
  151.                 mmu->suballocator = allocator;
  152.                 mmu->destroymmufunc = (TDESTROYFUNC) mmu_trackdestroy;
  153.                 mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) mmu_trackalloc;
  154.                 mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) mmu_trackfree;
  155.                 mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) mmu_trackrealloc;
  156.                 mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) mmu_trackgetsize;
  157.                 mmu->type = mmutype;
  158.                 return TTRUE;                
  159.  
  160.  
  161.             case TMMUT_TaskSafe:
  162.     
  163.                 /*    task-safe allocator on top of a MMU. */
  164.     
  165.                 if (kn_initlock(&mmu->tasklock))
  166.                 {
  167.                     mmu->allocator = mmu;
  168.                     mmu->suballocator = allocator;
  169.                     mmu->destroymmufunc = (TDESTROYFUNC) mmu_taskdestroy;
  170.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) mmu_taskalloc;
  171.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) mmu_taskfree;
  172.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) mmu_taskrealloc;
  173.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) mmu_taskgetsize;
  174.                     mmu->type = mmutype;
  175.                     return TTRUE;
  176.                 }
  177.                 break;
  178.  
  179.             case TMMUT_TaskSafe+TMMUT_Tracking:
  180.     
  181.                 /*    tasksafe plus memory-tracking allocator on top of a MMU. */
  182.  
  183.                 if (kn_initlock(&mmu->tasklock))
  184.                 {            
  185.                     TInitList(&mmu->tracklist);
  186.                     mmu->allocator = mmu;
  187.                     mmu->suballocator = allocator;
  188.                     mmu->destroymmufunc = (TDESTROYFUNC) mmu_tasktrackdestroy;
  189.                     mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) mmu_tasktrackalloc;
  190.                     mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) mmu_tasktrackfree;
  191.                     mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) mmu_tasktrackrealloc;
  192.                     mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) mmu_tasktrackgetsize;
  193.                     mmu->type = mmutype;
  194.                     return TTRUE;
  195.                 }
  196.                 break;
  197.  
  198.             case TMMUT_TaskSafe+TMMUT_Pooled:
  199.             
  200.                 /* tasksafe allocator on top of a pool */
  201.  
  202.                 if (allocator)
  203.                 {
  204.                     if (kn_initlock(&mmu->tasklock))
  205.                     {
  206.                         mmu->allocator = mmu;
  207.                         mmu->suballocator = allocator;
  208.                         mmu->destroymmufunc = (TDESTROYFUNC) pooltaskdestroy;
  209.                         mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) pooltaskalloc;
  210.                         mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) pooltaskfree;
  211.                         mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) pooltaskrealloc;
  212.                         mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) pooltaskgetsize;
  213.                         mmu->type = mmutype;
  214.                         return TTRUE;
  215.                     }
  216.                 }
  217.                 break;
  218.  
  219.             case TMMUT_Message:
  220.             {
  221.                 TBOOL okay = TTRUE;
  222.             
  223.                 /* message allocator. currently this will be a tasksafe pooled allocator
  224.                 ** on top of either a NULL MMU, or on top of another MMU which must be of
  225.                 ** type TMMUT_Message as well */
  226.  
  227.                 if (allocator)
  228.                 {
  229.                     okay = (((TMMU *) allocator)->type == TMMUT_Message);
  230.                 }
  231.                 
  232.                 if (okay)
  233.                 {
  234.                     if (kn_initlock(&mmu->tasklock))
  235.                     {
  236.                         mmu->userdata = TCreatePool(allocator, 256, 128, TNULL);
  237.                         if (mmu->userdata)
  238.                         {
  239.                             mmu->allocator = mmu;
  240.                             mmu->suballocator = allocator;
  241.                             mmu->destroymmufunc = (TDESTROYFUNC) msgpooltaskdestroy;
  242.                             mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) msgpooltaskalloc;
  243.                             mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) msgpooltaskfree;
  244.                             mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) msgpooltaskrealloc;
  245.                             mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) msgpooltaskgetsize;
  246.                             mmu->type = mmutype;
  247.                             return TTRUE;
  248.                         }
  249.                         kn_destroylock(&mmu->tasklock);
  250.                     }
  251.                 }
  252.                 break;
  253.             }
  254.  
  255.             default:
  256.                 break;
  257.         }
  258.  
  259.         /*
  260.         **    as a fallback, initialize a void MMU that is incapable of allocating.
  261.         **    this allows usage of an MMU without checking the return value of
  262.         **    TInitMMU().
  263.         */
  264.  
  265.         mmu->allocfunc = (TAPTR (*)(TAPTR, TUINT)) voidalloc;
  266.         mmu->freefunc = (TVOID (*)(TAPTR, TAPTR)) voidfree;
  267.         mmu->reallocfunc = (TAPTR (*)(TAPTR, TAPTR, TUINT)) voidrealloc;
  268.         mmu->getsizefunc = (TUINT (*)(TAPTR, TAPTR)) voidgetsize;
  269.         mmu->type = TMMUT_Void;
  270.     }
  271.  
  272.     return TFALSE;
  273. }
  274.  
  275.  
  276. /**************************************************************************
  277. **    void allocator
  278. **************************************************************************/
  279.  
  280. static TAPTR voidalloc(TAPTR x, TUINT size)
  281. {
  282.     return TNULL;
  283. }
  284.  
  285. static TAPTR voidrealloc(TAPTR x, TAPTR oldmem, TUINT newsize)
  286. {
  287.     return TNULL;
  288. }    
  289.  
  290. static TVOID voidfree(TAPTR x, TAPTR mem)
  291. {
  292. }
  293.  
  294. static TUINT voidgetsize(TAPTR x, TAPTR mem)
  295. {
  296.     return 0;
  297. }
  298.  
  299.  
  300. /**************************************************************************
  301. **    kernel allocator
  302. **************************************************************************/
  303.  
  304. static TAPTR mmu_kernelalloc(TAPTR allocator, TUINT size)
  305. {
  306.     return kn_alloc(size);
  307. }
  308.  
  309. static TVOID mmu_kernelfree(TAPTR allocator, TAPTR mem)
  310. {
  311.     kn_free(mem);
  312. }
  313.  
  314. static TAPTR mmu_kernelrealloc(TAPTR allocator, TAPTR oldmem, TUINT newsize)
  315. {
  316.     return kn_realloc(oldmem, newsize);
  317. }
  318.  
  319. static TUINT mmu_kernelgetsize(TAPTR allocator, TAPTR mem)
  320. {
  321.     return kn_getsize(mem);
  322. }
  323.  
  324.  
  325.  
  326. /**************************************************************************
  327. **    tracking MMU allocator
  328. **************************************************************************/
  329.  
  330. static TAPTR mmu_trackalloc(TMMU *mmu, TUINT size)
  331. {
  332.     TBYTE *mem = TMMUAlloc(mmu->suballocator, size + sizeof(TNODE));
  333.     if (mem)
  334.     {
  335.         TAddTail(&mmu->tracklist, (TNODE *) mem);
  336.         return (TAPTR) (mem + sizeof(TNODE));
  337.     }
  338.     return TNULL;
  339. }
  340.  
  341. static TAPTR mmu_trackrealloc(TMMU *mmu, TBYTE *oldmem, TUINT newsize)
  342. {
  343.     TBYTE *newmem;
  344.  
  345.     if (oldmem)
  346.     {
  347.         TRemove((TNODE *) (oldmem - sizeof(TNODE)));
  348.         newmem = TMMURealloc(mmu->suballocator, oldmem - sizeof(TNODE), newsize + sizeof(TNODE));
  349.     }
  350.     else
  351.     {
  352.         newmem = TMMUAlloc(mmu->suballocator, newsize + sizeof(TNODE));
  353.     }
  354.  
  355.     if (newmem)
  356.     {
  357.         TAddTail(&mmu->tracklist, (TNODE *) newmem);
  358.         return (TAPTR) (newmem + sizeof(TNODE));
  359.     }
  360.     
  361.     return TNULL;
  362. }    
  363.  
  364. static TVOID mmu_trackfree(TMMU *mmu, TBYTE *mem)
  365. {
  366.     TRemove((TNODE *) (mem - sizeof(TNODE)));
  367.     TMMUFree(mmu->suballocator, mem - sizeof(TNODE));
  368. }
  369.  
  370. static TUINT mmu_trackgetsize(TMMU *mmu, TBYTE *mem)
  371. {
  372.     return TMMUGetSize(mmu->suballocator, mem - sizeof(TNODE));
  373. }
  374.  
  375. static TINT mmu_trackdestroy(TMMU *mmu)
  376. {
  377.     TNODE *nextnode, *node = mmu->tracklist.head;
  378.     TINT numfreed = 0;
  379.     
  380.     while ((nextnode = node->succ))
  381.     {
  382.         TMMUFree(mmu->suballocator, node);
  383.         numfreed++;
  384.         node = nextnode;
  385.     }
  386.  
  387.     if (numfreed) tdbprintf1(5, "*** mmu_trackdestroy: %d allocations pending\n", numfreed);
  388.     return numfreed;
  389. }
  390.  
  391.  
  392. /**************************************************************************
  393. **    tasksafe MMU allocator
  394. **************************************************************************/
  395.  
  396. static TAPTR mmu_taskalloc(TMMU *mmu, TUINT size)
  397. {
  398.     TBYTE *mem;
  399.     kn_lock(&mmu->tasklock);
  400.     mem = TMMUAlloc(mmu->suballocator, size);
  401.     kn_unlock(&mmu->tasklock);
  402.     return mem;
  403. }
  404.  
  405. static TAPTR mmu_taskrealloc(TMMU *mmu, TBYTE *oldmem, TUINT newsize)
  406. {
  407.     TBYTE *newmem;
  408.     kn_lock(&mmu->tasklock);
  409.     newmem = TMMURealloc(mmu->suballocator, oldmem, newsize);
  410.     kn_unlock(&mmu->tasklock);
  411.     return newmem;
  412. }    
  413.  
  414. static TVOID mmu_taskfree(TMMU *mmu, TBYTE *mem)
  415. {
  416.     kn_lock(&mmu->tasklock);
  417.     TMMUFree(mmu->suballocator, mem);
  418.     kn_unlock(&mmu->tasklock);
  419. }
  420.  
  421. static TUINT mmu_taskgetsize(TMMU *mmu, TBYTE *mem)
  422. {
  423.     TUINT size;
  424.     kn_lock(&mmu->tasklock);
  425.     size = TMMUGetSize(mmu->suballocator, mem);
  426.     kn_unlock(&mmu->tasklock);
  427.     return size;
  428. }
  429.  
  430. static TINT mmu_taskdestroy(TMMU *mmu)
  431. {
  432.     kn_destroylock(&mmu->tasklock);
  433.     return 0;
  434. }
  435.  
  436.  
  437.  
  438. /**************************************************************************
  439. **    tasksafe+tracking MMU allocator
  440. **************************************************************************/
  441.  
  442. static TAPTR mmu_tasktrackalloc(TMMU *mmu, TUINT size)
  443. {
  444.     TBYTE *mem;
  445.     kn_lock(&mmu->tasklock);    
  446.     mem = TMMUAlloc(mmu->suballocator, size + sizeof(TNODE));
  447.     if (mem)
  448.     {
  449.         TAddTail(&mmu->tracklist, (TNODE *) mem);
  450.         kn_unlock(&mmu->tasklock);    
  451.         return (TAPTR) (mem + sizeof(TNODE));
  452.     }
  453.     kn_unlock(&mmu->tasklock);    
  454.     return TNULL;
  455. }
  456.  
  457. static TAPTR mmu_tasktrackrealloc(TMMU *mmu, TBYTE *oldmem, TUINT newsize)
  458. {
  459.     TBYTE *newmem;
  460.     kn_lock(&mmu->tasklock);    
  461.     if (oldmem)
  462.     {
  463.         TRemove((TNODE *) (oldmem - sizeof(TNODE)));
  464.         newmem = TMMURealloc(mmu->suballocator, oldmem - sizeof(TNODE), newsize + sizeof(TNODE));
  465.     }
  466.     else
  467.     {
  468.         newmem = TMMUAlloc(mmu->suballocator, newsize + sizeof(TNODE));
  469.     }
  470.  
  471.     if (newmem)
  472.     {
  473.         TAddTail(&mmu->tracklist, (TNODE *) newmem);
  474.         kn_unlock(&mmu->tasklock);    
  475.         return (TAPTR) (newmem + sizeof(TNODE));
  476.     }
  477.     
  478.     kn_unlock(&mmu->tasklock);    
  479.     return TNULL;
  480. }    
  481.  
  482. static TVOID mmu_tasktrackfree(TMMU *mmu, TBYTE *mem)
  483. {
  484.     kn_lock(&mmu->tasklock);    
  485.     TRemove((TNODE *) (mem - sizeof(TNODE)));
  486.     TMMUFree(mmu->suballocator, mem - sizeof(TNODE));
  487.     kn_unlock(&mmu->tasklock);    
  488. }
  489.  
  490. static TUINT mmu_tasktrackgetsize(TMMU *mmu, TBYTE *mem)
  491. {
  492.     TUINT size;
  493.     kn_lock(&mmu->tasklock);    
  494.     size = TMMUGetSize(mmu->suballocator, mem - sizeof(TNODE)) - sizeof(TNODE);
  495.     kn_unlock(&mmu->tasklock);    
  496.     return size;
  497. }
  498.  
  499. static TINT mmu_tasktrackdestroy(TMMU *mmu)
  500. {
  501.     TNODE *nextnode, *node = mmu->tracklist.head;
  502.     TINT numfreed = 0;
  503.     
  504.     while ((nextnode = node->succ))
  505.     {
  506.         TMMUFree(mmu->suballocator, node);
  507.         numfreed++;
  508.         node = nextnode;
  509.     }
  510.  
  511.     kn_destroylock(&mmu->tasklock);
  512.  
  513.     if (numfreed) tdbprintf1(5, "*** mmu_tasktrackdestroy: %d allocations pending\n", numfreed);
  514.  
  515.     return numfreed;
  516. }
  517.  
  518.  
  519.  
  520. /**************************************************************************
  521. **    tasksafe allocator on top of a pool
  522. **************************************************************************/
  523.  
  524. static TAPTR pooltaskalloc(TMMU *mmu, TUINT size)
  525. {
  526.     TBYTE *mem;
  527.     kn_lock(&mmu->tasklock);
  528.     mem = TPoolAlloc(mmu->suballocator, size);
  529.     kn_unlock(&mmu->tasklock);
  530.     return mem;
  531. }
  532.  
  533. static TAPTR pooltaskrealloc(TMMU *mmu, TAPTR oldmem, TUINT newsize)
  534. {
  535.     TBYTE *newmem;
  536.     kn_lock(&mmu->tasklock);
  537.     newmem = TPoolRealloc(mmu->suballocator, oldmem, newsize);
  538.     kn_unlock(&mmu->tasklock);
  539.     return newmem;
  540. }    
  541.  
  542. static TVOID pooltaskfree(TMMU *mmu, TAPTR mem)
  543. {
  544.     kn_lock(&mmu->tasklock);
  545.     TPoolFree(mmu->suballocator, mem);
  546.     kn_unlock(&mmu->tasklock);
  547. }
  548.  
  549. static TUINT pooltaskgetsize(TMMU *mmu, TAPTR mem)
  550. {
  551.     TUINT size;
  552.     kn_lock(&mmu->tasklock);
  553.     size = TPoolGetSize(mmu->suballocator, mem);
  554.     kn_unlock(&mmu->tasklock);
  555.     return size;
  556. }
  557.  
  558. static TINT pooltaskdestroy(TMMU *mmu)
  559. {
  560.     kn_destroylock(&mmu->tasklock);
  561.     return 0;
  562. }
  563.  
  564.  
  565.  
  566. /**************************************************************************
  567. **    msg allocator
  568. **************************************************************************/
  569.  
  570. static TAPTR msgpooltaskalloc(TMMU *mmu, TUINT size)
  571. {
  572.     TMSG *msg;
  573.     kn_lock(&mmu->tasklock);
  574.     msg = TPoolAlloc(mmu->userdata, size + sizeof(TMSG));
  575.     kn_unlock(&mmu->tasklock);
  576.     if (msg)
  577.     {
  578.         msg->handle.destroyfunc = (TDESTROYFUNC) TNULL;
  579.         msg->handle.mmu = mmu;
  580.         msg->size = size + sizeof(TMSG);
  581.         msg->status = TMSG_STATUS_UNDEFINED;
  582.         return (TAPTR) (msg + 1);
  583.     }
  584.     return TNULL;
  585. }
  586.  
  587. static TAPTR msgpooltaskrealloc(TMMU *mmu, TAPTR oldmem, TUINT newsize)
  588. {
  589.     /*
  590.     **    messages cannot be reallocated.
  591.     */
  592.  
  593.     if (oldmem)
  594.     {
  595.         TMSG *oldmsg = ((TMSG *) oldmem) - 1;
  596.  
  597.         if (newsize == 0)
  598.         {
  599.             kn_lock(&mmu->tasklock);
  600.             TPoolFree(mmu->userdata, (TAPTR) oldmsg);
  601.             kn_unlock(&mmu->tasklock);
  602.         }
  603.         else
  604.         {
  605.             if (newsize + sizeof(TMSG) == oldmsg->size)
  606.             {
  607.                 return oldmem;
  608.             }
  609.         }
  610.     }
  611.     
  612.     return TNULL;
  613. }    
  614.  
  615. static TVOID msgpooltaskfree(TMMU *mmu, TAPTR mem)
  616. {
  617.     if (mem)
  618.     {
  619.         TMSG *msg = ((TMSG *) mem) - 1;
  620.         kn_lock(&mmu->tasklock);
  621.         TPoolFree(mmu->userdata, (TAPTR) msg);
  622.  
  623.         kn_unlock(&mmu->tasklock);
  624.     }
  625. }
  626.  
  627. static TUINT msgpooltaskgetsize(TMMU *mmu, TAPTR mem)
  628. {
  629.     if (mem)
  630.     {
  631.         TMSG *msg = ((TMSG *) mem) - 1;
  632.         return msg->size - sizeof(TMSG);
  633.     }
  634.     return 0;
  635. }
  636.  
  637. static TINT msgpooltaskdestroy(TMMU *mmu)
  638. {
  639.     TDestroy(mmu->userdata);
  640.     kn_destroylock(&mmu->tasklock);
  641.     return 0;
  642. }
  643.  
  644.  
  645.  
  646. /**************************************************************************
  647. **
  648. **    generic mmu destroy function
  649. **
  650. **    needs to be overwritten if a MMU was not initialized in place,
  651. **    but created with TMMUAllocHandle(), or when an underlying allocator
  652. **    is attached to and needs to be destroyed with the MMU.
  653. **
  654. **************************************************************************/
  655.  
  656. static TINT mmudestroyfunc(TMMU *mmu)
  657. {
  658.     if (mmu->destroymmufunc)
  659.     {
  660.         (*mmu->destroymmufunc)(mmu);
  661.     }
  662.     return 0;
  663. }
  664.  
  665.  
  666.  
  667.  
  668. #if 0
  669.  
  670. /**************************************************************************
  671. **
  672. **    beispiel für eine MMU mit zugrundeliegendem allocator,
  673. **    die als ganzes per TMMUAllocHandle() erzeugt und per
  674. **    TDestroy() zerstört wird
  675. **
  676. **************************************************************************/
  677.  
  678. static TINT destroycreatedmmu(TMMU *mmu)
  679. {
  680.     if (mmu->destroymmufunc)
  681.     {
  682.         (*mmu->destroymmufunc)(mmu);
  683.     }
  684.     
  685.     if (mmu->destroyallocatorfunc)
  686.     {
  687.         if (mmu->suballocator && mmu->allocator == mmu)
  688.         {
  689.             (*mmu->destroyallocatorfunc)(mmu->suballocator);
  690.         }
  691.         else if (mmu->allocator)
  692.         {
  693.             (*mmu->destroyallocatorfunc)(mmu->allocator);
  694.         }
  695.     }
  696.  
  697.     TMMUFreeHandle(mmu);
  698.     return 0;
  699. }
  700.  
  701. TMMU *createpoolmmu(TMMU *parentmmu)
  702. {
  703.     TMMU *mmu = TMMUAllocHandle(parentmmu, TNULL, sizeof(TMMU));
  704.     if (mmu)
  705.     {
  706.         TAPTR pool = TCreatePool(parentmmu, 256, 160, TNULL);
  707.         if (pool)
  708.         {
  709.             if (TInitMMU(mmu, pool, TMMUT_Pooled, TNULL))
  710.             {
  711.                 mmu->destroyallocatorfunc = TDestroy;
  712.                 mmu->handle.destroyfunc = (TDESTROYFUNC) destroycreatedmmu;        /* overwrite destructor */
  713.                 return mmu;
  714.             }
  715.             TDestroy(pool);
  716.         }
  717.         TMMUFree(parentmmu, mmu);
  718.     }
  719.     return TNULL;
  720. }
  721.  
  722. #endif
  723.