1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 - 2010 Toru Maesaka
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
using namespace drizzled;
25
BlitzLock::BlitzLock() : scanner_count(0), updater_count(0) {
26
pthread_cond_init(&condition, NULL);
27
pthread_mutex_init(&mutex, NULL);
29
for (int i = 0; i < BLITZ_LOCK_SLOTS; i++)
30
pthread_mutex_init(&slots[i], NULL);
33
BlitzLock::~BlitzLock() {
34
pthread_cond_destroy(&condition);
35
pthread_mutex_destroy(&mutex);
37
for (int i = 0; i < BLITZ_LOCK_SLOTS; i++)
38
pthread_mutex_destroy(&slots[i]);
41
uint32_t BlitzLock::slot_id(const void *data, size_t len) {
42
uint64_t hash = 14695981039346656037ULL;
43
const unsigned char *rp = (unsigned char *)data;
44
const unsigned char *ep = rp + len;
47
hash = (hash ^ *(rp++)) * 109951162811ULL;
49
return (uint32_t)(hash % BLITZ_LOCK_SLOTS);
52
int BlitzLock::slotted_lock(const uint32_t id) {
53
return pthread_mutex_lock(&slots[id]);
56
int BlitzLock::slotted_unlock(const uint32_t id) {
57
return pthread_mutex_unlock(&slots[id]);
60
void BlitzLock::update_begin() {
61
pthread_mutex_lock(&mutex);
63
if (scanner_count < 1) {
65
pthread_mutex_unlock(&mutex);
68
pthread_cond_wait(&condition, &mutex);
70
pthread_mutex_unlock(&mutex);
73
void BlitzLock::update_end() {
74
pthread_mutex_lock(&mutex);
76
assert(updater_count >= 0);
77
if (updater_count == 0)
78
pthread_cond_broadcast(&condition);
79
pthread_mutex_unlock(&mutex);
82
void BlitzLock::scan_begin() {
83
pthread_mutex_lock(&mutex);
85
if (updater_count == 0) {
87
pthread_mutex_unlock(&mutex);
90
pthread_cond_wait(&condition, &mutex);
92
pthread_mutex_unlock(&mutex);
95
void BlitzLock::scan_end() {
96
pthread_mutex_lock(&mutex);
98
assert(scanner_count >= 0);
99
if (scanner_count == 0)
100
pthread_cond_broadcast(&condition);
101
pthread_mutex_unlock(&mutex);
104
void BlitzLock::scan_update_begin() {
105
pthread_mutex_lock(&mutex);
107
if (scanner_count == 0 && updater_count == 0) {
110
pthread_mutex_unlock(&mutex);
113
pthread_cond_wait(&condition, &mutex);
115
pthread_mutex_unlock(&mutex);
118
void BlitzLock::scan_update_end() {
119
pthread_mutex_lock(&mutex);
122
assert(scanner_count >= 0 && updater_count >= 0);
124
/* All other threads are guaranteed to be
125
waiting so broadcast regardless. */
126
pthread_cond_broadcast(&condition);
127
pthread_mutex_unlock(&mutex);
130
int ha_blitz::critical_section_enter() {
131
if (sql_command_type == SQLCOM_ALTER_TABLE ||
132
sql_command_type == SQLCOM_UPDATE ||
133
sql_command_type == SQLCOM_DELETE ||
134
sql_command_type == SQLCOM_REPLACE ||
135
sql_command_type == SQLCOM_REPLACE_SELECT) {
136
share->blitz_lock.scan_update_begin();
138
share->blitz_lock.scan_begin();
140
thread_locked = true;
144
int ha_blitz::critical_section_exit() {
145
if (sql_command_type == SQLCOM_ALTER_TABLE ||
146
sql_command_type == SQLCOM_UPDATE ||
147
sql_command_type == SQLCOM_DELETE ||
148
sql_command_type == SQLCOM_REPLACE ||
149
sql_command_type == SQLCOM_REPLACE_SELECT) {
150
share->blitz_lock.scan_update_end();
152
share->blitz_lock.scan_end();
154
thread_locked = false;