Below is the list of changes that have just been committed into a local
5.1 repository of knielsen. When knielsen does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-07 13:11:35+01:00, knielsen@ymer.(none) +3 -0
WL#1498: Multi-threaded ndbd.
Introduce locking around global memory manager for multi-threaded ndbd.
Debugging stats for signal sending.
storage/ndb/src/kernel/vm/FastScheduler.cpp@stripped, 2007-11-07 13:11:32+01:00, knielsen@ymer.(none) +10 -0
Introduce locking around global memory manager for multi-threaded ndbd.
storage/ndb/src/kernel/vm/mt/mt.cpp@stripped, 2007-11-07 13:11:32+01:00, knielsen@ymer.(none) +43 -1
Introduce locking around global memory manager for multi-threaded ndbd.
Debugging stats for signal sending.
storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp@stripped, 2007-11-07 13:11:32+01:00, knielsen@ymer.(none) +26 -0
Introduce locking around global memory manager for multi-threaded ndbd.
diff -Nrup a/storage/ndb/src/kernel/vm/FastScheduler.cpp b/storage/ndb/src/kernel/vm/FastScheduler.cpp
--- a/storage/ndb/src/kernel/vm/FastScheduler.cpp 2007-10-12 13:25:02 +02:00
+++ b/storage/ndb/src/kernel/vm/FastScheduler.cpp 2007-11-07 13:11:32 +01:00
@@ -548,3 +548,13 @@ FastScheduler::reportThreadConfigLoop(Ui
execute(&signal, JBA, CMVMI, GSN_EVENT_REP);
}
+/* Dummy functions for single-threaded ndbd. */
+void
+mt_mem_manager_lock()
+{
+}
+
+void
+mt_mem_manager_unlock()
+{
+}
diff -Nrup a/storage/ndb/src/kernel/vm/mt/mt.cpp b/storage/ndb/src/kernel/vm/mt/mt.cpp
--- a/storage/ndb/src/kernel/vm/mt/mt.cpp 2007-11-01 15:29:17 +01:00
+++ b/storage/ndb/src/kernel/vm/mt/mt.cpp 2007-11-07 13:11:32 +01:00
@@ -47,6 +47,7 @@ static const Uint32 MAX_SIGNALS_PER_JB =
#define NDB_MT_LOCK_TO_CPU
+//#define VM_MT_STATS
static const Uint32 NUM_THREADS = 3;
#define MAX_THREADS 4
@@ -432,6 +433,12 @@ struct thr_data
EmulatedJamBuffer *m_jam;
/* Watchdog counter for this thread. */
Uint32 *m_watchdog_counter;
+#ifdef VM_MT_STATS
+ Uint64 m_prioa_count;
+ Uint64 m_prioa_size;
+ Uint64 m_priob_count;
+ Uint64 m_priob_size;
+#endif
};
#define DBG_MALLOC 0
@@ -475,12 +482,14 @@ struct thr_repository
thr_repository()
: m_send_lock("sendlock"),
m_receive_lock("recvlock"),
- m_section_lock("sectionlock") {}
+ m_section_lock("sectionlock"),
+ m_mem_manager_lock("memmanagerlock") {}
unsigned m_thread_count;
struct thr_spin_lock m_send_lock;
struct thr_spin_lock m_receive_lock;
struct thr_spin_lock m_section_lock;
+ struct thr_spin_lock m_mem_manager_lock;
struct thr_data m_thread[MAX_THREADS];
struct thr_safe_pool<thr_job_buffer> m_free_list;
@@ -1223,6 +1232,13 @@ sendlocal(Uint32 self, Uint32 block, con
struct thr_repository* rep = &g_thr_repository;
struct thr_data * selfptr = rep->m_thread + self;
+#ifdef VM_MT_STATS
+ selfptr->m_priob_count++;
+ Uint32 siglen = (sizeof(*s) >> 2) + s->theLength + s->m_noOfSections;
+ selfptr->m_priob_size += siglen;
+ // if(selfptr->m_priob_count%2000000==0)ndbout_c("THR %u LOCAL signals: count=%lu bytes=%lu", self, selfptr->m_priob_count, selfptr->m_priob_size*4);
+#endif
+
thr_job_queue *q = rep->m_thread[dst].m_in_queue + self;
thr_jb_write_state *w = selfptr->m_write_states + dst;
if (insert_signal(q, w, false, s, selfptr->m_next_buffer))
@@ -1242,6 +1258,13 @@ sendprioa(Uint32 self, Uint32 block, con
struct thr_data * selfptr = rep->m_thread + self;
struct thr_data *dstptr = rep->m_thread + dst;
+#ifdef VM_MT_STATS
+ selfptr->m_prioa_count++;
+ Uint32 siglen = (sizeof(*s) >> 2) + s->theLength + s->m_noOfSections;
+ selfptr->m_prioa_size += siglen;
+ // if(selfptr->m_prioa_count%50000==0)ndbout_c("THR %u PRIOA signals: count=%lu bytes=%lu", self, selfptr->m_prioa_count, selfptr->m_prioa_size*4);
+#endif
+
thr_job_queue *q = &(dstptr->m_jba);
thr_jb_write_state w;
@@ -1494,6 +1517,13 @@ init(struct thr_repository* rep, struct
init(&selfptr->m_tq);
selfptr->m_jam = NULL;
+
+#ifdef VM_MT_STATS
+ selfptr->m_prioa_count = 0;
+ selfptr->m_prioa_size = 0;
+ selfptr->m_priob_count = 0;
+ selfptr->m_priob_size = 0;
+#endif
}
/* Have to do this after init of all m_in_queues is done. */
@@ -1975,6 +2005,18 @@ void
mt_section_unlock()
{
unlock(&(g_thr_repository.m_section_lock));
+}
+
+void
+mt_mem_manager_lock()
+{
+ lock(&(g_thr_repository.m_mem_manager_lock));
+}
+
+void
+mt_mem_manager_unlock()
+{
+ unlock(&(g_thr_repository.m_mem_manager_lock));
}
/**
diff -Nrup a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
--- a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp 2007-05-17 12:58:10 +02:00
+++ b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp 2007-11-07 13:11:32 +01:00
@@ -33,6 +33,16 @@ static const char * f_method = "MSms";
#endif
#define MAX_CHUNKS 10
+/*
+ * For muti-threaded ndbd, these calls are used for locking around
+ * memory allocation operations.
+ *
+ * For single-threaded ndbd, they are no-ops (but still called, to avoid
+ * having to compile this file twice).
+ */
+extern void mt_mem_manager_lock();
+extern void mt_mem_manager_unlock();
+
struct InitChunk
{
Uint32 m_cnt;
@@ -184,11 +194,13 @@ Ndbd_mem_manager::set_resource_limit(con
assert(id < XX_RL_COUNT);
Uint32 reserve = id ? rl.m_min : 0;
+ mt_mem_manager_lock();
Uint32 current_reserved = m_resource_limit[0].m_min;
m_resource_limit[id] = rl;
m_resource_limit[id].m_curr = 0;
m_resource_limit[0].m_min = current_reserved + reserve;
+ mt_mem_manager_unlock();
}
bool
@@ -196,7 +208,9 @@ Ndbd_mem_manager::get_resource_limit(Uin
{
if (id < XX_RL_COUNT)
{
+ mt_mem_manager_lock();
rl = m_resource_limit[id];
+ mt_mem_manager_unlock();
return true;
}
return false;
@@ -604,6 +618,7 @@ Ndbd_mem_manager::remove_free_list(Uint3
void
Ndbd_mem_manager::dump() const
{
+ mt_mem_manager_lock();
for(Uint32 i = 0; i<16; i++)
{
printf(" list: %d - ", i);
@@ -626,6 +641,7 @@ Ndbd_mem_manager::dump() const
m_resource_limit[i].m_curr,
m_resource_limit[i].m_max);
}
+ mt_mem_manager_unlock();
}
void*
@@ -633,6 +649,7 @@ Ndbd_mem_manager::alloc_page(Uint32 type
{
Uint32 idx = type & RG_MASK;
assert(idx && idx < XX_RL_COUNT);
+ mt_mem_manager_lock();
Resource_limit tot = m_resource_limit[0];
Resource_limit rl = m_resource_limit[idx];
@@ -653,9 +670,11 @@ Ndbd_mem_manager::alloc_page(Uint32 type
m_resource_limit[idx].m_curr = rl.m_curr + cnt;
check_resource_limits(m_resource_limit);
+ mt_mem_manager_unlock();
return m_base_page + *i;
}
}
+ mt_mem_manager_unlock();
return 0;
}
@@ -664,6 +683,7 @@ Ndbd_mem_manager::release_page(Uint32 ty
{
Uint32 idx = type & RG_MASK;
assert(idx && idx < XX_RL_COUNT);
+ mt_mem_manager_lock();
Resource_limit tot = m_resource_limit[0];
Resource_limit rl = m_resource_limit[idx];
@@ -674,6 +694,7 @@ Ndbd_mem_manager::release_page(Uint32 ty
m_resource_limit[idx].m_curr = rl.m_curr - 1;
check_resource_limits(m_resource_limit);
+ mt_mem_manager_unlock();
}
void
@@ -681,6 +702,7 @@ Ndbd_mem_manager::alloc_pages(Uint32 typ
{
Uint32 idx = type & RG_MASK;
assert(idx && idx < XX_RL_COUNT);
+ mt_mem_manager_lock();
Resource_limit tot = m_resource_limit[0];
Resource_limit rl = m_resource_limit[idx];
@@ -731,9 +753,11 @@ Ndbd_mem_manager::alloc_pages(Uint32 typ
m_resource_limit[0].m_min = tot.m_min - res0;
m_resource_limit[idx].m_curr = rl.m_curr + req;
check_resource_limits(m_resource_limit);
+ mt_mem_manager_unlock();
return ;
}
* cnt = req;
+ mt_mem_manager_unlock();
return;
}
@@ -742,6 +766,7 @@ Ndbd_mem_manager::release_pages(Uint32 t
{
Uint32 idx = type & RG_MASK;
assert(idx && idx < XX_RL_COUNT);
+ mt_mem_manager_lock();
Resource_limit tot = m_resource_limit[0];
Resource_limit rl = m_resource_limit[idx];
@@ -762,6 +787,7 @@ Ndbd_mem_manager::release_pages(Uint32 t
m_resource_limit[0].m_curr = tot.m_curr - cnt;
m_resource_limit[idx].m_curr = currnew;
check_resource_limits(m_resource_limit);
+ mt_mem_manager_unlock();
}
#ifdef UNIT_TEST
| Thread |
|---|
| • bk commit into 5.1 tree (knielsen:1.2617) | knielsen | 7 Nov |