#include <asm/delay.h> #include <asm/special_insns.h> /* for mfctl() */ #include <asm/processor.h> /* for boot_cpu_data */
/* CR16 based delay: */ staticvoid __cr16_delay(unsignedlong __loops)
{ /* * Note: Due to unsigned math, cr16 rollovers shouldn't be * a problem here. However, on 32 bit, we need to make sure * we don't pass in too big a value. The current default * value of MAX_UDELAY_MS should help prevent this.
*/
u32 bclock, now, loops = __loops; int cpu;
preempt_disable();
cpu = smp_processor_id();
bclock = mfctl(16); for (;;) {
now = mfctl(16); if ((now - bclock) >= loops) break;
/* Allow RT tasks to run */
preempt_enable(); asmvolatile(" nop\n");
barrier();
preempt_disable();
/* * It is possible that we moved to another CPU, and * since CR16's are per-cpu we need to calculate * that. The delay must guarantee that we wait "at * least" the amount of time. Being moved to another * CPU could make the wait longer but we just need to * make sure we waited long enough. Rebalance the * counter for this CPU.
*/ if (unlikely(cpu != smp_processor_id())) {
loops -= (now - bclock);
cpu = smp_processor_id();
bclock = mfctl(16);
}
}
preempt_enable();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.