tlockfree.c 2.3 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
B
Bomin Zhang 已提交
17
#include "tlockfree.h"
H
Hongze Cheng 已提交
18 19 20 21 22 23 24

#define TD_RWLATCH_WRITE_FLAG 0x40000000

void taosInitRWLatch(SRWLatch *pLatch) { *pLatch = 0; }

void taosWLockLatch(SRWLatch *pLatch) {
  SRWLatch oLatch, nLatch;
S
Shengliang Guan 已提交
25
  int32_t  nLoops = 0;
H
Hongze Cheng 已提交
26 27 28

  // Set write flag
  while (1) {
29
    oLatch = atomic_load_32(pLatch);
H
Hongze Cheng 已提交
30 31 32 33 34 35 36 37 38 39
    if (oLatch & TD_RWLATCH_WRITE_FLAG) {
      nLoops++;
      if (nLoops > 1000) {
        sched_yield();
        nLoops = 0;
      }
      continue;
    }

    nLatch = oLatch | TD_RWLATCH_WRITE_FLAG;
40
    if (atomic_val_compare_exchange_32(pLatch, oLatch, nLatch) == oLatch) break;
H
Hongze Cheng 已提交
41 42 43 44 45
  }

  // wait for all reads end
  nLoops = 0;
  while (1) {
46 47
    oLatch = atomic_load_32(pLatch);
    if (0 == oLatch) break;
H
Hongze Cheng 已提交
48 49 50 51 52 53 54 55
    nLoops++;
    if (nLoops > 1000) {
      sched_yield();
      nLoops = 0;
    }
  }
}

56
// no reentrant
D
dapan1121 已提交
57 58
int32_t taosWTryLockLatch(SRWLatch *pLatch) {
  SRWLatch oLatch, nLatch;
59 60
  oLatch = atomic_load_32(pLatch);
  if (oLatch) {
D
dapan1121 已提交
61 62 63 64
    return -1;
  }

  nLatch = oLatch | TD_RWLATCH_WRITE_FLAG;
65
  if (atomic_val_compare_exchange_32(pLatch, oLatch, nLatch) == oLatch) {
D
dapan1121 已提交
66 67 68 69 70 71
    return 0;
  }

  return -1;
}

72
void taosWUnLockLatch(SRWLatch *pLatch) { atomic_store_32(pLatch, 0); }
H
Hongze Cheng 已提交
73 74 75

void taosRLockLatch(SRWLatch *pLatch) {
  SRWLatch oLatch, nLatch;
S
Shengliang Guan 已提交
76
  int32_t  nLoops = 0;
H
Hongze Cheng 已提交
77 78

  while (1) {
79
    oLatch = atomic_load_32(pLatch);
H
Hongze Cheng 已提交
80 81 82 83 84 85 86 87 88 89
    if (oLatch & TD_RWLATCH_WRITE_FLAG) {
      nLoops++;
      if (nLoops > 1000) {
        sched_yield();
        nLoops = 0;
      }
      continue;
    }

    nLatch = oLatch + 1;
90
    if (atomic_val_compare_exchange_32(pLatch, oLatch, nLatch) == oLatch) break;
H
Hongze Cheng 已提交
91 92 93
  }
}

94
void taosRUnLockLatch(SRWLatch *pLatch) { atomic_fetch_sub_32(pLatch, 1); }