proportions.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * FLoating proportions
  3. *
  4. * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
  5. *
  6. * This file contains the public data structure and API definitions.
  7. */
  8. #ifndef _LINUX_PROPORTIONS_H
  9. #define _LINUX_PROPORTIONS_H
  10. #include <linux/percpu_counter.h>
  11. #include <linux/spinlock.h>
  12. #include <linux/mutex.h>
  13. #include <linux/gfp.h>
  14. struct prop_global {
  15. /*
  16. * The period over which we differentiate
  17. *
  18. * period = 2^shift
  19. */
  20. int shift;
  21. /*
  22. * The total event counter aka 'time'.
  23. *
  24. * Treated as an unsigned long; the lower 'shift - 1' bits are the
  25. * counter bits, the remaining upper bits the period counter.
  26. */
  27. struct percpu_counter events;
  28. };
  29. /*
  30. * global proportion descriptor
  31. *
  32. * this is needed to consistently flip prop_global structures.
  33. */
  34. struct prop_descriptor {
  35. int index;
  36. struct prop_global pg[2];
  37. struct mutex mutex; /* serialize the prop_global switch */
  38. };
  39. int prop_descriptor_init(struct prop_descriptor *pd, int shift, gfp_t gfp);
  40. void prop_change_shift(struct prop_descriptor *pd, int new_shift);
  41. /*
  42. * ----- PERCPU ------
  43. */
  44. struct prop_local_percpu {
  45. /*
  46. * the local events counter
  47. */
  48. struct percpu_counter events;
  49. /*
  50. * snapshot of the last seen global state
  51. */
  52. int shift;
  53. unsigned long period;
  54. raw_spinlock_t lock; /* protect the snapshot state */
  55. };
  56. int prop_local_init_percpu(struct prop_local_percpu *pl, gfp_t gfp);
  57. void prop_local_destroy_percpu(struct prop_local_percpu *pl);
  58. void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl);
  59. void prop_fraction_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl,
  60. long *numerator, long *denominator);
  61. static inline
  62. void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
  63. {
  64. unsigned long flags;
  65. local_irq_save(flags);
  66. __prop_inc_percpu(pd, pl);
  67. local_irq_restore(flags);
  68. }
  69. /*
  70. * Limit the time part in order to ensure there are some bits left for the
  71. * cycle counter and fraction multiply.
  72. */
  73. #if BITS_PER_LONG == 32
  74. #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4)
  75. #else
  76. #define PROP_MAX_SHIFT (BITS_PER_LONG/2)
  77. #endif
  78. #define PROP_FRAC_SHIFT (BITS_PER_LONG - PROP_MAX_SHIFT - 1)
  79. #define PROP_FRAC_BASE (1UL << PROP_FRAC_SHIFT)
  80. void __prop_inc_percpu_max(struct prop_descriptor *pd,
  81. struct prop_local_percpu *pl, long frac);
  82. /*
  83. * ----- SINGLE ------
  84. */
  85. struct prop_local_single {
  86. /*
  87. * the local events counter
  88. */
  89. unsigned long events;
  90. /*
  91. * snapshot of the last seen global state
  92. * and a lock protecting this state
  93. */
  94. unsigned long period;
  95. int shift;
  96. raw_spinlock_t lock; /* protect the snapshot state */
  97. };
  98. #define INIT_PROP_LOCAL_SINGLE(name) \
  99. { .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \
  100. }
  101. int prop_local_init_single(struct prop_local_single *pl);
  102. void prop_local_destroy_single(struct prop_local_single *pl);
  103. void __prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl);
  104. void prop_fraction_single(struct prop_descriptor *pd, struct prop_local_single *pl,
  105. long *numerator, long *denominator);
  106. static inline
  107. void prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl)
  108. {
  109. unsigned long flags;
  110. local_irq_save(flags);
  111. __prop_inc_single(pd, pl);
  112. local_irq_restore(flags);
  113. }
  114. #endif /* _LINUX_PROPORTIONS_H */