LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
123
返回列表 发新帖
楼主: lobby

linux灵活性太差了。。。。

[复制链接]
发表于 2008-7-9 17:53:52 | 显示全部楼层
对阿。我觉得最大的问题是minix3中貌似没有虚拟内存的概念。要人命 阿。
回复 支持 反对

使用道具 举报

发表于 2008-7-9 23:40:08 | 显示全部楼层
3好多了,1 2都是教学用的,内存管理是我对这书唯一看了的代码,非常简单,比dos的都简单.
人家的目的是教学演示.还有, 1和2 都是收费的哦.不是gpl
回复 支持 反对

使用道具 举报

发表于 2008-7-9 23:46:51 | 显示全部楼层
alloc.c
2.04的,简洁明了吧,大师写的代码就是不一样,看着就是种享受.
不过原理很简单,就是找到一块足够大的空闲快,分出去.
碎片问题很严重的.


  1. /* This file is concerned with allocating and freeing arbitrary-size blocks of
  2. * physical memory on behalf of the FORK and EXEC system calls.  The key data
  3. * structure used is the hole table, which maintains a list of holes in memory.
  4. * It is kept sorted in order of increasing memory address. The addresses
  5. * it contains refer to physical memory, starting at absolute address 0
  6. * (i.e., they are not relative to the start of MM).  During system
  7. * initialization, that part of memory containing the interrupt vectors,
  8. * kernel, and MM are "allocated" to mark them as not available and to
  9. * remove them from the hole list.
  10. *
  11. * The entry points into this file are:
  12. *   alloc_mem:        allocate a given sized chunk of memory
  13. *   free_mem:        release a previously allocated chunk of memory
  14. *   mem_init:        initialize the tables when MM start up
  15. *   max_hole:        returns the largest hole currently available
  16. */

  17. #include "mm.h"
  18. #include <minix/com.h>
  19. #include <minix/callnr.h>
  20. #include <signal.h>
  21. #include "mproc.h"

  22. #define NR_HOLES  (2*NR_PROCS)        /* max # entries in hole table */
  23. #define NIL_HOLE (struct hole *) 0

  24. PRIVATE struct hole {
  25.   struct hole *h_next;                /* pointer to next entry on the list */
  26.   phys_clicks h_base;                /* where does the hole begin? */
  27.   phys_clicks h_len;                /* how big is the hole? */
  28. } hole[NR_HOLES];

  29. PRIVATE struct hole *hole_head;        /* pointer to first hole */
  30. PRIVATE struct hole *free_slots;/* ptr to list of unused table slots */
  31. #if ENABLE_SWAP
  32. PRIVATE int swap_fd = -1;        /* file descriptor of open swap file/device */
  33. PRIVATE u32_t swap_offset;        /* offset to start of swap area on swap file */
  34. PRIVATE phys_clicks swap_base;        /* memory offset chosen as swap base */
  35. PRIVATE phys_clicks swap_maxsize;/* maximum amount of swap "memory" possible */
  36. PRIVATE struct mproc *in_queue;        /* queue of processes wanting to swap in */
  37. PRIVATE struct mproc *outswap = &mproc[LOW_USER];  /* outswap candidate? */
  38. #else /* !SWAP */
  39. #define swap_base ((phys_clicks) -1)
  40. #endif /* !SWAP */

  41. FORWARD _PROTOTYPE( void del_slot, (struct hole *prev_ptr, struct hole *hp) );
  42. FORWARD _PROTOTYPE( void merge, (struct hole *hp)                            );
  43. #if ENABLE_SWAP
  44. FORWARD _PROTOTYPE( int swap_out, (void)                                    );
  45. #else
  46. #define swap_out()        (0)
  47. #endif

  48. /*===========================================================================*
  49. *                                alloc_mem                                     *
  50. *===========================================================================*/
  51. PUBLIC phys_clicks alloc_mem(clicks)
  52. phys_clicks clicks;                /* amount of memory requested */
  53. {
  54. /* Allocate a block of memory from the free list using first fit. The block
  55. * consists of a sequence of contiguous bytes, whose length in clicks is
  56. * given by 'clicks'.  A pointer to the block is returned.  The block is
  57. * always on a click boundary.  This procedure is called when memory is
  58. * needed for FORK or EXEC.  Swap other processes out if needed.
  59. */

  60.   register struct hole *hp, *prev_ptr;
  61.   phys_clicks old_base;

  62.   do {
  63.         hp = hole_head;
  64.         while (hp != NIL_HOLE && hp->h_base < swap_base) {
  65.                 if (hp->h_len >= clicks) {
  66.                         /* We found a hole that is big enough.  Use it. */
  67.                         old_base = hp->h_base;        /* remember where it started */
  68.                         hp->h_base += clicks;        /* bite a piece off */
  69.                         hp->h_len -= clicks;        /* ditto */

  70.                         /* Delete the hole if used up completely. */
  71.                         if (hp->h_len == 0) del_slot(prev_ptr, hp);

  72.                         /* Return the start address of the acquired block. */
  73.                         return(old_base);
  74.                 }

  75.                 prev_ptr = hp;
  76.                 hp = hp->h_next;
  77.         }
  78.   } while (swap_out());                /* try to swap some other process out */
  79.   return(NO_MEM);
  80. }

  81. /*===========================================================================*
  82. *                                free_mem                                     *
  83. *===========================================================================*/
  84. PUBLIC void free_mem(base, clicks)
  85. phys_clicks base;                /* base address of block to free */
  86. phys_clicks clicks;                /* number of clicks to free */
  87. {
  88. /* Return a block of free memory to the hole list.  The parameters tell where
  89. * the block starts in physical memory and how big it is.  The block is added
  90. * to the hole list.  If it is contiguous with an existing hole on either end,
  91. * it is merged with the hole or holes.
  92. */

  93.   register struct hole *hp, *new_ptr, *prev_ptr;

  94.   if (clicks == 0) return;
  95.   if ( (new_ptr = free_slots) == NIL_HOLE) panic("Hole table full", NO_NUM);
  96.   new_ptr->h_base = base;
  97.   new_ptr->h_len = clicks;
  98.   free_slots = new_ptr->h_next;
  99.   hp = hole_head;

  100.   /* If this block's address is numerically less than the lowest hole currently
  101.    * available, or if no holes are currently available, put this hole on the
  102.    * front of the hole list.
  103.    */
  104.   if (hp == NIL_HOLE || base <= hp->h_base) {
  105.         /* Block to be freed goes on front of the hole list. */
  106.         new_ptr->h_next = hp;
  107.         hole_head = new_ptr;
  108.         merge(new_ptr);
  109.         return;
  110.   }

  111.   /* Block to be returned does not go on front of hole list. */
  112.   while (hp != NIL_HOLE && base > hp->h_base) {
  113.         prev_ptr = hp;
  114.         hp = hp->h_next;
  115.   }

  116.   /* We found where it goes.  Insert block after 'prev_ptr'. */
  117.   new_ptr->h_next = prev_ptr->h_next;
  118.   prev_ptr->h_next = new_ptr;
  119.   merge(prev_ptr);                /* sequence is 'prev_ptr', 'new_ptr', 'hp' */
  120. }

  121. /*===========================================================================*
  122. *                                del_slot                                     *
  123. *===========================================================================*/
  124. PRIVATE void del_slot(prev_ptr, hp)
  125. register struct hole *prev_ptr;        /* pointer to hole entry just ahead of 'hp' */
  126. register struct hole *hp;        /* pointer to hole entry to be removed */
  127. {
  128. /* Remove an entry from the hole list.  This procedure is called when a
  129. * request to allocate memory removes a hole in its entirety, thus reducing
  130. * the numbers of holes in memory, and requiring the elimination of one
  131. * entry in the hole list.
  132. */

  133.   if (hp == hole_head)
  134.         hole_head = hp->h_next;
  135.   else
  136.         prev_ptr->h_next = hp->h_next;

  137.   hp->h_next = free_slots;
  138.   free_slots = hp;
  139. }

  140. /*===========================================================================*
  141. *                                merge                                             *
  142. *===========================================================================*/
  143. PRIVATE void merge(hp)
  144. register struct hole *hp;        /* ptr to hole to merge with its successors */
  145. {
  146. /* Check for contiguous holes and merge any found.  Contiguous holes can occur
  147. * when a block of memory is freed, and it happens to abut another hole on
  148. * either or both ends.  The pointer 'hp' points to the first of a series of
  149. * three holes that can potentially all be merged together.
  150. */

  151.   register struct hole *next_ptr;

  152.   /* If 'hp' points to the last hole, no merging is possible.  If it does not,
  153.    * try to absorb its successor into it and free the successor's table entry.
  154.    */
  155.   if ( (next_ptr = hp->h_next) == NIL_HOLE) return;
  156.   if (hp->h_base + hp->h_len == next_ptr->h_base) {
  157.         hp->h_len += next_ptr->h_len;        /* first one gets second one's mem */
  158.         del_slot(hp, next_ptr);
  159.   } else {
  160.         hp = next_ptr;
  161.   }

  162.   /* If 'hp' now points to the last hole, return; otherwise, try to absorb its
  163.    * successor into it.
  164.    */
  165.   if ( (next_ptr = hp->h_next) == NIL_HOLE) return;
  166.   if (hp->h_base + hp->h_len == next_ptr->h_base) {
  167.         hp->h_len += next_ptr->h_len;
  168.         del_slot(hp, next_ptr);
  169.   }
  170. }

  171. /*===========================================================================*
  172. *                                mem_init                                     *
  173. *===========================================================================*/
  174. PUBLIC void mem_init(total, free)
  175. phys_clicks *total, *free;                /* memory size summaries */
  176. {
  177. /* Initialize hole lists.  There are two lists: 'hole_head' points to a linked
  178. * list of all the holes (unused memory) in the system; 'free_slots' points to
  179. * a linked list of table entries that are not in use.  Initially, the former
  180. * list has one entry for each chunk of physical memory, and the second
  181. * list links together the remaining table slots.  As memory becomes more
  182. * fragmented in the course of time (i.e., the initial big holes break up into
  183. * smaller holes), new table slots are needed to represent them.  These slots
  184. * are taken from the list headed by 'free_slots'.
  185. */

  186.   register struct hole *hp;
  187.   phys_clicks base;                /* base address of chunk */
  188.   phys_clicks size;                /* size of chunk */
  189.   message mess;

  190.   /* Put all holes on the free list. */
  191.   for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
  192.   hole[NR_HOLES-1].h_next = NIL_HOLE;
  193.   hole_head = NIL_HOLE;
  194.   free_slots = &hole[0];

  195.   /* Ask the kernel for chunks of physical memory and allocate a hole for
  196.    * each of them.  The SYS_MEM call responds with the base and size of the
  197.    * next chunk and the total amount of memory.
  198.    */
  199.   *free = 0;
  200.   for (;;) {
  201.         mess.m_type = SYS_MEM;
  202.         if (sendrec(SYSTASK, &mess) != OK) panic("bad SYS_MEM?", NO_NUM);
  203.         base = mess.m1_i1;
  204.         size = mess.m1_i2;
  205.         if (size == 0) break;                /* no more? */

  206.         free_mem(base, size);
  207.         *total = mess.m1_i3;
  208.         *free += size;
  209. #if ENABLE_SWAP
  210.         if (swap_base < base + size) swap_base = base+size;
  211. #endif
  212.   }

  213. #if ENABLE_SWAP
  214.   /* The swap area is represented as a hole above and separate of regular
  215.    * memory.  A hole at the size of the swap file is allocated on "swapon".
  216.    */
  217.   swap_base++;                                /* make separate */
  218.   swap_maxsize = 0 - swap_base;                /* maximum we can possibly use */
  219. #endif
  220. }

  221. #if ENABLE_SWAP
  222. /*===========================================================================*
  223. *                                swap_on                                             *
  224. *===========================================================================*/
  225. PUBLIC int swap_on(file, offset, size)
  226. char *file;                                /* file to swap on */
  227. u32_t offset, size;                        /* area on swap file to use */
  228. {
  229. /* Turn swapping on. */

  230.   if (swap_fd != -1) return(EBUSY);        /* already have swap? */

  231.   tell_fs(CHDIR, who, FALSE, 0);        /* be like the caller for open() */
  232.   if ((swap_fd = open(file, O_RDWR)) < 0) return(-errno);
  233.   swap_offset = offset;
  234.   size >>= CLICK_SHIFT;
  235.   if (size > swap_maxsize) size = swap_maxsize;
  236.   if (size > 0) free_mem(swap_base, (phys_clicks) size);
  237. }

  238. /*===========================================================================*
  239. *                                swap_off                                     *
  240. *===========================================================================*/
  241. PUBLIC int swap_off()
  242. {
  243. /* Turn swapping off. */
  244.   struct mproc *rmp;
  245.   struct hole *hp, *prev_ptr;

  246.   if (swap_fd == -1) return(OK);        /* can't turn off what isn't on */

  247.   /* Put all swapped out processes on the inswap queue and swap in. */
  248.   for (rmp = &mproc[LOW_USER]; rmp < &mproc[NR_PROCS]; rmp++) {
  249.         if (rmp->mp_flags & ONSWAP) swap_inqueue(rmp);
  250.   }
  251.   swap_in();

  252.   /* All in memory? */
  253.   for (rmp = &mproc[LOW_USER]; rmp < &mproc[NR_PROCS]; rmp++) {
  254.         if (rmp->mp_flags & ONSWAP) return(ENOMEM);
  255.   }

  256.   /* Yes.  Remove the swap hole and close the swap file descriptor. */
  257.   for (hp = hole_head; hp != NIL_HOLE; prev_ptr = hp, hp = hp->h_next) {
  258.         if (hp->h_base >= swap_base) {
  259.                 del_slot(prev_ptr, hp);
  260.                 hp = hole_head;
  261.         }
  262.   }
  263.   close(swap_fd);
  264.   swap_fd = -1;
  265.   return(OK);
  266. }

  267. /*===========================================================================*
  268. *                                swap_inqueue                                     *
  269. *===========================================================================*/
  270. PUBLIC void swap_inqueue(rmp)
  271. register struct mproc *rmp;                /* process to add to the queue */
  272. {
  273. /* Put a swapped out process on the queue of processes to be swapped in.  This
  274. * happens when such a process gets a signal, or if a reply message must be
  275. * sent, like when a process doing a wait() has a child that exits.
  276. */
  277.   struct mproc **pmp;

  278.   if (rmp->mp_flags & SWAPIN) return;        /* already queued */

  279.   
  280.   for (pmp = &in_queue; *pmp != NULL; pmp = &(*pmp)->mp_swapq) {}
  281.   *pmp = rmp;
  282.   rmp->mp_swapq = NULL;
  283.   rmp->mp_flags |= SWAPIN;
  284. }

  285. /*===========================================================================*
  286. *                                swap_in                                             *
  287. *===========================================================================*/
  288. PUBLIC void swap_in()
  289. {
  290. /* Try to swap in a process on the inswap queue.  We want to send it a message,
  291. * interrupt it, or something.
  292. */
  293.   struct mproc **pmp, *rmp;
  294.   phys_clicks old_base, new_base, size;
  295.   off_t off;
  296.   int proc_nr;

  297.   pmp = &in_queue;
  298.   while ((rmp = *pmp) != NULL) {
  299.         proc_nr = (rmp - mproc);
  300.         size = rmp->mp_seg[S].mem_vir + rmp->mp_seg[S].mem_len
  301.                 - rmp->mp_seg[D].mem_vir;

  302.         if (!(rmp->mp_flags & SWAPIN)) {
  303.                 /* Guess it got killed.  (Queue is cleaned here.) */
  304.                 *pmp = rmp->mp_swapq;
  305.                 continue;
  306.         } else
  307.         if ((new_base = alloc_mem(size)) == NO_MEM) {
  308.                 /* No memory for this one, try the next. */
  309.                 pmp = &rmp->mp_swapq;
  310.         } else {
  311.                 /* We've found memory.  Update map and swap in. */
  312.                 old_base = rmp->mp_seg[D].mem_phys;
  313.                 rmp->mp_seg[D].mem_phys = new_base;
  314.                 rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys +
  315.                         (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
  316.                 sys_newmap(proc_nr, rmp->mp_seg);
  317.                 off = swap_offset + ((off_t) (old_base-swap_base)<<CLICK_SHIFT);
  318.                 lseek(swap_fd, off, SEEK_SET);
  319.                 rw_seg(0, swap_fd, proc_nr, D, (phys_bytes)size << CLICK_SHIFT);
  320.                 free_mem(old_base, size);
  321.                 rmp->mp_flags &= ~(ONSWAP|SWAPIN);
  322.                 *pmp = rmp->mp_swapq;
  323.                 check_pending(rmp);        /* a signal may have waked this one */
  324.         }
  325.   }
  326. }

  327. /*===========================================================================*
  328. *                                swap_out                                     *
  329. *===========================================================================*/
  330. PRIVATE int swap_out()
  331. {
  332. /* Try to find a process that can be swapped out.  Candidates are those blocked
  333. * on a system call that MM handles, like wait(), pause() or sigsuspend().
  334. */
  335.   struct mproc *rmp;
  336.   struct hole *hp, *prev_ptr;
  337.   phys_clicks old_base, new_base, size;
  338.   off_t off;
  339.   int proc_nr;

  340.   rmp = outswap;
  341.   do {
  342.         if (++rmp == &mproc[NR_PROCS]) rmp = &mproc[LOW_USER];

  343.         /* A candidate? */
  344.         if (!(rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED))) continue;

  345.         /* Already on swap or otherwise to be avoided? */
  346.         if (rmp->mp_flags & (TRACED | REPLY | ONSWAP)) continue;

  347.         /* Got one, find a swap hole and swap it out. */
  348.         proc_nr = (rmp - mproc);
  349.         size = rmp->mp_seg[S].mem_vir + rmp->mp_seg[S].mem_len
  350.                 - rmp->mp_seg[D].mem_vir;

  351.         prev_ptr = NIL_HOLE;
  352.         for (hp = hole_head; hp != NIL_HOLE; prev_ptr = hp, hp = hp->h_next) {
  353.                 if (hp->h_base >= swap_base && hp->h_len >= size) break;
  354.         }
  355.         if (hp == NIL_HOLE) continue;        /* oops, not enough swapspace */
  356.         new_base = hp->h_base;
  357.         hp->h_base += size;
  358.         hp->h_len -= size;
  359.         if (hp->h_len == 0) del_slot(prev_ptr, hp);

  360.         off = swap_offset + ((off_t) (new_base - swap_base) << CLICK_SHIFT);
  361.         lseek(swap_fd, off, SEEK_SET);
  362.         rw_seg(1, swap_fd, proc_nr, D, (phys_bytes)size << CLICK_SHIFT);
  363.         old_base = rmp->mp_seg[D].mem_phys;
  364.         rmp->mp_seg[D].mem_phys = new_base;
  365.         rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys +
  366.                 (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
  367.         sys_newmap(proc_nr, rmp->mp_seg);
  368.         free_mem(old_base, size);
  369.         rmp->mp_flags |= ONSWAP;

  370.         outswap = rmp;                /* next time start here */
  371.         return(TRUE);
  372.   } while (rmp != outswap);

  373.   return(FALSE);        /* no candidate found */
  374. }
  375. #endif /* SWAP */

复制代码
回复 支持 反对

使用道具 举报

发表于 2008-7-10 09:03:40 | 显示全部楼层
linux的灵活性很强
不同的人有不同的配置
不同的机子也有不同的配置

一是提高充分挖掘机子的潜能,做到最合理的运用
二是满足不同层次的人在使用linux时有用不同的效果,满足不同需求
回复 支持 反对

使用道具 举报

发表于 2008-7-10 10:03:45 | 显示全部楼层
你们都没有理解楼主的意思啊,楼主心理想的是linux不够智能。
回复 支持 反对

使用道具 举报

发表于 2008-7-10 11:25:53 | 显示全部楼层
呵呵,大家都明白楼主的意思,反着说

一下子想起《大头儿子小头爸爸》动画片上的“喂饭机"
真智能
回复 支持 反对

使用道具 举报

发表于 2008-7-11 21:57:05 | 显示全部楼层
哇赛,竟有人敢在Linux论坛里说Linux灵活性太差.....
佩服...
回复 支持 反对

使用道具 举报

发表于 2008-7-12 12:19:34 | 显示全部楼层
Post by linuxahah;1873586
哇赛,竟有人敢在Linux论坛里说Linux灵活性太差.....
佩服...


哈哈,经典!!!
回复 支持 反对

使用道具 举报

发表于 2008-7-12 12:51:28 | 显示全部楼层
stop, ok?
BTW, 换了主板不重装好像在windows也很麻烦啊....
回复 支持 反对

使用道具 举报

发表于 2008-7-12 22:59:32 | 显示全部楼层
Post by LinuxIsHard;1873730
stop, ok?
BTW, 换了主板不重装好像在windows也很麻烦啊....


哈哈,stop
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表