gpsd-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gpsd-users] gpsd and shared memory


From: Roger Oberholtzer
Subject: Re: [gpsd-users] gpsd and shared memory
Date: Fri, 2 Oct 2015 06:54:20 +0000

I see that the interface to shared memory is not that I do the access myself. 
gps_read does this. So I was curious how it did this. I have what is perhaps a 
silly question about  gps_shm_read (listed below). I see that the first 
memcpy() copies data into local storage. What I am curious about is:

 - Is gps_read differentiating between there not being new information in the 
shared memory segment since the last read or that the memory changed while 
reading it?

 - If before != after (the data changed while being read?), then the read 
returns that there is no data? So gps_read() would report 0 bytes read, I 
guess. The caller is expected to call again if data is wanted. So old data 
would be returned each time, and only if the data changed while accessing the 
data would gps_read say there is no data?

 - And if the data did not change, there is a second copy of the data? 



int gps_shm_read(struct gps_data_t *gpsdata)
/* read an update from the shared-memory segment */
{
    /*@ -compdestroy */
    if (gpsdata->privdata == NULL)
        return -1;
    else
    {
        int before, after;
        void *private_save = gpsdata->privdata;
        volatile struct shmexport_t *shared = (struct shmexport_t 
*)gpsdata->privdata;
        struct gps_data_t noclobber;

        /*
         * Following block of instructions must not be reordered, otherwise 
         * havoc will ensue.  The barrier() call should prevent reordering
         * of the data accesses.
         *
         * This is a simple optimistic-concurrency technique.  We wrote
         * the second bookend first, then the data, then the first bookend.
         * Reader copies what it sees in normal order; that way, if we
         * start to write the segment during the read, the second bookend will
         * get clobbered first and the data can be detected as bad.
         */
        before = shared->bookend1;
        barrier();
        (void)memcpy((void *)&noclobber, 
                     (void *)&shared->gpsdata, 
                     sizeof(struct gps_data_t));
        barrier();
        after = shared->bookend2;

        if (before != after) 
            return 0;
        else {
            (void)memcpy((void *)gpsdata, 
                         (void *)&noclobber, 
                         sizeof(struct gps_data_t));
            /address@hidden@*/gpsdata->privdata = private_save;
            if ((gpsdata->set & REPORT_IS)!=0) {
                if (gpsdata->fix.mode >= 2)
                    gpsdata->status = STATUS_FIX;
                else
                    gpsdata->status = STATUS_NO_FIX;
                gpsdata->set = STATUS_SET;
            }
            return (int)sizeof(struct gps_data_t);
        }
    }
    /*@ +compdestroy */
}

Roger Oberholtzer

RST Systems

Office: +46 (0)10-615 6020
Mobile: +46 (0)70-815 1696
address@hidden
________________________________________

Ramböll Sverige AB
Krukmakargatan 21
P.O. Box 17009
SE-104 62 Stockholm, Sweden
www.rambollrst.se




reply via email to

[Prev in Thread] Current Thread [Next in Thread]