9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* RE: [9fans] A quite amusing thing...
@ 2003-02-22 20:34 philw
  2003-02-22 20:40 ` Russ Cox
  0 siblings, 1 reply; 12+ messages in thread
From: philw @ 2003-02-22 20:34 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 17886 bytes --]

Leendert van Doorn was a summer student at the labs that year I think
 
phil

	-----Original Message----- 
	From: Russ Cox [mailto:rsc@plan9.bell-labs.com] 
	Sent: Sat 2/22/2003 12:30 PM 
	To: 9fans@cse.psu.edu 
	Cc: 
	Subject: Re: [9fans] A quite amusing thing...
	
	

	That _is_ fairly amusing.
	
	We've had a form of that code (including the big
	comment) in our source tree since July 15, 1994.
	But the 1994 code didn't have the for loop to run
	until loops got big enough (it assumed 10000 was
	enough) and it didn't have all the clock frequency
	stuff (which got added later).
	
	So either Plan 9 copied Amoeba back in 1994 (before
	the original project was terminated) and has been
	secretly tracking the code since then, or Amoeba copied
	Plan 9 some time later after the code was changed to
	look more like it does today.  I know where my money is.
	
	Also, I downloaded the original Amoeba code and the
	pit.c looked nothing like the Plan 9 code as of 1996. 
	
	Below you'll find Plan 9's clock.c from 1994, Amoeba's
	pit.c from 1996, and Amoeba's pit.c from today.
	Note the difference between the last two.  Sure looks like
	
	 * Stefan Bosse (12/1999-7/2000)
	 * sbosse@physik.uni-bremen.de
	 *
	 * -> pit_hw_milli now default routine with 1ms resolution
	 * -> cpuspeed measurement and delay loop reference
	
	copied the Plan 9 code.
	
	> Hmm... It is possible too that Amoeba developer's have copied this code
	> but I doubt it.
	
	Why?
	
	Russ
	
	/* --rw-rw-r-- M 3014 jmk sys 2766 Jul 15  1994 sys/src/brazil/pc/clock.c */
	
	void
	clockinit(void)
	{
	        ulong x, y;     /* change in counter */
	        ulong cycles, loops;
	
	        /*
	         *  set vector for clock interrupts
	         */
	        setvec(Clockvec, clock, 0);
	
	        /*
	         *  set clock for 1/HZ seconds
	         */
	        outb(Tmode, Load0|Square);
	        outb(T0cntr, (Freq/HZ));        /* low byte */
	        outb(T0cntr, (Freq/HZ)>>8);     /* high byte */
	
	        /*
	         *  measure time for the loop
	         *
	         *                      MOVL    loops,CX
	         *      aaml1:          AAM
	         *                      LOOP    aaml1
	         *
	         *  the time for the loop should be independent from external
	         *  cache's and memory system since it fits in the execution
	         *  prefetch buffer.
	         *
	         */
	        loops = 10000;
	        outb(Tmode, Latch0);
	        x = inb(T0cntr);
	        x |= inb(T0cntr)<<8;
	        aamloop(loops);
	        outb(Tmode, Latch0);
	        y = inb(T0cntr);
	        y |= inb(T0cntr)<<8;
	        x -= y;
	
	        /*
	         *  counter  goes at twice the frequency, once per transition,
	         *  i.e., twice per the square wave
	         */
	        x >>= 1;
	
	        /*
	         *  figure out clock frequency and a loop multiplier for delay().
	         */
	        switch(cputype = x86()){
	        case 386:
	                cycles = 30;
	                break;
	        case 486:
	                cycles = 24;
	                break;
	        default:
	                cycles = 23;
	                break;
	        }
	        cpufreq = (cycles*loops) * (Freq/x);
	        loopconst = (cpufreq/1000)/cycles;      /* AAM+LOOP's for 1 ms */
	}
	
	
	/*      @(#)pit.c       1.4     94/04/06 09:23:12 */
	/*
	 * Copyright 1994 Vrije Universiteit, The Netherlands.
	 * For full copyright and restrictions on use see the file COPYRIGHT in the
	 * top level of the Amoeba distribution.
	 */
	
	/*
	 * pit.c
	 *
	 * Driver for the 8254 timer (PIT). The i8254 timer has three timer channels
	 * of which only one (channel 0) is available for timer interrupts. The other
	 * channels are used for the speaker and memory refresh.
	 *
	 * Author:
	 *      Leendert van Doorn
	 */
	#include <amoeba.h>
	#include <assert.h>
	INIT_ASSERT
	#include <fault.h>
	#include <bool.h>
	#include "sys/proto.h"
	#include "i386_proto.h"
	#include "pit.h"
	
	#ifndef PIT_DEBUG
	#define PIT_DEBUG       0
	#endif
	
	static int pit_debug;                   /* current debug level */
	
	#ifdef notyet
	static uint32 pit_hw_milli();
	#endif
	static void pit_intr();
	
	/*
	 * Initialize channel 0 of the i8254A timer
	 */
	void
	pit_init()
	{
	    register uint32 counter = (PIT_FREQ * PIT_INTERVAL) / 1000L;
	
	#ifndef NDEBUG
	    if ((pit_debug = kernel_option("pit")) == 0)
	        pit_debug = PIT_DEBUG;
	    if (pit_debug > 1)
	        printf("pit_init(), pit_interval = 0x%x (%d), counter = %x\n",
	            PIT_INTERVAL, PIT_INTERVAL, counter);
	#endif
	
	    /* set timer to run continuously */
	    assert(counter <= 0xFFFF);
	    out_byte(PIT_MODE, PIT_MODE3);
	    out_byte(PIT_CH0, (int) (counter & 0xFF));
	    out_byte(PIT_CH0, (int) ((counter >> 8) & 0xFF));
	
	#ifdef notyet
	    /* I still have to thoroughly test this */
	    set_hw_milli(pit_hw_milli);
	#endif
	
	    setirq(PIT_IRQ, pit_intr);
	    pic_enable(PIT_IRQ);
	}
	
	/*
	 * Read i8254's channel 0 counter. The counter decrements at twice the
	 * timer frequency (one full cycle for each half of a square wave).
	 */
	uint16
	pit_channel0()
	{
	    register uint16 counter;
	
	    out_byte(PIT_MODE, PIT_LC);
	    counter = in_byte(PIT_CH0), counter |= (in_byte(PIT_CH0) << 8);
	    return counter;
	}
	
	/*
	 * Delay for at least ``msec'' milli seconds
	 */
	void
	pit_delay(msec)
	    int msec;
	{
	    register uint16 current, previous, diff;
	    register uint32 total;
	
	    /*
	     * The counter decrements at twice the timer frequency
	     * (one full cycle for each half of a square wave).
	     */
	    diff = 100; /* just in case */
	    total = (uint32) msec * (2 * PIT_FREQ / 1000);
	    previous = pit_channel0();
	    for (;;) {
	        current = pit_channel0();
	        if (current < previous)
	            diff = previous - current;
	        if (diff >= total)
	            break;
	        total -= diff;
	        previous = current;
	    }
	}
	
	#ifdef notyet
	/*
	 * Return number of actual milli-seconds that have passed
	 */
	static uint32
	pit_hw_milli()
	{
	    extern uint32 milli_uptime;
	    register uint32 milli;
	    register int flags;
	    uint16 counter;
	    int status;
	
	    flags = get_flags(); disable();
	    out_byte(PIT_MODE, PIT_RB);
	    out_byte(PIT_MODE, 0xC2);
	    status = in_byte(PIT_CH0);
	    counter = in_byte(PIT_CH0), counter |= (in_byte(PIT_CH0) << 8);
	    milli = milli_uptime + (PIT_INTERVAL / 2) *
	        (counter / (PIT_FREQ * PIT_INTERVAL) / 1000L);
	    if ((status & 0x80) == 0) milli += PIT_INTERVAL/2;
	    set_flags(flags);
	    return milli;
	}
	#endif
	
	/*
	 * The actual clock interrupt
	 */
	/* ARGSUSED */
	static void
	pit_intr(reason, frame)
	    int reason;
	    struct fault *frame;
	{
	    void sweeper_run();
	    void flp_motoroff();
	    extern int motortime;
	
	#ifdef MCA
	    /* ps/2 clock needs to be told to stop interrupting */
	    out_byte(0x61, in_byte(0x61) | 0x80);
	#endif
	
	    enqueue(sweeper_run, (long) PIT_INTERVAL);
	
	#if (defined(ISA) || defined(MCA)) && !defined(NOFLOPPY)
	    /* stop running floppy motor */
	    if (motortime != 0 && --motortime == 0)
	        flp_motoroff();
	#endif
	}
	
	
	/*
	 * This file is part of the FIREBALL AMOEBA System.
	 *
	 *
	 * Last modified:
	 *              18/02/01
	 *
	 * Stefan Bosse (12/1999-7/2000)
	 * sbosse@physik.uni-bremen.de
	 *
	 * -> pit_hw_milli now default routine with 1ms resolution
	 * -> cpuspeed measurement and delay loop reference
	 *
	 *
	 *
	 * FIREBALL AMOEBA is free software; you can redistribute it and/or
	 * modify it under the terms of the GNU General Public License as
	 * published by the Free Software Foundation; version 2.
	 *
	 * The FIREBALL AMOEBA is distributed in the hope that it will be usefull,
	 * but WITHOUT ANY WARRANTY; without even implied warranty of
	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
	 * General Public License for more details.
	 *
	 * Original Copyright: Vrije Universiteit, The Netherlands.
	 */
	
	
	
	
	/*
	 * pit.c
	 *
	 * Driver for the 8254 timer (PIT). The i8254 timer has three timer channels
	 * of which only one (channel 0) is available for timer interrupts. The other
	 * channels are used for the speaker and memory refresh.
	 *
	 * Author:
	 *      Leendert van Doorn
	 */
	
	
	#include <amoeba.h>
	#include <assert.h>
	INIT_ASSERT
	#include <fault.h>
	#include <bool.h>
	#include "sys/proto.h"
	#include "i386_proto.h"
	#include <irq.h>
	#include "pit.h"
	#include <cpu.h>
	
	#ifndef PIT_DEBUG
	#define PIT_DEBUG       0
	#endif
	
	#ifdef STATISTICS
	static unsigned long pit_hw_milli_count=0;
	static unsigned long pit_hw_milli_wrap1=0;
	static unsigned long pit_hw_milli_wrap2=0;
	static unsigned long pit_delay_count=0;
	#endif
	
	static int pit_debug;                   /* current debug level */
	static int initialized=0;
	
	#ifdef PIT_HW_MILLI
	static uint32 pit_hw_milli();
	#endif
	static void pit_intr();
	
	/*
	 * milli_uptime will be incremented in sweeper_run, but it's delayed
	 * because of enqueue() handling.
	 * milli_uptime should be handled ***here***.
	 * Hack: Local we use timer_ticks for pit_hw_milli(), incremented in low
	 * level ISR below...
	 */
	unsigned long timer_ticks=0;   
	
	/* for time monotony checking; we have a serious problem with
	 * this faulty timer hardware
	 */
	static unsigned long last_time=0;
	
	/*
	 * Initialize channel 0 of the i8254A timer
	 */
	void
	pit_init()
	{
	    register uint32 counter = (PIT_FREQ * PIT_INTERVAL) / 1000L;
	
	
	    if(!initialized)
	    {
	
	        initialized=1;
	#ifndef NDEBUG
	        if ((pit_debug = kernel_option("pit")) == 0)
	                pit_debug = PIT_DEBUG;
	        if (pit_debug > 1)
	                printf("pit_init(), pit_interval = 0x%x (%d), counter = %x\n",
	                       PIT_INTERVAL, PIT_INTERVAL, counter);
	#endif
	
	        /* set timer to run continuously */
	        assert(counter <= 0xFFFF);
	
	        if(check_region(PIT_CH0,4)<0)
	                panic("Some fool allocated timer ports");
	        request_region(PIT_CH0,4,"PIT");
	
	        out_byte(PIT_MODE, PIT_MODE2);
	
	        out_byte(PIT_CH0, (int) (counter & 0xFF));
	        out_byte(PIT_CH0, (int) ((counter >> 8) & 0xFF));
	
	#ifdef PIT_HW_MILLI
	        /* I still have to thoroughly test this */
	        /* SB: still timer wrap problems; but time monotonie is guranteed */
	        set_hw_milli(pit_hw_milli);
	#endif
	
	        if(request_irq(PIT_IRQ,
	                       pit_intr,
	                       SA_NORMAL,
	                       "PIT",
	                       (void *)NULL)!=0)
	                panic("Some fool allocated timer irq");
	
	        enable_irq(PIT_IRQ);
	        /*pic_enable(PIT_IRQ);*/
	    }
	}
	
	/*
	 * Read i8254's channel 0 counter. The counter decrements at twice the
	 * timer frequency (one full cycle for each half of a square wave).
	 */
	uint16
	pit_channel0()
	{
	    register uint16 counter;
	    unsigned long flags;
	
	    save_flags(flags);cli();
	    out_byte(PIT_MODE, PIT_LC);
	    counter = in_byte(PIT_CH0), counter |= (in_byte(PIT_CH0) << 8);
	    restore_flags(flags);
	    return counter;
	}
	
	/*
	 * Delay for at least ``msec'' milli seconds
	 */
	void
	pit_delay(msec)
	    int msec;
	{
	    register uint16 current, previous, diff;
	    register uint32 total;
	
	
	#ifdef STATISTICS
	    pit_delay_count++;
	#endif
	    /*
	     * The counter decrements at twice the timer frequency
	     * (one full cycle for each half of a square wave).
	     */
	    diff = 100; /* just in case */
	    total = (uint32) msec * (PIT_FREQ / 1000);
	    previous = pit_channel0();
	    for (;;) {
	        current = pit_channel0();
	        if (current < previous)
	            diff = previous - current;
	        if (diff >= total)
	            break;
	        total -= diff;
	        previous = current;
	    }
	}
	
	
	#ifdef PIT_HW_MILLI
	/*
	 * Return number of actual milli-seconds that have passed
	 */
	static uint32
	pit_hw_milli()
	{
	    extern uint32 milli_uptime;
	    register uint32 milli;
	    uint16 counter,counter2;
	    int status,status2;
	    unsigned long flags;
	    unsigned long ticks=timer_ticks;
	
	
	
	#ifdef STATISTICS
	    pit_hw_milli_count++;      
	#endif
	
	    save_flags(flags);cli();
	    /* Select timer0 and latch counter value. */
	    out_byte(PIT_MODE,PIT_LC);
	    counter = in_byte(PIT_CH0), counter |= (in_byte(PIT_CH0) << 8);
	    restore_flags(flags);
	
	    milli = timer_ticks*PIT_INTERVAL +
	        (1000*(((PIT_FREQ*PIT_INTERVAL)/1000) - counter )/(PIT_FREQ) );
	
	
	    /* check time monotony */
	    if(milli<last_time)
	    {
	#ifdef STATISTICS
	        pit_hw_milli_wrap1++;
	#endif 
	        if(ticks<timer_ticks)
	        {
	                milli=timer_ticks*PIT_INTERVAL;
	#ifdef STATISTICS
	                pit_hw_milli_wrap2++;
	#endif
	        }
	        else
	                milli=last_time;
	    }
	
	
	    last_time=milli;
	
	
	    if(ticks<timer_ticks) /* Between start and here pit_intr was called */
	        return (timer_ticks*PIT_INTERVAL);
	    else
	        return milli;
	}
	#endif
	
	/*
	 * The actual clock interrupt
	 */
	/* ARGSUSED */
	#ifdef __KERNEL__       /* Work with Linux-ISR  */
	static void
	pit_intr(reason,dev_idt,frame)
	    int reason;
	    void *dev_idt;
	    struct fault *frame;
	#else
	static void
	pit_intr(reason,frame)
	    int reason;
	    struct fault *frame;
	#endif
	{
	    void sweeper_run();
	    void flp_motoroff();
	    extern int motortime;
	
	
	    timer_ticks++;
	
	#ifdef MCA
	    /* ps/2 clock needs to be told to stop interrupting */
	    out_byte(0x61, in_byte(0x61) | 0x80);
	#endif
	
	    enqueue(sweeper_run, (long) PIT_INTERVAL);
	
	#if (defined(ISA) || defined(MCA)) && !defined(NOFLOPPY)
	    /* stop running floppy motor */
	    if (motortime != 0 && --motortime == 0)
	        flp_motoroff();
	#endif
	}
	
	#ifdef STATISTICS
	int
	pit_stat(begin,end)
	char    *begin;
	char    *end;
	{
	        char *p;
	        int     i;
	
	        p=bprintf(begin,end,"**** Hardware Timer statistics *****\n");
	        p=bprintf(p,end,"pit_hw_milli() calls: %d\n",
	                  pit_hw_milli_count);
	        p=bprintf(p,end,"pit_hw_milli time wrap check failed: %d\n",
	                  pit_hw_milli_wrap1);
	        p=bprintf(p,end,"pit_hw_milli dirty ticks increment: %d\n",
	                  pit_hw_milli_wrap2);
	
	        p=bprintf(p,end,"pit_delay() calls: %d\n",
	                  pit_delay_count);
	
	        return p-begin;
	}
	#endif
	
	/* For cpu speed measurement. We need timer access. */
	
	void
	cpuspeed(int aalcycles, int havecycleclock)
	{
	        int cpufreq, loops, incr, x, y;
	        unsigned long ax1,dx1,ax2,dx2,a,b;
	
	        pit_init();
	
	        /* find biggest loop that doesn't wrap */
	        incr = 16000000/(aalcycles*HZ*2);
	        x = 2000;
	        for(loops = incr; loops < 64*1024; loops += incr) {
	       
	                /*
	                 *  measure time for the loop
	                 *
	                 *                      MOVL    loops,CX
	                 *      aaml1:          AAM
	                 *                      LOOP    aaml1
	                 *
	                 *  the time for the loop should be independent of external
	                 *  cache and memory system since it fits in the execution
	                 *  prefetch buffer.
	                 *
	                 */
	
	                /* Beware of counter reset's (wraps)... */
	
	                /* Read the cpu internal clock if available */
	                if(havecycleclock)
	                        rdmsr(0x10, &ax1,&dx1);
	                x = (int)pit_channel0();
	
	                aamloop(loops);
	
	                if(havecycleclock)
	                        rdmsr(0x10, &ax2,&dx2);
	
	                y = (int)pit_channel0();
	
	                x -= y;
	
	                if(x < 0)
	                        x += PIT_FREQ/PIT_HZ;
	
	                if(x > PIT_FREQ/(3*PIT_HZ))
	                        break;
	        }
	
	        /*
	         *  figure out clock frequency and a loop multiplier for delay().
	         *  n.b. counter goes up by 2*PIT_FREQ
	         */
	        cpufreq = loops*((aalcycles*PIT_FREQ)/x);
	        cpu.loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1ms */
	
	        /* check aalcycle value */
	        if(kernel_option("cud") == 1)
	                printf("cpuspeed: aalcycle MHz=%d\n",
	                        (cpufreq + cpufreq/200)/1000000);
	
	        if(havecycleclock){
	
	
	                if(dx2 == dx1)
	                        b = (ax2-ax1);
	                else    /* counter wrap */
	                        b = (ax2+0xffffffff-ax1);
	
	                b /= x;
	                b *= PIT_FREQ;
	
	
	                /*
	                 *  round to the nearest megahz
	                 */
	                cpu.cpumhz = (b+500000)/1000000L;
	                cpu.cpuhz = b;
	        } else {
	                /*
	                 *  add in possible 0.5% error and convert to MHz
	                 */
	                cpu.cpumhz = (cpufreq + cpufreq/200)/1000000;
	                cpu.cpuhz = cpufreq;
	        }
	
	
	}
	
	


[-- Attachment #2.1: Type: text/plain, Size: 268 bytes --]

The following attachment had content that we can't
prove to be harmless.  To avoid possible automatic
execution, we changed the content headers.
The original header was:

	Content-Type: application/ms-tnef;
	name="winmail.dat"
	Content-Transfer-Encoding: base64

[-- Attachment #2.2: winmail.dat.suspect --]
[-- Type: application/octet-stream, Size: 34814 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread
* [9fans] A quite amusing thing...
@ 2003-02-22 19:17 Maksim Radziwill
  2003-02-22 20:30 ` Russ Cox
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Maksim Radziwill @ 2003-02-22 19:17 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 5773 bytes --]

