home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / os / bsdss4.tz / bsdss4 / bsdss / server / uxkern / zalloc.c < prev   
Encoding:
C/C++ Source or Header  |  1992-04-22  |  5.2 KB  |  235 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1992 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon 
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    zalloc.c,v $
  29.  * Revision 2.1  92/04/21  17:11:20  rwd
  30.  * BSDSS
  31.  * 
  32.  *
  33.  */
  34.  
  35. #include <sys/zalloc.h>
  36. #include <uxkern/import_mach.h>
  37.  
  38. zone_t        zone_zone;    /* this is the zone containing other zones */
  39.  
  40. boolean_t    zone_ignore_overflow = FALSE;
  41.  
  42. vm_offset_t    zdata;
  43. vm_size_t    zdata_size;
  44.  
  45. #define    lock_zone(zone)        mutex_lock(&zone->lock)
  46.  
  47. #define    unlock_zone(zone)    mutex_unlock(&zone->lock)
  48.  
  49. #define    lock_zone_init(zone)    mutex_init(&zone->lock)
  50.  
  51. /*
  52.  *    Initialize the "zone of zones."
  53.  */
  54. void zone_init()
  55. {
  56.     vm_offset_t    p;
  57.  
  58.     zdata_size = round_page(64 * sizeof(struct zone));
  59.     (void) vm_allocate(mach_task_self(), &zdata, zdata_size, TRUE);
  60. #if    0
  61.     (void) vm_pageable(mach_task_self(), zdata, zdata_size,
  62.                VM_PROT_READ|VM_PROT_WRITE);
  63. #endif
  64.  
  65.     zone_zone = ZONE_NULL;
  66.     zone_zone = zinit(sizeof(struct zone), sizeof(struct zone), 0,
  67.                     FALSE, "zones");
  68.     p = (vm_offset_t)(zone_zone + 1);
  69.     zcram(zone_zone, p, (zdata + zdata_size) - p);
  70. }
  71.  
  72. /*
  73.  *    zinit initializes a new zone.  The zone data structures themselves
  74.  *    are stored in a zone, which is initially a static structure that
  75.  *    is initialized by zone_init.
  76.  */
  77. zone_t zinit(size, max, alloc, pageable, name)
  78.     vm_size_t    size;        /* the size of an element */
  79.     vm_size_t    max;        /* maximum memory to use */
  80.     vm_size_t    alloc;        /* allocation size */
  81.     boolean_t    pageable;    /* is this zone pageable? */
  82.     char        *name;        /* a name for the zone */
  83. {
  84.     register zone_t        z;
  85.  
  86.     if (zone_zone == ZONE_NULL)
  87.         z = (zone_t) zdata;
  88.     else if ((z = (zone_t) zalloc(zone_zone)) == ZONE_NULL)
  89.         return(ZONE_NULL);
  90.  
  91.     /*
  92.      *    Round off all the parameters appropriately.
  93.      */
  94.  
  95.     if ((max = round_page(max)) < (alloc = round_page(alloc)))
  96.         max = alloc;
  97.  
  98.     z->free_elements = 0;
  99.     z->cur_size = 0;
  100.     z->max_size = max;
  101.     z->elem_size = size;
  102.     z->alloc_size = alloc;
  103.     z->pageable = pageable;
  104.     z->zone_name = name;
  105.     z->count = 0;
  106.     z->doing_alloc = FALSE;
  107.     z->exhaustible = z->sleepable = FALSE;
  108.     lock_zone_init(z);
  109.     return(z);
  110. }
  111.  
  112. /*
  113.  *    Cram the given memory into the specified zone.
  114.  */
  115. void zcram(zone, newmem, size)
  116.     register zone_t        zone;
  117.     vm_offset_t        newmem;
  118.     vm_size_t        size;
  119. {
  120.     register vm_size_t    elem_size;
  121.  
  122.     elem_size = zone->elem_size;
  123.  
  124.     lock_zone(zone);
  125.     zone->cur_size += size;
  126.     while (size >= elem_size) {
  127.         ADD_TO_ZONE(zone, newmem);
  128.         zone->count++;    /* compensate for ADD_TO_ZONE */
  129.         size -= elem_size;
  130.         newmem += elem_size;
  131.     }
  132.     unlock_zone(zone);
  133. }
  134.  
  135. /*
  136.  *    zalloc returns an element from the specified zone.
  137.  */
  138. vm_offset_t zalloc(zone)
  139.     register zone_t    zone;
  140. {
  141.     register vm_offset_t    addr;
  142.  
  143.     if (zone == ZONE_NULL)
  144.         panic ("zalloc: null zone");
  145.  
  146.     lock_zone(zone);
  147.     REMOVE_FROM_ZONE(zone, addr, vm_offset_t);
  148.     while (addr == 0) {
  149.         /*
  150.          *    If nothing was there, try to get more
  151.          */
  152.         vm_offset_t    alloc_addr;
  153.  
  154.         if ((zone->cur_size + zone->alloc_size) > zone->max_size) {
  155.             if (zone->exhaustible)
  156.                 break;
  157.  
  158.             if (!zone_ignore_overflow) {
  159.                 printf("zone \"%s\" empty.\n", zone->zone_name);
  160.                 panic("zalloc");
  161.             }
  162.         }
  163.         unlock_zone(zone);
  164.  
  165.         if (vm_allocate(mach_task_self(),
  166.                 &alloc_addr,
  167.                 zone->alloc_size,
  168.                 TRUE)
  169.             != KERN_SUCCESS) {
  170.             if (zone->exhaustible)
  171.             break;
  172.             panic("zalloc");
  173.         }
  174. #if    0
  175.         if (!zone->pageable) {
  176.             (void) vm_pageable(mach_task_self(),
  177.                     alloc_addr,
  178.                     zone->alloc_size,
  179.                     VM_PROT_READ|VM_PROT_WRITE);
  180.         }
  181. #endif
  182.         zcram(zone, alloc_addr, zone->alloc_size);
  183.  
  184.         lock_zone(zone);
  185.  
  186.         REMOVE_FROM_ZONE(zone, addr, vm_offset_t);
  187.     }
  188.  
  189.     unlock_zone(zone);
  190.     return(addr);
  191. }
  192.  
  193. /*
  194.  *    zget returns an element from the specified zone
  195.  *    and immediately returns nothing if there is nothing there.
  196.  *
  197.  *    This form should be used when you can not block (like when
  198.  *    processing an interrupt).
  199.  */
  200. vm_offset_t zget(zone)
  201.     register zone_t    zone;
  202. {
  203.     register vm_offset_t    addr;
  204.  
  205.     if (zone == ZONE_NULL)
  206.         panic ("zalloc: null zone");
  207.  
  208.     lock_zone(zone);
  209.     REMOVE_FROM_ZONE(zone, addr, vm_offset_t);
  210.     unlock_zone(zone);
  211.  
  212.     return(addr);
  213. }
  214.  
  215. void zfree(zone, elem)
  216.     register zone_t    zone;
  217.     vm_offset_t    elem;
  218. {
  219.     lock_zone(zone);
  220.     ADD_TO_ZONE(zone, elem);
  221.     unlock_zone(zone);
  222. }
  223.  
  224.  
  225. void zchange(zone, pageable, sleepable, exhaustible)
  226.     zone_t        zone;
  227.     boolean_t    pageable;
  228.     boolean_t    sleepable;
  229.     boolean_t    exhaustible;
  230. {
  231.     zone->pageable = pageable;
  232.     zone->sleepable = sleepable;
  233.     zone->exhaustible = exhaustible;
  234. }
  235.