Header And Logo

PostgreSQL
| The world's most advanced open source database.

spin.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * spin.c
00004  *     Hardware-independent implementation of spinlocks.
00005  *
00006  *
00007  * For machines that have test-and-set (TAS) instructions, s_lock.h/.c
00008  * define the spinlock implementation.  This file contains only a stub
00009  * implementation for spinlocks using PGSemaphores.  Unless semaphores
00010  * are implemented in a way that doesn't involve a kernel call, this
00011  * is too slow to be very useful :-(
00012  *
00013  *
00014  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00015  * Portions Copyright (c) 1994, Regents of the University of California
00016  *
00017  *
00018  * IDENTIFICATION
00019  *    src/backend/storage/lmgr/spin.c
00020  *
00021  *-------------------------------------------------------------------------
00022  */
00023 #include "postgres.h"
00024 
00025 #include "miscadmin.h"
00026 #include "replication/walsender.h"
00027 #include "storage/lwlock.h"
00028 #include "storage/spin.h"
00029 
00030 
00031 #ifdef HAVE_SPINLOCKS
00032 
00033 /*
00034  * Report number of semaphores needed to support spinlocks.
00035  */
00036 int
00037 SpinlockSemas(void)
00038 {
00039     return 0;
00040 }
00041 #else                           /* !HAVE_SPINLOCKS */
00042 
00043 /*
00044  * No TAS, so spinlocks are implemented as PGSemaphores.
00045  */
00046 
00047 
00048 /*
00049  * Report number of semaphores needed to support spinlocks.
00050  */
00051 int
00052 SpinlockSemas(void)
00053 {
00054     int     nsemas;
00055 
00056     /*
00057      * It would be cleaner to distribute this logic into the affected modules,
00058      * similar to the way shmem space estimation is handled.
00059      *
00060      * For now, though, there are few enough users of spinlocks that we just
00061      * keep the knowledge here.
00062      */
00063     nsemas = NumLWLocks();      /* one for each lwlock */
00064     nsemas += NBuffers;         /* one for each buffer header */
00065     nsemas += max_wal_senders;  /* one for each wal sender process */
00066     nsemas += 30;               /* plus a bunch for other small-scale use */
00067 
00068     return nsemas;
00069 }
00070 
00071 /*
00072  * s_lock.h hardware-spinlock emulation
00073  */
00074 
00075 void
00076 s_init_lock_sema(volatile slock_t *lock)
00077 {
00078     PGSemaphoreCreate((PGSemaphore) lock);
00079 }
00080 
00081 void
00082 s_unlock_sema(volatile slock_t *lock)
00083 {
00084     PGSemaphoreUnlock((PGSemaphore) lock);
00085 }
00086 
00087 bool
00088 s_lock_free_sema(volatile slock_t *lock)
00089 {
00090     /* We don't currently use S_LOCK_FREE anyway */
00091     elog(ERROR, "spin.c does not support S_LOCK_FREE()");
00092     return false;
00093 }
00094 
00095 int
00096 tas_sema(volatile slock_t *lock)
00097 {
00098     /* Note that TAS macros return 0 if *success* */
00099     return !PGSemaphoreTryLock((PGSemaphore) lock);
00100 }
00101 
00102 #endif   /* !HAVE_SPINLOCKS */