1

I have followed the following webpage:

http://www.1024cores.net/home/lock-free-algorithms/reader-writer-problem/improved-lock-free-seqlock

the source is like following:

struct data_t 
{ 
    int seq; // sequence number 
    int data [1024]; // user data 
}; 

struct seqlock_t 
{ 
    data_t* current; 
    data_t pool [16]; // 16 user objects are held 
}; 

seqlock_t sl; 

The structure is quite simple, what confuses me is the following:

data_t* d0 = sl.current; // load-consume
int idx = (sl.current - sl.pool + 1) % 16; 
data_t* d = &sl.pool[idx]; 

The sl.current is a pointer, sl.pool is? What current - pool can achieve? in c language view, how should I explain this statement?

int idx = (sl.current - sl.pool + 1) % 16;

Edit :

Thanks for all information , it help a lot !!! in my own coding style would use int idx = (sl.current - &[sl.pool[0]) + 1) % 16; now I know &(sl.pool[0]) is the same with sl.pool !!! I should figure it out , the following example , what I read before , showes pointer/array ....

void display(int *p)
{
    int idx ;
    printf("(%d)(%d)\n",*p,p[1]) ;
}
int main()
{
    int i,Arr[10] ;
    for(i=0;i<10;i++)
        Arr[i] = i + 100;
    display(Arr) ;
}

Yes , I can use display(Arr) and display(&Arr[0]) , they are the same ~!!

barfatchen
  • 1,630
  • 2
  • 24
  • 48
  • pool is an array of data_t. So, pool can be used for pointer operations. – Abhineet Oct 22 '13 at 09:08
  • 1
    It occurs to me that a strong article on pointer math is C must be *somewhere* on SO, but for the life of me I can't find one I'd recommend. If anyone reading this has a good candidate by all means toss a link to it; as I think the OP can use it right about now. **Edit**: ok. [this is a pretty damn good one](http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and-what-can-be-done-to-overcome?rq=1). – WhozCraig Oct 22 '13 at 09:19

3 Answers3

6

sl.current is a pointer. sl.pool is an array, and by writing like that it is equal to &sl.pool[0]. So it points to the first element of the array. We can do some pointer operations such as subtraction, in that case to obtain some index.

I find this link http://www.eskimo.com/~scs/cclass/notes/sx10b.html quite simple to understand some pointer arithmetic.

rcs
  • 6,713
  • 12
  • 53
  • 75
  • 7
    `sl.pool` is *not* a pointer. It is an array. They're *not* the same. A pointer is a variable that *holds* an address; an array is a variable that effectively *is* an address. Were `sl.pool` a pointer, `sl.pool++` would be valid; it isn't. – WhozCraig Oct 22 '13 at 09:14
  • I do not understand the first sentence. It reads as if `sl.pool` and `sl.pool[0]` were the same - which isn't true. – glglgl Oct 22 '13 at 09:25
  • 1
    @glglgl I concur. They're not the same. `&sl.pool[0]`, `sl.pool + 0` and `sl.pool` are all equivalent; `sl.pool[0]` is equivalent to exactly *none* of those. – WhozCraig Oct 22 '13 at 09:29
  • @Abhineet I know how pointer arithmetics works. But the statement in that sentence is just not true. – glglgl Oct 22 '13 at 09:29
  • @rcs Perfect. Thus, +1 from me. – glglgl Oct 22 '13 at 09:34
2
data_t* d0 = sl.current; // load-consume

gets the pointer into a local variable or even a register in order to access easier.

int idx = (sl.current - sl.pool + 1) % 16; 

It is assumed that sl.current points to one of the elements of the array sl.pool. So sl.current - sl.pool gets the respective distances in terms of data_t *, so it gets the current index. + 1 advances to the next index and with % 16 you achieve that a value of 16 - which would be illegal - points to 0 instead.

data_t* d = &sl.pool[idx];

This points to the new one; I suppose later comes a sl.current = d or something like that.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • The part of this concept that I'm quite-sure it a struggle for newbs to pointer math is the typed-pointer differencing. It is the contrapositive to scalar additions to pointers. You did pretty good in your "in terms of `data_t` clause, but even with that I think the OP may be scratching their head. Imnsho, there really is no easy way to describe it that leads to revelation quickly. Samples (lots of them) usually help. (+1, btw). – WhozCraig Oct 22 '13 at 09:36
1

From what I can deduce by the given information::

int idx = (sl.current - sl.pool + 1) % 16; 
data_t* d = &sl.pool[idx]; 

s1.pool is an array. So, negating s1.pool will give some value, say int x. Now ((x+1) % 16) will give a valid array bound index for s1.pool which is stored in idx. And thus, they found a valid array index for second line processing.

Abhineet
  • 5,320
  • 1
  • 25
  • 43