summaryrefslogtreecommitdiff
path: root/innobase/sync/sync0ipm.c
blob: e10e1c85da580ca431bbe184071a436b15659f41 (plain)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/******************************************************
A fast mutex for interprocess synchronization.
mutex_t can be used only within single process,
but ip_mutex_t also between processes.

(c) 1995 Innobase Oy

Created 9/30/1995 Heikki Tuuri
*******************************************************/
#include "sync0ipm.h"
#ifdef UNIV_NONINL
#include "sync0ipm.ic"
#endif

#include "mem0mem.h"

/* The performance of the ip mutex in NT depends on how often
a thread has to suspend itself waiting for the ip mutex
to become free. The following variable counts system calls
involved. */

ulint	ip_mutex_system_call_count	= 0;

/**********************************************************************
Creates, or rather, initializes
an ip mutex object in a specified shared memory location (which must be
appropriately aligned). The ip mutex is initialized in the reset state.
NOTE! Explicit destroying of the ip mutex with ip_mutex_free
is not recommended
as the mutex resides in shared memory and we cannot make sure that
no process is currently accessing it. Therefore just use
ip_mutex_close to free the operating system event and mutex. */

ulint
ip_mutex_create(
/*============*/
					/* out: 0 if succeed */
	ip_mutex_t*	ip_mutex,	/* in: pointer to shared memory */
	char*		name,		/* in: name of the ip mutex */
	ip_mutex_hdl_t** handle)	/* out, own: handle to the
					created mutex; handle exists
					in the private address space of
					the calling process */
{
	mutex_t*	mutex;
	char*		buf;
	os_event_t	released;
	os_mutex_t	exclude;
	
	ip_mutex_set_waiters(ip_mutex, 0);

	buf = mem_alloc(strlen(name) + 20);

	strcpy(buf, name);
	strcpy(buf + strlen(name), "_IB_RELS");

	released = os_event_create(buf);

	if (released == NULL) {
		mem_free(buf);
		return(1);
	}

	strcpy(buf + strlen(name), "_IB_EXCL");

	exclude = os_mutex_create(buf);

	if (exclude == NULL) {
		os_event_free(released);
		mem_free(buf);
		return(1);
	}

	mutex = ip_mutex_get_mutex(ip_mutex);

	mutex_create(mutex);
	mutex_set_level(mutex, SYNC_NO_ORDER_CHECK);
	
	*handle = mem_alloc(sizeof(ip_mutex_hdl_t));

	(*handle)->ip_mutex = ip_mutex;
	(*handle)->released = released;
	(*handle)->exclude = exclude;

	mem_free(buf);

	return(0);
}

/**********************************************************************
NOTE! Using this function is not recommended. See the note
on ip_mutex_create. Destroys an ip mutex */

void
ip_mutex_free(
/*==========*/
	ip_mutex_hdl_t*	handle)		/* in, own: ip mutex handle */
{
	mutex_free(ip_mutex_get_mutex(handle->ip_mutex));

	os_event_free(handle->released);
	os_mutex_free(handle->exclude);

	mem_free(handle);
}

/**********************************************************************
Opens an ip mutex object in a specified shared memory location.
Explicit closing of the ip mutex with ip_mutex_close is necessary to
free the operating system event and mutex created, and the handle. */

ulint
ip_mutex_open(
/*==========*/
					/* out: 0 if succeed */
	ip_mutex_t*	ip_mutex,	/* in: pointer to shared memory */
	char*		name,		/* in: name of the ip mutex */
	ip_mutex_hdl_t** handle)	/* out, own: handle to the
					opened mutex */
{
	char*		buf;
	os_event_t	released;
	os_mutex_t	exclude;
	
	buf = mem_alloc(strlen(name) + 20);

	strcpy(buf, name);
	strcpy(buf + strlen(name), "_IB_RELS");

	released = os_event_create(buf);

	if (released == NULL) {
		mem_free(buf);
		return(1);
	}

	strcpy(buf + strlen(name), "_IB_EXCL");

	exclude = os_mutex_create(buf);

	if (exclude == NULL) {
		os_event_free(released);
		mem_free(buf);
		return(1);
	}

	*handle = mem_alloc(sizeof(ip_mutex_hdl_t));

	(*handle)->ip_mutex = ip_mutex;
	(*handle)->released = released;
	(*handle)->exclude = exclude;

	mem_free(buf);

	return(0);
}

/**********************************************************************
Closes an ip mutex. */

void
ip_mutex_close(
/*===========*/
	ip_mutex_hdl_t*	handle)		/* in, own: ip mutex handle */
{
	os_event_free(handle->released);
	os_mutex_free(handle->exclude);

	mem_free(handle);
}