CUBRID Engine  latest
critical_section.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * critical_section.h - Definitions for critical section interface.
22  */
23 
24 #ifndef _CRITICAL_SECTION_H_
25 #define _CRITICAL_SECTION_H_
26 
27 #ident "$Id$"
28 
29 #include "dbtype_def.h"
30 #include "porting.h" // for pthread, STATIC_CAST
31 #include "thread_compat.hpp"
32 
33 #if !defined(WINDOWS)
34 #include <pthread.h>
35 #endif /* !WINDOWS */
36 #if !defined(WINDOWS)
37 #include <sys/time.h>
38 #endif /* !WINDOWS */
39 #if defined (WINDOWS)
40 #include <WinSock2.h>
41 #endif // WINDOWS
42 
43 #if !defined (SERVER_MODE) && !defined (SA_MODE)
44 #error critical_section.h belongs to server or stand-alone modules.
45 #endif /* !defined (SERVER_MODE) && !defined (SA_MODE) */
46 
47 enum
48 {
49  INF_WAIT = -1, /* INFINITE WAIT */
50  NOT_WAIT = 0 /* NO WAIT */
51 };
52 
53 /*
54  * These are the user defined lock definitions. When adding more locks, also
55  * add initialization entries in critical_section.c
56  */
57 enum
58 {
59  CSECT_WFG = 0, /* Latch for wait-for-graph */
60  CSECT_LOG, /* Latch for log manager */
61  CSECT_LOCATOR_SR_CLASSNAME_TABLE, /* Latch for classname to classOID entries */
62  CSECT_QPROC_QUERY_TABLE, /* Latch for query manager table */
63  CSECT_QPROC_LIST_CACHE, /* Latch for query result(list file) cache (mht) */
64  CSECT_DISK_CHECK, /* Block changes on disk cache during check */
65  CSECT_CNV_FMT_LEXER, /* Latch for value/string format translation lexer */
66  CSECT_HEAP_CHNGUESS, /* Latch for schema change */
67 
68  CSECT_TRAN_TABLE, /* Latch for transaction table */
70  CSECT_HA_SERVER_STATE, /* Latch for HA server mode change */
71  CSECT_COMPACTDB_ONE_INSTANCE, /* Latch for compactdb */
72  CSECT_ACL, /* Latch for accessible IP list table */
73  CSECT_PARTITION_CACHE, /* Latch for partitions cache */
74  CSECT_EVENT_LOG_FILE, /* Latch for event log file */
75  CSECT_LOG_ARCHIVE, /* Latch for log_Gl.archive */
76  CSECT_ACCESS_STATUS, /* Latch for user access status */
78 };
79 
80 static const int CRITICAL_SECTION_COUNT = STATIC_CAST (int, CSECT_LAST);
81 
82 typedef enum
83 {
85 
86  SYNC_TYPE_CSECT, /* critical section primitive */
87  SYNC_TYPE_RWLOCK, /* rwlock primitive */
88  SYNC_TYPE_RMUTEX, /* re-entrant mutex */
89  SYNC_TYPE_MUTEX, /* simple mutex */
90 
95 
96 typedef struct sync_stats
97 {
99  const char *name;
100 
101  unsigned int nenter; /* total number of acquisition. */
102  unsigned int nwait; /* total number of waiting. only available for SYNC_TYPE_CSECT */
103  unsigned int nreenter; /* total number of re-acquisition. available for SYNC_TYPE_CSECT, SYNC_TYPE_RMUTEX */
104 
105  struct timeval total_elapsed; /* total elapsed time to acquire the synchronization primitive */
106  struct timeval max_elapsed; /* max elapsed time to acquire the synchronization primitive */
107 } SYNC_STATS;
108 
109 typedef struct sync_critical_section
110 {
111  const char *name;
112  int cs_index;
113  pthread_mutex_t lock; /* read/write monitor lock */
114  int rwlock; /* >0 = # readers, <0 = writer, 0 = none */
115  unsigned int waiting_readers; /* # of waiting readers */
116  unsigned int waiting_writers; /* # of waiting writers */
117  pthread_cond_t readers_ok; /* start waiting readers */
118  THREAD_ENTRY *waiting_writers_queue; /* queue of waiting writers */
119  THREAD_ENTRY *waiting_promoters_queue; /* queue of waiting promoters */
120  thread_id_t owner; /* CS owner writer */
121  int tran_index; /* transaction id acquiring CS */
124 
125 typedef struct sync_rwlock
126 {
127  const char *name;
128  pthread_mutex_t read_lock; /* read lock. Only readers will use it. */
129  pthread_mutex_t global_lock; /* global lock */
130  int num_readers; /* # of readers. Only readers will use it. */
132 } SYNC_RWLOCK;
133 
134 typedef struct sync_rmutex
135 {
136  const char *name;
137  pthread_mutex_t lock; /* mutex */
138  thread_id_t owner; /* owner thread id */
139  int lock_cnt; /* # of times that owner enters */
141 } SYNC_RMUTEX;
142 
145 
146 extern int csect_enter (THREAD_ENTRY * thread_p, int cs_index, int wait_secs);
147 extern int csect_enter_as_reader (THREAD_ENTRY * thread_p, int cs_index, int wait_secs);
148 extern int csect_demote (THREAD_ENTRY * thread_p, int cs_index, int wait_secs);
149 extern int csect_promote (THREAD_ENTRY * thread_p, int cs_index, int wait_secs);
150 extern int csect_exit (THREAD_ENTRY * thread_p, int cs_index);
151 
152 #if defined (SERVER_MODE)
153 extern const char *csect_name_at (int cs_index);
154 #else // not SERVER_MODE = SA_MODE
155 static inline const char *
156 csect_name_at (int cs_index)
157 {
158  return "UNKNOWN";
159 }
160 #endif // not SERVER_MODE = SA_MODE
161 extern int csect_initialize_critical_section (SYNC_CRITICAL_SECTION * cs_ptr, const char *name);
163 extern int csect_enter_critical_section (THREAD_ENTRY * thread_p, SYNC_CRITICAL_SECTION * cs_ptr, int wait_secs);
165  int wait_secs);
166 extern int csect_exit_critical_section (THREAD_ENTRY * thread_p, SYNC_CRITICAL_SECTION * cs_ptr);
167 
168 extern int csect_check_own (THREAD_ENTRY * thread_p, int cs_index);
169 
170 extern void csect_dump_statistics (FILE * fp);
171 
172 extern int csect_start_scan (THREAD_ENTRY * thread_p, int show_type, DB_VALUE ** arg_values, int arg_cnt, void **ctx);
173 
174 extern int rwlock_initialize (SYNC_RWLOCK * rwlock, const char *name);
175 extern int rwlock_finalize (SYNC_RWLOCK * rwlock);
176 
177 extern int rwlock_read_lock (SYNC_RWLOCK * rwlock);
178 extern int rwlock_read_unlock (SYNC_RWLOCK * rwlock);
179 
180 extern int rwlock_write_lock (SYNC_RWLOCK * rwlock);
181 extern int rwlock_write_unlock (SYNC_RWLOCK * rwlock);
182 
183 extern int sync_initialize_sync_stats (void);
184 extern int sync_finalize_sync_stats (void);
185 
186 extern void rwlock_dump_statistics (FILE * fp);
187 
188 extern int rmutex_initialize (SYNC_RMUTEX * rmutex, const char *name);
189 extern int rmutex_finalize (SYNC_RMUTEX * rmutex);
190 
191 extern int rmutex_lock (THREAD_ENTRY * thread_p, SYNC_RMUTEX * rmutex);
192 extern int rmutex_unlock (THREAD_ENTRY * thread_p, SYNC_RMUTEX * rmutex);
193 
194 extern void rmutex_dump_statistics (FILE * fp);
195 
196 extern void sync_dump_statistics (FILE * fp, SYNC_PRIMITIVE_TYPE type);
197 
198 #if !defined(SERVER_MODE)
199 #define csect_initialize_critical_section(a, b)
200 #define csect_finalize_critical_section(a)
201 #define csect_enter(a, b, c) NO_ERROR
202 #define csect_enter_as_reader(a, b, c) NO_ERROR
203 #define csect_exit(a, b)
204 #define csect_enter_critical_section(a, b, c)
205 #define csect_enter_critical_section_as_reader(a, b, c)
206 #define csect_exit_critical_section(a, b)
207 #define csect_check_own(a, b) 1
208 #define csect_start_scan NULL
209 
210 #define rwlock_initialize(a, b) NO_ERROR
211 #define rwlock_finalize(a) NO_ERROR
212 #define rwlock_read_lock(a) NO_ERROR
213 #define rwlock_read_unlock(a) NO_ERROR
214 #define rwlock_write_lock(a) NO_ERROR
215 #define rwlock_write_unlock(a) NO_ERROR
216 
217 #define rmutex_initialize(a, b) NO_ERROR
218 #define rmutex_finalize(a) NO_ERROR
219 #define rmutex_lock(a, b) NO_ERROR
220 #define rmutex_unlock(a, b) NO_ERROR
221 #endif /* !SERVER_MODE */
222 
223 #endif /* _CRITICAL_SECTION_H_ */
#define rmutex_finalize(a)
#define rwlock_write_unlock(a)
int csect_finalize_static_critical_sections(void)
#define rmutex_unlock(a, b)
struct sync_stats SYNC_STATS
THREAD_ENTRY * waiting_promoters_queue
int csect_initialize_static_critical_sections(void)
#define csect_finalize_critical_section(a)
unsigned long int thread_id_t
int sync_initialize_sync_stats(void)
struct sync_rmutex SYNC_RMUTEX
#define csect_initialize_critical_section(a, b)
struct sync_rwlock SYNC_RWLOCK
SYNC_STATS * stats
unsigned int nreenter
pthread_mutex_t global_lock
void THREAD_ENTRY
int csect_demote(THREAD_ENTRY *thread_p, int cs_index, int wait_secs)
unsigned int waiting_readers
unsigned int nwait
void sync_dump_statistics(FILE *fp, SYNC_PRIMITIVE_TYPE type)
#define csect_check_own(a, b)
void rwlock_dump_statistics(FILE *fp)
#define csect_enter(a, b, c)
#define rwlock_write_lock(a)
struct timeval max_elapsed
const char * name
const char * name
unsigned int waiting_writers
pthread_cond_t readers_ok
int sync_finalize_sync_stats(void)
pthread_mutex_t read_lock
SYNC_PRIMITIVE_TYPE type
#define rmutex_lock(a, b)
struct sync_critical_section SYNC_CRITICAL_SECTION
#define csect_enter_critical_section_as_reader(a, b, c)
#define csect_exit_critical_section(a, b)
SYNC_STATS * stats
int csect_promote(THREAD_ENTRY *thread_p, int cs_index, int wait_secs)
THREAD_ENTRY * waiting_writers_queue
#define rwlock_read_lock(a)
const char * name
#define rwlock_finalize(a)
struct timeval total_elapsed
#define csect_enter_as_reader(a, b, c)
unsigned int nenter
thread_id_t owner
void rmutex_dump_statistics(FILE *fp)
#define csect_exit(a, b)
#define csect_start_scan
SYNC_PRIMITIVE_TYPE
#define STATIC_CAST(dest_type, expr)
Definition: porting.h:1050
static const int CRITICAL_SECTION_COUNT
void csect_dump_statistics(FILE *fp)
pthread_mutex_t lock
#define rmutex_initialize(a, b)
#define csect_enter_critical_section(a, b, c)
#define rwlock_initialize(a, b)
#define rwlock_read_unlock(a)
static const char * csect_name_at(int cs_index)