Linux-Development-Sys Digest #570, Volume #8     Fri, 16 Mar 01 01:13:11 EST

Contents:
  Re: Select blocking all threads... (Matt Woodyard)
  PORTIMG PRBLEMS FOR A DEVICE DRIVER (Josef Allen)
  ReiserFS vs NFSv3 still trouble? (Konstantinos Agouros)
  detecting cache misses on amd ("Denis")
  Re: detecting cache misses on amd (Robert Redelmeier)
  Re: Select blocking all threads... (Matt Woodyard)
  Re: Processor ID (Matt Woodyard)

----------------------------------------------------------------------------

From: Matt Woodyard <[EMAIL PROTECTED]>
Reply-To: [EMAIL PROTECTED]
Subject: Re: Select blocking all threads...
Date: Fri, 16 Mar 2001 03:05:25 GMT

what i have is one thread that executes a thread for each icmp echo request, to
different machines. I AM NOT REWRITING PING. I want to "ping" a list of machines
at the same time.


pseudo code looks like:
exec thread printing stuff
while(1)
            walkthrough list
                         exec thread  sendping

end while


sendping
            sendto (ip)
            select (wait 5 secs)
            decode response
            return



[EMAIL PROTECTED] wrote:

> On Fri, 16 Mar 2001 01:02:17 GMT Matt Woodyard <[EMAIL PROTECTED]> wrote:
>
> | I have a program that sends icmp requests in separate threads. Something is
> | blocking because the pings (as evidenced by tcpdump) are not being spit out
> | concurrently. For example lets say machine 1 is down, the next machine is
> | not tested for 5 secs (the select wait time amount). But if the machine is
> | up then the pings appear more concurrent. Whats the deal? If select is
> | acctually behaving as you say.
>
> Source code might help.
>
> If there is nothing coming in then of course select() should be blocked
> until the timeout.  Is the same thread sending the ping as receiving?
> If so, then of course it won't be awake to send another until one comes
> back or the timer pops.
>
> I'm not sure why you even need threads for this.  If you are doing
> nonblocked I/O you could:
>
> 1.  select for every fd you are waiting for a ping reply on
> 2.  set your timer to the difference in time to the next time
>     point you want to send pings on
>
> If each thread is in select with a timeout, how do you even know that
> they are all going to be waking at the same time?  As soon as any
> pings start to come back, if you wake up then, send another ping,
> and go back to sleep for the same 5 seconds, each thread is going
> to get into different time phases based on those roundtrip times.
>
> The way I do this is to get the current time from gettimeofday()
> and calculate when the next point in time is that I want to do
> something, calculate the difference until then, and use that for
> the select timeout (actually, I'm using poll now days, but the
> same concept applies).  I can get my pings to come out right at
> a specific interval with nothing more than a little clock jitter
> instead of accumulated time shifting.
>
> --
> -----------------------------------------------------------------
> | Phil Howard - KA9WGN |   Dallas   | http://linuxhomepage.com/ |
> | [EMAIL PROTECTED] | Texas, USA | http://phil.ipal.org/     |
> -----------------------------------------------------------------


------------------------------

From: Josef Allen <[EMAIL PROTECTED]>
Subject: PORTIMG PRBLEMS FOR A DEVICE DRIVER
Date: Thu, 15 Mar 2001 22:28:54 -0500

I am having problems porting a program from the Visual C++ world to the
linux world could someone please help
#include <conio.h>
#include <windows.h>
#include <time.h>

#include "Cti.h"

#define CTI_MCR 4  // UART bit/address definitions
#define CTI_LSR 5
#define CTI_LCR 3
#define CTI_DAV 0x01
#define CTI_ODR 0x20
#define CTI_COMPORT_TIMEOUT 100000L

WORD CtiSend(WORD Addr, WORD Data);
WORD CtiRcv(WORD Addr, WORD * Data);
void CtiSleep(clock_t MsecsToSleep);