Hi everyone,
I recently have found an amusing thing between (FSD-)Amoeba and Plan9 :
The code for cpu speed identification is the same ;)

Here I paste it. If you don't believe youre eyes check out
/sys/src/9/pc/i8253.c in the plan9 system
/profile/module/amoeba/src/machdep/dev/ibm_at/timer/pit.c in the
FSD-Amoeba system
(the sys source must be installed of course)

You can get FSD-Amoeba at fsd-amoeba.sourceforge.net it is the
continuation of
the original Amoeba project (www.cs.vu.nl/pub/amoeba) who has been
terminated
in 1996.

++++++ i8253.c the guesscpuhz function
void
guesscpuhz(int aalcycles)
{
      int cpufreq, loops, incr, x, y;
      uvlong a, b;

      /* find biggest loop that doesn't wrap */
      incr = 16000000/(aalcycles*HZ*2);
      x = 2000;
      for(loops = incr; loops < 64*1024; loops += incr) {

            /*
             *  measure time for the loop
             *
             *                MOVL  loops,CX
             *    aaml1:           AAM
             *                LOOP  aaml1
             *
             *  the time for the loop should be independent of external
             *  cache and memory system since it fits in the execution
             *  prefetch buffer.
             *
             */
            outb(Tmode, Latch0);
            if(m->havetsc)
                  rdtsc(&a);
            x = inb(T0cntr);
            x |= inb(T0cntr)<<8;
            aamloop(loops);
            outb(Tmode, Latch0);
            if(m->havetsc)
                  rdtsc(&b);
            y = inb(T0cntr);
            y |= inb(T0cntr)<<8;
            x -= y;

            if(x < 0)
                  x += Freq/HZ;

            if(x > Freq/(3*HZ))
                  break;
      }

      /*
       *  figure out clock frequency and a loop multiplier for delay().
       *  n.b. counter goes up by 2*Freq
       */
      cpufreq = loops*((aalcycles*2*Freq)/x);
      m->loopconst = (cpufreq/1000)/aalcycles;  /* AAM+LOOP's for 1 ms
*/

      if(m->havetsc){

            /* counter goes up by 2*Freq */
            b = (b-a)<<1;
            b *= Freq;
            b /= x;

            /*
             *  round to the nearest megahz
             */
            m->cpumhz = (b+500000)/1000000L;
            m->cpuhz = b;
      } else {
            /*
             *  add in possible 0.5% error and convert to MHz
             */
            m->cpumhz = (cpufreq + cpufreq/200)/1000000;
            m->cpuhz = cpufreq;
      }

      i8253.hz = Freq<<Tickshift;
}

