PostgreSQL Source Code: src/backend/storage/lmgr/s_lock.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

49

52

56

57#define MIN_SPINS_PER_DELAY 10

58#define MAX_SPINS_PER_DELAY 1000

59#define NUM_DELAYS 1000

60#define MIN_DELAY_USEC 1000L

61#define MAX_DELAY_USEC 1000000L

62

63#ifdef S_LOCK_TEST

64

65

66

67

70#endif

71

73

74

75

76

77

78static void

79s_lock_stuck(const char *file, int line, const char *func)

80{

81 if (!func)

82 func = "(unknown)";

83#if defined(S_LOCK_TEST)

85 "\nStuck spinlock detected at %s, %s:%d.\n",

86 func, file, line);

87 exit(1);

88#else

89 elog(PANIC, "stuck spinlock detected at %s, %s:%d",

90 func, file, line);

91#endif

92}

93

94

95

96

97int

98s_lock(volatile slock_t *lock, const char *file, int line, const char *func)

99{

101

103

105 {

107 }

108

110

111 return delayStatus.delays;

112}

113

114#ifdef USE_DEFAULT_S_UNLOCK

115void

117{

118 *lock = 0;

119}

120#endif

121

122

123

124

125void

127{

128

130

131

133 {

136

137 if (status->cur_delay == 0)

139

140

141

142

143

144

145

146

147

151

152#if defined(S_LOCK_TEST)

155#endif

156

157

160

163

164 status->spins = 0;

165 }

166}

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185void

187{

189 {

190

193 }

194 else

195 {

198 }

199}

200

201

202

203

204

205

206void

208{

210}

211

212

213

214

215

216

217int

219{

220

221

222

223

224

225

226

227

228

229

230 return (shared_spins_per_delay * 15 + spins_per_delay) / 16;

231}

232

233

234

235#if defined(S_LOCK_TEST)

236

237

238

239

240

241struct test_lock_struct

242{

243 char pad1;

244 slock_t lock;

245 char pad2;

246};

247

248volatile struct test_lock_struct test_lock;

249

250int

252{

254

255 test_lock.pad1 = test_lock.pad2 = 0x44;

256

258

259 if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)

260 {

261 printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");

262 return 1;

263 }

264

266 {

267 printf("S_LOCK_TEST: failed, lock not initialized\n");

268 return 1;

269 }

270

271 S_LOCK(&test_lock.lock);

272

273 if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)

274 {

275 printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");

276 return 1;

277 }

278

280 {

281 printf("S_LOCK_TEST: failed, lock not locked\n");

282 return 1;

283 }

284

286

287 if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)

288 {

289 printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");

290 return 1;

291 }

292

294 {

295 printf("S_LOCK_TEST: failed, lock not unlocked\n");

296 return 1;

297 }

298

299 S_LOCK(&test_lock.lock);

300

301 if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)

302 {

303 printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");

304 return 1;

305 }

306

308 {

309 printf("S_LOCK_TEST: failed, lock not re-locked\n");

310 return 1;

311 }

312

313 printf("S_LOCK_TEST: this will print %d stars and then\n", NUM_DELAYS);

314 printf(" exit with a 'stuck spinlock' message\n");

315 printf(" if S_LOCK() and TAS() are working.\n");

317

318 s_lock(&test_lock.lock, __FILE__, __LINE__, __func__);

319

320 printf("S_LOCK_TEST: failed, lock not locked\n");

321 return 1;

322}

323

324#endif

#define fprintf(file, fmt, msg)

int main(int argc, char **argv)

double pg_prng_double(pg_prng_state *state)

void pg_prng_seed(pg_prng_state *state, uint64 seed)

pg_prng_state pg_global_prng_state

void set_spins_per_delay(int shared_spins_per_delay)

void perform_spin_delay(SpinDelayStatus *status)

void finish_spin_delay(SpinDelayStatus *status)

int s_lock(volatile slock_t *lock, const char *file, int line, const char *func)

#define MAX_SPINS_PER_DELAY

void s_unlock(volatile slock_t *lock)

#define MIN_SPINS_PER_DELAY

int update_spins_per_delay(int shared_spins_per_delay)

static int spins_per_delay

static void s_lock_stuck(const char *file, int line, const char *func)

#define DEFAULT_SPINS_PER_DELAY

#define S_LOCK_FREE(lock)

static void init_spin_delay(SpinDelayStatus *status, const char *file, int line, const char *func)

#define S_INIT_LOCK(lock)

void pg_usleep(long microsec)

static uint32 local_my_wait_event_info

uint32 * my_wait_event_info

static void pgstat_report_wait_start(uint32 wait_event_info)

static void pgstat_report_wait_end(void)