From: | Robert Haas <robertmhaas(at)gmail(dot)com> |
---|---|
To: | Andres Freund <andres(at)2ndquadrant(dot)com> |
Cc: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Peter Geoghegan <pg(at)heroku(dot)com>, Pg Hackers <pgsql-hackers(at)postgresql(dot)org>, Ants Aasma <ants(at)cybertec(dot)at> |
Subject: | Re: better atomics - v0.2 |
Date: | 2013-11-19 17:43:44 |
Message-ID: | CA+Tgmob2cnmZG=NqKy38UEi-94LVvtku+yWmN2zOkxHokJUOCg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Tue, Nov 19, 2013 at 11:38 AM, Andres Freund <andres(at)2ndquadrant(dot)com> wrote:
> /*-------------------------------------------------------------------------
> *
> * atomics.h
> * Generic atomic operations support.
> *
> * Hardware and compiler dependent functions for manipulating memory
> * atomically and dealing with cache coherency. Used to implement locking
> * facilities and other concurrency safe constructs.
> *
> * There's three data types which can be manipulated atomically:
> *
> * * pg_atomic_flag - supports atomic test/clear operations, useful for
> * implementing spinlocks and similar constructs.
> *
> * * pg_atomic_uint32 - unsigned 32bit integer that can correctly manipulated
> * by several processes at the same time.
> *
> * * pg_atomic_uint64 - optional 64bit variant of pg_atomic_uint32. Support
> * can be tested by checking for PG_HAVE_64_BIT_ATOMICS.
> *
> * The values stored in theses cannot be accessed using the API provided in
> * thise file, i.e. it is not possible to write statements like `var +=
> * 10`. Instead, for this example, one would have to use
> * `pg_atomic_fetch_add_u32(&var, 10)`.
> *
> * This restriction has several reasons: Primarily it doesn't allow non-atomic
> * math to be performed on these values which wouldn't be concurrency
> * safe. Secondly it allows to implement these types ontop of facilities -
> * like C11's atomics - that don't provide direct access. Lastly it serves as
> * a useful hint what code should be looked at more carefully because of
> * concurrency concerns.
> *
> * To be useful they usually will need to be placed in memory shared between
> * processes or threads, most frequently by embedding them in structs. Be
> * careful to align atomic variables to their own size!
What does that mean exactly?
> * Before variables of one these types can be used they needs to be
> * initialized using the type's initialization function (pg_atomic_init_flag,
> * pg_atomic_init_u32 and pg_atomic_init_u64) or in case of global
> * pg_atomic_flag variables using the PG_ATOMIC_INIT_FLAG macro. These
> * initializations have to be performed before any (possibly concurrent)
> * access is possible, otherwise the results are undefined.
> *
> * For several mathematical operations two variants exist: One that returns
> * the old value before the operation was performed, and one that that returns
> * the new value. *_fetch_<op> variants will return the old value,
> * *_<op>_fetch the new one.
Ugh. Do we really need this much complexity?
> * Use higher level functionality (lwlocks, spinlocks, heavyweight locks)
> * whenever possible. Writing correct code using these facilities is hard.
> *
> * For an introduction to using memory barriers within the PostgreSQL backend,
> * see src/backend/storage/lmgr/README.barrier
The extent to which these primitives themselves provide ordering
guarantees should be documented.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
From | Date | Subject | |
---|---|---|---|
Next Message | Robert Haas | 2013-11-19 17:47:29 | Re: Replication Node Identifiers and crashsafe Apply Progress |
Previous Message | Robert Haas | 2013-11-19 17:29:40 | Re: additional json functionality |