+++++ Amoeba's pit.c cpuspeed function

/* For cpu speed measurement. We need timer access. */

void
cpuspeed(int aalcycles, int havecycleclock)
{
        int cpufreq, loops, incr, x, y;
        unsigned long ax1,dx1,ax2,dx2,a,b;

        pit_init();

        /* find biggest loop that doesn't wrap */
        incr = 16000000/(aalcycles*HZ*2);
        x = 2000;
        for(loops = incr; loops < 64*1024; loops += incr) {

                /*
                 *  measure time for the loop
                 *
                 *                        MOVL        loops,CX
                 *        aaml1:                 AAM
                 *                        LOOP        aaml1
                 *
                 *  the time for the loop should be independent of
external
                 *  cache and memory system since it fits in the
execution
                 *  prefetch buffer.
                 *
                 */

                /* Beware of counter reset's (wraps)... */

                /* Read the cpu internal clock if available */
                if(havecycleclock)
                        rdmsr(0x10, &ax1,&dx1);
                x = (int)pit_channel0();

                aamloop(loops);

                if(havecycleclock)
                        rdmsr(0x10, &ax2,&dx2);

                y = (int)pit_channel0();

                x -= y;

                if(x < 0)
                        x += PIT_FREQ/PIT_HZ;

                if(x > PIT_FREQ/(3*PIT_HZ))
                        break;
        }

        /*
         *  figure out clock frequency and a loop multiplier for
delay().
         *  n.b. counter goes up by 2*PIT_FREQ
         */
        cpufreq = loops*((aalcycles*PIT_FREQ)/x);
        cpu.loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1ms
*/

        /* check aalcycle value */
        if(kernel_option("cud") == 1)
                printf("cpuspeed: aalcycle MHz=%d\n",
                        (cpufreq + cpufreq/200)/1000000);

        if(havecycleclock){


                if(dx2 == dx1)
                        b = (ax2-ax1);
                else        /* counter wrap */
                        b = (ax2+0xffffffff-ax1);

                b /= x;
                b *= PIT_FREQ;


                /*
                 *  round to the nearest megahz
                 */
                cpu.cpumhz = (b+500000)/1000000L;
                cpu.cpuhz = b;
        } else {
                /*
                 *  add in possible 0.5% error and convert to MHz
                 */
                cpu.cpumhz = (cpufreq + cpufreq/200)/1000000;
                cpu.cpuhz = cpufreq;
        }

}


The thing is even more amusing since I heard someone saying plan9 is
written from the ground up... ;)

Hmm... It is possible too that Amoeba developer's have copied this code
but I doubt it.
Or maybe I'm missing something and the code comes from an other external
source...
(Don't forget these all are only hypotheses)

If someone could explain this it would be great, since I would like to
know the
only real true (story) ;)

Maks,


[-- Attachment #2: Type: text/html, Size: 69140 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2003-02-23 22:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-22 20:34 [9fans] A quite amusing thing philw
2003-02-22 20:40 ` Russ Cox
  -- strict thread matches above, loose matches on Subject: below --
2003-02-22 19:17 Maksim Radziwill
2003-02-22 20:30 ` Russ Cox
2003-02-22 20:51 ` David Presotto
2003-02-23  2:16 ` Skip Tavakkolian
2003-02-23  3:53 ` John Packer
2003-02-23  6:10   ` northern snowfall
2003-02-23  8:30     ` John Packer
2003-02-23 20:26       ` northern snowfall
2003-02-23 21:28         ` John Packer
2003-02-23 22:00           ` northern snowfall

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).