WORD CtiComms (CtiData * Cti)
{ unsigned short ComportAddress;
  WORD Status = 0;
  WORD ControlIndex, SensorIndex, ThrottleIndex;
  WORD Byte;
  WORD ii, TxCnt, RxCnt, StatCnt;
  WORD NextDoublet;
  WORD Doublet[2*CTI_MAXMODULES];
  char TxBuffer[2+5*CTI_MAXMODULES];
  static WORD EvenOdd = 0;

  // Map logical COM port number to I/O address

  switch (Cti->ComPort)
  { case 1:  ComportAddress = 0x3F8; break;
    case 2:  ComportAddress = 0x2F8; break;
    case 3:  ComportAddress = 0x3E8; break;
    case 4:  ComportAddress = 0x2E8; break;
    default: ComportAddress = Cti->ComPort;
  }
  if (ComportAddress == 0)
    return(CTI_PORT_NOT_FOUND);

  //  Init COM port hardware (9600,N,8,1, no IRQ's)

  if (Cti->ServiceRequested & CTI_INIT)
  {
    _outp(ComportAddress+1, 0x00);  // set baud rate, stop bits, etc.
    _outp(ComportAddress+2, 0x00);
    _outp(ComportAddress+3, 0x83);
    _outp(ComportAddress+0, 0x0C);
    _outp(ComportAddress+1, 0x00);
    _outp(ComportAddress+3, 0x03);

    _outp(ComportAddress+CTI_MCR, 0x01);  // generate hardware reset pulse
    CtiSleep(100);              
    _outp(ComportAddress+CTI_MCR, 0x00);
    CtiSleep(500);

    _inp(ComportAddress);  // flush com port data_in register
    _inp(ComportAddress);

    // Poll the CTI network

    Status |= CtiSend(ComportAddress, 65);    // send message header ('A')
    Status |= CtiRcv(ComportAddress, &Byte);

    // Loop till header moves around the network

    for (ii = 0; (ii < CTI_MAXMODULES) && (Byte != 65) && !Status; ii++)
    { Status |= CtiSend(ComportAddress, 0x00);
      Status |= CtiRcv(ComportAddress, &Byte);
    }

    if (ii == CTI_MAXMODULES)  // message header was never returned
      return(CTI_IO_TIMEOUT);

    Status |= CtiSend(ComportAddress, 0x00); // read module count
    Status |= CtiRcv(ComportAddress, &Byte);
        
    if (Status)
      Cti->NumModules = 0;
    else
    { Cti->NumModules = ii;

      for (ii = 0; ii < Cti->NumModules; ii++)  // read in module IDs
      { Status |= CtiSend(ComportAddress, 0x00);
        Status |= CtiRcv(ComportAddress, &Byte);

        if (Byte == 0x88)
          Cti->ModuleType[ii] = CTI_8C;
        else if (Byte == 0xAA)
          Cti->ModuleType[ii] = CTI_8S;
        else if (Byte == 0x56)
          Cti->ModuleType[ii] = CTI_THROTTLE;
        else
          Cti->ModuleType[ii] = CTI_4C4S;
       }
     }

     _outp(ComportAddress+CTI_MCR, 0x01);    // reset network after poll
     CtiSleep(100);
     _outp(ComportAddress+CTI_MCR, 0x00);
     CtiSleep(500);

     _inp(ComportAddress);  // flush com port data_in register
     _inp(ComportAddress);

  }

  if (Cti->ServiceRequested == CTI_DATA_EXCHANGE)
  { ControlIndex  = 0;
    SensorIndex   = 0;
    ThrottleIndex = 0;
    TxCnt         = 0;
    NextDoublet   =  0;
    Doublet[0]    = (WORD) -1;

    Byte = _inp(ComportAddress);  // flush input port
    Byte = _inp(ComportAddress);

    Status = CtiSend(ComportAddress, 65);  // send header

    if (Cti->NumModules == 0)
    { Status |= CtiRcv(ComportAddress, &Byte);
      if (Byte != 65)
        return(CTI_UNEXPECTED_DATA);
    }

    // Save time by building tx buffer while header is being sent

    for (ii = 0; ii < Cti->NumModules; ii++)
    {
      if (Cti->ModuleType[ii] == CTI_4C4S)
      { Byte  = (Cti->Control[ControlIndex++] != 0) * 1;
        Byte += (Cti->Control[ControlIndex++] != 0) * 2;
        Byte += (Cti->Control[ControlIndex++] != 0) * 4;
        Byte += (Cti->Control[ControlIndex++] != 0) * 8;
        TxBuffer[TxCnt++] = (char) Byte;
      }

      else if (Cti->ModuleType[ii] == CTI_8C)
      { Byte  = (Cti->Control[ControlIndex++] != 0) *   1;
        Byte += (Cti->Control[ControlIndex++] != 0) *   2;
        Byte += (Cti->Control[ControlIndex++] != 0) *   4;
        Byte += (Cti->Control[ControlIndex++] != 0) *   8;
        Byte += (Cti->Control[ControlIndex++] != 0) *  16;
        Byte += (Cti->Control[ControlIndex++] != 0) *  32;
        Byte += (Cti->Control[ControlIndex++] != 0) *  64;
        Byte += (Cti->Control[ControlIndex++] != 0) * 128;

        if ( (Byte == 65) || (Byte == 0x1B) )
        { TxBuffer[TxCnt++] = 0x1B;
          Doublet[NextDoublet++] = TxCnt+ii;
          Doublet[NextDoublet] = (WORD) -1;
          TxBuffer[TxCnt++] = ~Byte;
        }
        else
          TxBuffer[TxCnt++] = (char)Byte;
      }

      else if (Cti->ModuleType[ii] == CTI_8S)
        TxBuffer[TxCnt++] = 0x01;

      else if (Cti->ModuleType[ii] == CTI_THROTTLE)
      { if (EvenOdd)
        { Byte = (Cti->Throttle[ThrottleIndex++] & 0x7F);
          if (Byte > 100)
            Byte = 100;
          Byte = Byte | 0x80;
        }
        else
          Byte = (Cti->Throttle[ThrottleIndex++] >> 8) & 0x7F;

        TxBuffer[TxCnt++] = (char) Byte;
      }
    }

    for (ii = 0; ii < Cti->NumModules; ii++)
      TxBuffer[TxCnt++] = (char) 0xFF;

    Status |= CtiRcv(ComportAddress, &Byte); // receive response to header

    Status |= CtiSend(ComportAddress, 0x00); // send module counter
    Status |= CtiRcv(ComportAddress, &Byte); // receive response to module counter

    NextDoublet = 0;
    RxCnt = 0;
    StatCnt = 0;

    for (ii = 0; ii < TxCnt; ii++)
    {
      Status |= CtiSend(ComportAddress, TxBuffer[ii]);

      if (ii == Doublet[NextDoublet])
      { NextDoublet++;
        CtiSleep(1);
      }
      else
      { Status |= CtiRcv(ComportAddress, &Byte);
        RxCnt++;
        if (RxCnt > Cti->NumModules)  // Status has begun coming back
        {
          if (Cti->ModuleType[StatCnt] == CTI_4C4S)
          { Byte >>= 4;
            Cti->Sensor[SensorIndex++] = ((Byte & 0x01) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x02) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x04) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x08) != 0);
          }
          else if (Cti->ModuleType[StatCnt] == CTI_8S)
          { Cti->Sensor[SensorIndex++] = ((Byte & 0x01) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x02) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x04) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x08) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x10) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x20) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x40) != 0);
            Cti->Sensor[SensorIndex++] = ((Byte & 0x80) != 0);
          }
          StatCnt++;
        }
      }
    }
  }

  EvenOdd = EvenOdd ? 0 : 1;

  return(Status);
}

