disksched.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. ulong lasttime[2];
  5. int manualscheduling;
  6. int l0quantum = 120;
  7. int l1quantum = 120;
  8. ulong lasticachechange;
  9. void
  10. disksched(void)
  11. {
  12. int p, nwrite, nflush, ndirty, tdirty, toflush;
  13. ulong t;
  14. vlong cflush;
  15. Stats *prev;
  16. /*
  17. * no locks because all the data accesses are atomic.
  18. */
  19. t = time(0);
  20. if(manualscheduling){
  21. lasticachechange = t;
  22. return;
  23. }
  24. if(t-lasttime[0] < l0quantum){
  25. /* level-0 disk access going on */
  26. p = icachedirtyfrac();
  27. if(p < IcacheFrac*5/10){ /* can wait */
  28. icachesleeptime = SleepForever;
  29. lasticachechange = t;
  30. }else if(p > IcacheFrac*9/10){ /* can't wait */
  31. icachesleeptime = 0;
  32. lasticachechange = t;
  33. }else if(t-lasticachechange > 60){
  34. /* have minute worth of data for current rate */
  35. prev = &stathist[(stattime-60+nstathist)%nstathist];
  36. /* # entries written to index cache */
  37. nwrite = stats.n[StatIcacheWrite] - prev->n[StatIcacheWrite];
  38. /* # dirty entries in index cache */
  39. ndirty = stats.n[StatIcacheDirty] - prev->n[StatIcacheDirty];
  40. /* # entries flushed to disk */
  41. nflush = nwrite - ndirty;
  42. /* want to stay around 70% dirty */
  43. tdirty = (vlong)stats.n[StatIcacheSize]*700/1000;
  44. /* assume nflush*icachesleeptime is a constant */
  45. cflush = (vlong)nflush*(icachesleeptime+1);
  46. /* computer number entries to write in next minute */
  47. toflush = nwrite + (stats.n[StatIcacheDirty] - tdirty);
  48. /* schedule for that many */
  49. if(toflush <= 0 || cflush/toflush > 100000)
  50. icachesleeptime = SleepForever;
  51. else
  52. icachesleeptime = cflush/toflush;
  53. }
  54. arenasumsleeptime = SleepForever;
  55. return;
  56. }
  57. if(t-lasttime[1] < l1quantum){
  58. /* level-1 disk access (icache flush) going on */
  59. icachesleeptime = 0;
  60. arenasumsleeptime = SleepForever;
  61. return;
  62. }
  63. /* no disk access going on - no holds barred*/
  64. icachesleeptime = 0;
  65. arenasumsleeptime = 0;
  66. }
  67. void
  68. diskaccess(int level)
  69. {
  70. if(level < 0 || level >= nelem(lasttime)){
  71. fprint(2, "bad level in diskaccess; caller=%#p\n",
  72. getcallerpc(&level));
  73. return;
  74. }
  75. lasttime[level] = time(0);
  76. }