Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Ruslan Ermilov
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 
0011 
0012 #if (NGX_HAVE_ATOMIC_OPS)
0013 
0014 
0015 #define NGX_RWLOCK_SPIN   2048
0016 #define NGX_RWLOCK_WLOCK  ((ngx_atomic_uint_t) -1)
0017 
0018 
0019 void
0020 ngx_rwlock_wlock(ngx_atomic_t *lock)
0021 {
0022     ngx_uint_t  i, n;
0023 
0024     for ( ;; ) {
0025 
0026         if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) {
0027             return;
0028         }
0029 
0030         if (ngx_ncpu > 1) {
0031 
0032             for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {
0033 
0034                 for (i = 0; i < n; i++) {
0035                     ngx_cpu_pause();
0036                 }
0037 
0038                 if (*lock == 0
0039                     && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK))
0040                 {
0041                     return;
0042                 }
0043             }
0044         }
0045 
0046         ngx_sched_yield();
0047     }
0048 }
0049 
0050 
0051 void
0052 ngx_rwlock_rlock(ngx_atomic_t *lock)
0053 {
0054     ngx_uint_t         i, n;
0055     ngx_atomic_uint_t  readers;
0056 
0057     for ( ;; ) {
0058         readers = *lock;
0059 
0060         if (readers != NGX_RWLOCK_WLOCK
0061             && ngx_atomic_cmp_set(lock, readers, readers + 1))
0062         {
0063             return;
0064         }
0065 
0066         if (ngx_ncpu > 1) {
0067 
0068             for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {
0069 
0070                 for (i = 0; i < n; i++) {
0071                     ngx_cpu_pause();
0072                 }
0073 
0074                 readers = *lock;
0075 
0076                 if (readers != NGX_RWLOCK_WLOCK
0077                     && ngx_atomic_cmp_set(lock, readers, readers + 1))
0078                 {
0079                     return;
0080                 }
0081             }
0082         }
0083 
0084         ngx_sched_yield();
0085     }
0086 }
0087 
0088 
0089 void
0090 ngx_rwlock_unlock(ngx_atomic_t *lock)
0091 {
0092     ngx_atomic_uint_t  readers;
0093 
0094     readers = *lock;
0095 
0096     if (readers == NGX_RWLOCK_WLOCK) {
0097         *lock = 0;
0098         return;
0099     }
0100 
0101     for ( ;; ) {
0102 
0103         if (ngx_atomic_cmp_set(lock, readers, readers - 1)) {
0104             return;
0105         }
0106 
0107         readers = *lock;
0108     }
0109 }
0110 
0111 
0112 #else
0113 
0114 #if (NGX_HTTP_UPSTREAM_ZONE || NGX_STREAM_UPSTREAM_ZONE)
0115 
0116 #error ngx_atomic_cmp_set() is not defined!
0117 
0118 #endif
0119 
0120 #endif