WORD CtiSend(WORD Addr, WORD Data)

{ clock_t TimeToGiveUp;

  TimeToGiveUp = clock() + CLOCKS_PER_SEC/10;   // give up after 100 msecs
  while (!(_inp(Addr+CTI_LSR) & CTI_ODR))
  if (clock() > TimeToGiveUp)
    return(CTI_IO_TIMEOUT);
        
  _outp(Addr, Data);
  return(CTI_SUCCESS);
}

WORD CtiRcv(WORD Addr, WORD *Data)

{ clock_t TimeToGiveUp;

  TimeToGiveUp = clock() + CLOCKS_PER_SEC/10;   // give up after 100 msecs
  while (! (_inp(Addr + CTI_LSR) & CTI_DAV))
    if (clock() > TimeToGiveUp)
    { *Data = 0x00;
      return(CTI_IO_TIMEOUT);
    }
  *Data = _inp(Addr);
  return(CTI_SUCCESS);
}

void CtiSleep(clock_t MsecsToSleep)
{ clock_t Goal;

  Goal = clock() + (MsecsToSleep * CLOCKS_PER_SEC)/1000;
  while (Goal > clock())
    ;
}

Josef D. Allen


------------------------------

From: [EMAIL PROTECTED] (Konstantinos Agouros)
Subject: ReiserFS vs NFSv3 still trouble?
Date: 15 Mar 2001 21:30:42 +0100

