Hi,

> +/*
> + * The following two macros are aimed to simplify buffer state modification
> + * in CAS loop.  It's assumed that variable "uint32 state" is defined outside
> + * of this loop.  It should be used as following:
> + *
> + * BEGIN_BUFSTATE_CAS_LOOP(bufHdr);
> + * modifications of state variable;
> + * END_BUFSTATE_CAS_LOOP(bufHdr);
> + *
> + * For local buffers, these macros shouldn't be used..  Since there is
> + * no cuncurrency, local buffer state could be chaged directly by atomic
> + * read/write operations.
> + */
> +#define BEGIN_BUFSTATE_CAS_LOOP(bufHdr) \
> +     do { \
> +             SpinDelayStatus delayStatus = 
> init_spin_delay((Pointer)(bufHdr)); \

> +             uint32                  oldstate; \
> +             oldstate = pg_atomic_read_u32(&(bufHdr)->state); \
> +             for (;;) { \
> +                     while (oldstate & BM_LOCKED) \
> +                     { \
> +                             make_spin_delay(&delayStatus); \
> +                             oldstate = 
> pg_atomic_read_u32(&(bufHdr)->state); \
> +                     } \
> +                     state = oldstate
> +
> +#define END_BUFSTATE_CAS_LOOP(bufHdr) \
> +                     if (pg_atomic_compare_exchange_u32(&bufHdr->state, 
> &oldstate, state)) \
> +                             break; \
> +             } \
> +             finish_spin_delay(&delayStatus); \
> +     } while (0)

Hm. Not sure if that's not too much magic. Will think about it.

>   /*
> +  * Lock buffer header - set BM_LOCKED in buffer state.
> +  */
> + uint32
> + LockBufHdr(BufferDesc *desc)
> + {
> +     uint32                  state;
> + 
> +     BEGIN_BUFSTATE_CAS_LOOP(desc);
> +     state |= BM_LOCKED;
> +     END_BUFSTATE_CAS_LOOP(desc);
> + 
> +     return state;
> + }
> + 

Hm. It seems a bit over the top to do the full round here. How about

uint32 oldstate;
while (true)
{
    oldstate = pg_atomic_fetch_or(..., BM_LOCKED);
    if (!(oldstate & BM_LOCKED)
        break;
    perform_spin_delay();
}
return oldstate | BM_LOCKED;

Especially if we implement atomic xor on x86, that'd likely be a good
bit more efficient.


>  typedef struct BufferDesc
>  {
>       BufferTag       tag;                    /* ID of page contained in 
> buffer */
> -     BufFlags        flags;                  /* see bit definitions above */
> -     uint8           usage_count;    /* usage counter for clock sweep code */
> -     slock_t         buf_hdr_lock;   /* protects a subset of fields, see 
> above */
> -     unsigned        refcount;               /* # of backends holding pins 
> on buffer */
> -     int                     wait_backend_pid;               /* backend PID 
> of pin-count waiter */
>  
> +     /* state of the tag, containing flags, refcount and usagecount */
> +     pg_atomic_uint32 state;
> +
> +     int                     wait_backend_pid;               /* backend PID 
> of pin-count waiter */
>       int                     buf_id;                 /* buffer's index 
> number (from 0) */
>       int                     freeNext;               /* link in freelist 
> chain */

Hm. Won't matter on most platforms, but it seems like a good idea to
move to an 8 byte aligned boundary. Move buf_id up?

> +/*
> + * Support for spin delay which could be useful in other places where
> + * spinlock-like procedures take place.
> + */
> +typedef struct
> +{
> +     int                     spins;
> +     int                     delays;
> +     int                     cur_delay;
> +     Pointer         ptr;
> +     const char *file;
> +     int                     line;
> +} SpinDelayStatus;
> +
> +#define init_spin_delay(ptr) {0, 0, 0, (ptr), __FILE__, __LINE__}
> +
> +void make_spin_delay(SpinDelayStatus *status);
> +void finish_spin_delay(SpinDelayStatus *status);
> +
>  #endif        /* S_LOCK_H */

s/make_spin_delay/perform_spin_delay/? The former sounds like it's
allocating something or such.


Regards,

Andres


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to