disksched.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "stdinc.h"
  10. #include "dat.h"
  11. #include "fns.h"
  12. uint32_t lasttime[2];
  13. int manualscheduling;
  14. int l0quantum = 120;
  15. int l1quantum = 120;
  16. uint32_t lasticachechange;
  17. void
  18. disksched(void)
  19. {
  20. int p, nwrite, nflush, ndirty, tdirty, toflush;
  21. uint32_t t;
  22. int64_t cflush;
  23. Stats *prev;
  24. /*
  25. * no locks because all the data accesses are atomic.
  26. */
  27. t = time(0);
  28. if(manualscheduling){
  29. lasticachechange = t;
  30. return;
  31. }
  32. if(t-lasttime[0] < l0quantum){
  33. /* level-0 disk access going on */
  34. p = icachedirtyfrac();
  35. if(p < IcacheFrac*5/10){ /* can wait */
  36. icachesleeptime = SleepForever;
  37. lasticachechange = t;
  38. }else if(p > IcacheFrac*9/10){ /* can't wait */
  39. icachesleeptime = 0;
  40. lasticachechange = t;
  41. }else if(t-lasticachechange > 60){
  42. /* have minute worth of data for current rate */
  43. prev = &stathist[(stattime-60+nstathist)%nstathist];
  44. /* # entries written to index cache */
  45. nwrite = stats.n[StatIcacheWrite] - prev->n[StatIcacheWrite];
  46. /* # dirty entries in index cache */
  47. ndirty = stats.n[StatIcacheDirty] - prev->n[StatIcacheDirty];
  48. /* # entries flushed to disk */
  49. nflush = nwrite - ndirty;
  50. /* want to stay around 70% dirty */
  51. tdirty = (int64_t)stats.n[StatIcacheSize]*700/1000;
  52. /* assume nflush*icachesleeptime is a constant */
  53. cflush = (int64_t)nflush*(icachesleeptime+1);
  54. /* computer number entries to write in next minute */
  55. toflush = nwrite + (stats.n[StatIcacheDirty] - tdirty);
  56. /* schedule for that many */
  57. if(toflush <= 0 || cflush/toflush > 100000)
  58. icachesleeptime = SleepForever;
  59. else
  60. icachesleeptime = cflush/toflush;
  61. }
  62. arenasumsleeptime = SleepForever;
  63. return;
  64. }
  65. if(t-lasttime[1] < l1quantum){
  66. /* level-1 disk access (icache flush) going on */
  67. icachesleeptime = 0;
  68. arenasumsleeptime = SleepForever;
  69. return;
  70. }
  71. /* no disk access going on - no holds barred*/
  72. icachesleeptime = 0;
  73. arenasumsleeptime = 0;
  74. }
  75. void
  76. diskaccess(int level)
  77. {
  78. if(level < 0 || level >= nelem(lasttime)){
  79. fprint(2, "bad level in diskaccess; caller=%#p\n",
  80. getcallerpc());
  81. return;
  82. }
  83. lasttime[level] = time(0);
  84. }