Hello,

I just read in German Linux-Magazine, that there shall be problems in the
combination ReiserFS/NFSv3, is this still true?

Konstantin
-- 
Dipl-Inf. Konstantin Agouros aka Elwood Blues. Internet: [EMAIL PROTECTED]
Otkerstr. 28, 81547 Muenchen, Germany. Tel +49 89 69370185
============================================================================
"Captain, this ship will not sustain the forming of the cosmos." B'Elana Torres

------------------------------

From: "Denis" <[EMAIL PROTECTED]>
Crossposted-To: 
comp.os.linux.hardware,alt.comp.hardware,alt.comp.hardware.amd.thunderbird,comp.programming
Subject: detecting cache misses on amd
Date: Thu, 15 Mar 2001 19:53:25 -0800

hello,

i apologize if i crossposted to a ng. where this would be off-topic...

can anyone tell me if it is possible, and if it is then, how would one
detect
the number of cache misses between two points in execution of a
program on an amd-k6 processor.... maybe some assembly language
hack? any register i could monitor?

numbers do not have to be very precise, but fairly close.

i looked in amd processor manual, but could not find anything.
i mean, is it even feasible to do such a thing? you'd have to keep a
register just for this.....

thanks.

denis



------------------------------

Date: Thu, 15 Mar 2001 22:27:01 -0600
From: Robert Redelmeier <[EMAIL PROTECTED]>
Crossposted-To: comp.os.linux.hardware
Subject: Re: detecting cache misses on amd

[Newsgroups trimmed -- my newserver doesn't carry'em]
Denis wrote:
> 
> can anyone tell me if it is possible, and if it is then, 
> how would one detect the number of cache misses between 
> two points in execution of a program on an amd-k6 processor.... 
> maybe some assembly language hack? any register i could monitor?

Unfortunately, I don't believe the K6-2 contains the MSRs
or PMCs you need.  My datasheet had no mention of them
with the other MSRs.  Perhaps the K6-2ctx or K6-3 does
have them, though.

OTOH, the AMD K7 (Athlon, T'bird, Duron) _does_ have 
what you need.  You need to program one or more of
the PerfEvtSel MSRs using `wrmsr` in a module because
it requires Ring0 priviliges.  Unless there's some
other MSR interface, like thru /proc . Fortunately once
programmed, you can read it in your userland program
with `rdpmc` as much as you want.

Intel processors have similar facilities.

-- Robert   author `cpuburn`  http://users.ev1.net/~redelm

------------------------------

Subject: Re: Select blocking all threads...
From: Matt Woodyard <[EMAIL PROTECTED]>
Date: Fri, 16 Mar 2001 05:12:34 GMT

As request some source code. Play with the code by placing machines in
different orders. You'll find that if you place a pingable machine in ip1
and down machine in ip2 and a up one in ip3, you'll see the "blocking"
effect im talking about. try all three machines being up, all three down.
when all three are down execution will take 20 seconds, assuming that you
tell it to hit 3 up hosts the maximum ping time will be 10 seconds (should
be for both scenarios). Although if its not really running in parallel then
the problem is not my code.

I compile this on linux 2.2.16 (RH 7.0) with:

g++ testthreadping.cpp -lpthread

start code-->

#include <stdio.h>
#include <pthread.h>
#include <fstream>
#include <string>
#include "cfgfile.h"
#include <pthread.h>
#include <string>
#include <iostream>
#include <netinet/in.h>


pthread_mutex_t lockping = PTHREAD_MUTEX_INITIALIZER;

void sendPing(unsigned long myAddr,int *state)
{
int numbytes,ret;
struct sockaddr_in dest_addr;   /* will hold the destination addr */
struct icmphdr *out,*icmpheader; /*ICMP Header Information*/
char buff[256]; 
struct timeval Timeout;
fd_set readfs;
unsigned int addrlen;
char *buffer = new char[100];
int sockfd,r;

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); /* do some error checking!
*/
fcntl(sockfd,F_SETFL,O_NONBLOCK);
/*Set up select stuff */
FD_ZERO(&readfs);
FD_SET(sockfd,&readfs);
/*Time out after 5 seconds*/
Timeout.tv_sec = 5;
Timeout.tv_usec = 0;

/*Set Destination Information*/
dest_addr.sin_family = AF_INET;        /* host byte order */
dest_addr.sin_addr.s_addr = myAddr;
bzero(&(dest_addr.sin_zero), 8);       /* zero the rest of the struct */

/************
Load ICMP Header
************/
out = (struct icmphdr *)buff;
bzero((char *)out,sizeof(struct icmphdr));
out->type = ICMP_ECHO;
out->un.echo.sequence = getpid();
out->un.echo.id =  getpid();
out->checksum = in_cksum((unsigned short *)out,sizeof(struct icmphdr));

/*Send Packet*/  

if ((numbytes=sendto(sockfd,out, sizeof(struct icmphdr), 0, (struct sockaddr
*)&dest_addr, sizeof(struct sockaddr))) == -1) {
            perror("Send Packet");
            *state = -1;
        }  



/*Wait for less than 5 seconds*/
ret = select(sockfd+1,&readfs,NULL,NULL,&Timeout);
if (ret)
    {
    ret = recvfrom(sockfd, buffer,100,0,(struct sockaddr
*)&dest_addr,&addrlen);
    if(ret == -1)
        {
        perror("Ping Recieve");
        close(sockfd);
        *state = -1;
//        return -1;
        }
    else
        {
        icmpheader = (struct icmphdr *)(buffer +sizeof(iphdr));
        close(sockfd);
        *state = icmpheader->type;
        //return icmpheader->type;
        }

        
    }
else
    {
    *state = 3;
    //return 3;
    close(sockfd);
    }

//return -1;    
}

/*
 * I stole this from tracroute which stol it from ping
 * in_cksum --
 *      Checksum routine for Internet Protocol family headers (C Version)
 */
unsigned short in_cksum(unsigned short *addr,int len)
{
        register int sum = 0;
        u_short answer = 0;
        register u_short *w = addr;
        register int nleft = len;

        /*
         * Our algorithm is simple, using a 32 bit accumulator (sum), we add
         * sequential 16 bit words to it, and at the end, fold back all the
         * carry bits from the top 16 bits into the lower 16 bits.
         */
        while (nleft > 1)  {
                sum += *w++;
                nleft -= 2;
        }

        /* mop up an odd byte, if necessary */
        if (nleft == 1) {
                *(u_char *)(&answer) = *(u_char *)w ;
                sum += answer;
        }

        /* add back carry outs from top 16 bits to low 16 bits */
        sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
        sum += (sum >> 16);                     /* add carry */
        answer = ~sum;                          /* truncate to 16 bits */
        return(answer);
}

void *ThreadPing(void *idr)
{
int pingret;
unsigned long *d = (unsigned long *)idr;
printf("%ld\n",*d);
sendPing(*d,&pingret);
printf("%d %d\n",pthread_self(),pingret);
return NULL;
}


int main(void)
{
char ip1[15] = "207.246.71.2";
char ip2[15] = "207.246.71.25";
char ip3[15] = "207.246.71.44";

unsigned long NetAddr1,NetAddr2,NetAddr3;

pthread_t p_thread;

int thrid;


NetAddr1 = inet_addr(ip1);
NetAddr2 = inet_addr(ip2);
NetAddr3 = inet_addr(ip3);

printf ("%ld, %ld\n",NetAddr1,NetAddr2);

thrid =  pthread_create(&p_thread,NULL,ThreadPing,(void *)&NetAddr1);
thrid =  pthread_create(&p_thread,NULL,ThreadPing,(void *)&NetAddr2);
thrid =  pthread_create(&p_thread,NULL,ThreadPing,(void *)&NetAddr3);

printf ("%ld, %ld\n",NetAddr1,NetAddr2);
sleep(5);
}

<--end



------------------------------

Subject: Re: Processor ID
From: Matt Woodyard <[EMAIL PROTECTED]>
Crossposted-To: comp.os.linux.development.apps,comp.os.linux.hardware
Date: Fri, 16 Mar 2001 05:43:19 GMT

You can't track the MAC addr anywhere but the local lan segment .

As for being afraid of the software... (insert anti intel spew)

Most hardware vendors don�t supply developers with API's that allow people
to track transactions by hardware part numbers over the internet. That�s
about the last thing we need, next you'll have processor specific liscenses
and "dongling". 


On 3/15/01 1:54 PM, in article [EMAIL PROTECTED], "Kasper
Dupont" <[EMAIL PROTECTED]> wrote:

> [EMAIL PROTECTED] wrote:
>> 
>> In article <[EMAIL PROTECTED]>,
>> Kasper Dupont  <[EMAIL PROTECTED]> wrote:
>> 
>>> MAC addresses of ethernet cards on the other
>>> hand are sent over the network every time you
>>> send a packet.
>> 
>> No, MAC addresses are sent only over your local
>> network *segment*.
> 
> Correct, but that is much longer than the CPUid
> which is not sent anywhere.
> 
>> 
>>> Can anybody explain WHY people are so unhappy
>>> about the CPUid?
>> 
>> One example: web browsers could start sending the id
>> as part of the http protocol which would increase
>> the ability of web sites to track users.
> 
> The http protocol does not specify that the
> client sends a CPUid.
> 
> Oh sure the browser could send a CPUid to a
> server. But remember that the browser could also
> send your MAC address to the server, together
> with a copy of the 5 last emails you wrote, the
> 10 most frequently used names form your address
> book, a listing of the last 20 transactions from
> your homebanking system, your private RSA key,
> and whatever other information you have stored
> on your computer.
> 
> I have never heard about a browser doing any of
> this, and I doubt anybody would be using it if
> it existed.
> 
> So if you want to be paranoid look on the
> software instead of some serial number on your
> CPU, there are much worse thing software could
> do.
> 
>> 
>> --
>> http://www.spinics.net/linux/


------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: [EMAIL PROTECTED]

You can send mail to the entire list by posting to the
comp.os.linux.development.system newsgroup.

Linux may be obtained via one of these FTP sites:
    ftp.funet.fi                                pub/Linux
    tsx-11.mit.edu                              pub/linux
    sunsite.unc.edu                             pub/Linux

End of Linux-Development-System Digest
******************************

Reply via email to