Commit aea73116 authored by unknown's avatar unknown

post-review fixes (style)


include/lf.h:
  comments
parent 12a55aea
/* Copyright (C) 2006 MySQL AB
/*
TODO
1. copyright
6. reduce the number of memory barriers
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _lf_h
#define _lf_h
......@@ -11,7 +20,8 @@
#include <my_atomic.h>
/*
Generic helpers
Helpers to define both func() and _func(), where
func() is a _func() protected by my_atomic_rwlock_wrlock()
*/
#define lock_wrap(f,t,proto_args, args, lock) \
......@@ -49,7 +59,7 @@ static inline void f proto_args \
}
/*
dynamic array
wait-free dynamic array, see lf_dynarray.c
4 levels of 256 elements each mean 4311810304 elements in an array - it
should be enough for a while
......@@ -68,14 +78,9 @@ typedef int (*lf_dynarray_func)(void *, void *);
void lf_dynarray_init(LF_DYNARRAY *array, uint element_size);
void lf_dynarray_destroy(LF_DYNARRAY *array);
nolock_wrap(lf_dynarray_nr, int,
(LF_DYNARRAY *array, void *el),
(array,el));
nolock_wrap(lf_dynarray_value, void *,
(LF_DYNARRAY *array, uint idx),
(array,idx));
lock_wrap(lf_dynarray_lvalue, void *,
(LF_DYNARRAY *array, uint idx),
(array,idx),
......@@ -85,7 +90,7 @@ nolock_wrap(lf_dynarray_iterate, int,
(array,func,arg));
/*
pin manager for memory allocator
pin manager for memory allocator, lf_alloc-pin.c
*/
#define LF_PINBOX_PINS 4
......@@ -102,13 +107,13 @@ typedef struct {
uint32 volatile pins_in_stack; /* number of elements in array */
} LF_PINBOX;
/* we want sizeof(LF_PINS) to be 128 to avoid false sharing */
typedef struct {
void * volatile pin[LF_PINBOX_PINS];
LF_PINBOX *pinbox;
void *purgatory;
uint32 purgatory_count;
uint32 volatile link;
/* we want sizeof(LF_PINS) to be 128 to avoid false sharing */
char pad[128-sizeof(uint32)*2
-sizeof(void *)*(LF_PINBOX_PINS+2)];
} LF_PINS;
......@@ -160,19 +165,13 @@ lock_wrap_void(lf_pinbox_put_pins,
(LF_PINS *pins),
(pins),
&pins->pinbox->pinstack.lock);
#if 0
lock_wrap_void(lf_pinbox_real_free,
(LF_PINS *pins),
(pins),
&pins->pinbox->pinstack.lock);
#endif
lock_wrap_void(lf_pinbox_free,
(LF_PINS *pins, void *addr),
(pins,addr),
&pins->pinbox->pinstack.lock);
/*
memory allocator
memory allocator, lf_alloc-pin.c
*/
typedef struct st_lf_allocator {
......@@ -199,7 +198,7 @@ lock_wrap(lf_alloc_new, void *,
&pins->pinbox->pinstack.lock);
/*
extendible hash
extendible hash, lf_hash.c
*/
#include <hash.h>
......
......@@ -5,7 +5,7 @@
different characteristics. long lists, few distinct resources -
slow to scan, [possibly] high retry rate
*/
/* Copyright (C) 2000 MySQL AB
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -272,7 +272,7 @@ retry:
_lf_unpin(pins, 3);
do {
cursor->curr= PTR(*cursor->prev);
_lf_pin(pins,1,cursor->curr);
_lf_pin(pins, 1, cursor->curr);
} while(*cursor->prev != (intptr)cursor->curr && LF_BACKOFF);
for (;;)
{
......@@ -507,7 +507,7 @@ static int lockdelete(LOCK * volatile *head, LOCK *node, LF_PINS *pins)
void lockman_init(LOCKMAN *lm, loid_to_lo_func *func, uint timeout)
{
lf_alloc_init(&lm->alloc,sizeof(LOCK), offsetof(LOCK,lonext));
lf_alloc_init(&lm->alloc, sizeof(LOCK), offsetof(LOCK, lonext));
lf_dynarray_init(&lm->array, sizeof(LOCK **));
lm->size= 1;
lm->count= 0;
......@@ -744,7 +744,7 @@ static char *lock2str[]=
void print_lockhash(LOCKMAN *lm)
{
LOCK *el= *(LOCK **)_lf_dynarray_lvalue(&lm->array, 0);
printf("hash: size=%u count=%u\n", lm->size, lm->count);
printf("hash: size:%u count:%u\n", lm->size, lm->count);
while (el)
{
intptr next= el->link;
......
/* Copyright (C) 2000 MySQL AB
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......
This diff is collapsed.
/* Copyright (C) 2000 MySQL AB
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......
......@@ -48,10 +48,14 @@ LOCK_OWNER *loid2lo(uint16 loid)
ok(lockman_getlock(&lockman, loid2lo(O), R, L) == RES, \
"lo" #O "> " S " lock resource " #R " with " #L "-lock"); \
print_lockhash(&lockman)
#define lock_ok_a(O,R,L) test_lock(O,R,L,"",GOT_THE_LOCK)
#define lock_ok_i(O,R,L) test_lock(O,R,L,"",GOT_THE_LOCK_NEED_TO_LOCK_A_SUBRESOURCE)
#define lock_ok_l(O,R,L) test_lock(O,R,L,"",GOT_THE_LOCK_NEED_TO_INSTANT_LOCK_A_SUBRESOURCE)
#define lock_conflict(O,R,L) test_lock(O,R,L,"cannot ",DIDNT_GET_THE_LOCK);
#define lock_ok_a(O, R, L) \
test_lock(O, R, L, "", GOT_THE_LOCK)
#define lock_ok_i(O, R, L) \
test_lock(O, R, L, "", GOT_THE_LOCK_NEED_TO_LOCK_A_SUBRESOURCE)
#define lock_ok_l(O, R, L) \
test_lock(O, R, L, "", GOT_THE_LOCK_NEED_TO_INSTANT_LOCK_A_SUBRESOURCE)
#define lock_conflict(O, R, L) \
test_lock(O, R, L, "cannot ", DIDNT_GET_THE_LOCK);
void test_lockman_simple()
{
......@@ -63,41 +67,41 @@ void test_lockman_simple()
lock_ok_a(1, 1, X);
lock_ok_i(2, 2, IX);
/* failures */
lock_conflict(2,1,X);
lock_conflict(2, 1, X);
unlock_all(2);
lock_ok_a(1,2,S);
lock_ok_a(1,2,IS);
lock_ok_a(1,2,LS);
lock_ok_i(1,3,IX);
lock_ok_a(2,3,LS);
lock_ok_i(1,3,IX);
lock_ok_l(2,3,IS);
lock_ok_a(1, 2, S);
lock_ok_a(1, 2, IS);
lock_ok_a(1, 2, LS);
lock_ok_i(1, 3, IX);
lock_ok_a(2, 3, LS);
lock_ok_i(1, 3, IX);
lock_ok_l(2, 3, IS);
unlock_all(1);
unlock_all(2);
lock_ok_i(1,1,IX);
lock_conflict(2,1,S);
lock_ok_a(1,1,LS);
lock_ok_i(1, 1, IX);
lock_conflict(2, 1, S);
lock_ok_a(1, 1, LS);
unlock_all(1);
unlock_all(2);
lock_ok_i(1,1,IX);
lock_ok_a(2,1,LS);
lock_ok_a(1,1,LS);
lock_ok_i(1,1,IX);
lock_ok_i(3,1,IS);
lock_ok_i(1, 1, IX);
lock_ok_a(2, 1, LS);
lock_ok_a(1, 1, LS);
lock_ok_i(1, 1, IX);
lock_ok_i(3, 1, IS);
unlock_all(1);
unlock_all(2);
unlock_all(3);
lock_ok_i(1,4,IS);
lock_ok_i(2,4,IS);
lock_ok_i(3,4,IS);
lock_ok_a(3,4,LS);
lock_ok_i(4,4,IS);
lock_conflict(4,4,IX);
lock_conflict(2,4,IX);
lock_ok_a(1,4,LS);
lock_ok_i(1, 4, IS);
lock_ok_i(2, 4, IS);
lock_ok_i(3, 4, IS);
lock_ok_a(3, 4, LS);
lock_ok_i(4, 4, IS);
lock_conflict(4, 4, IX);
lock_conflict(2, 4, IX);
lock_ok_a(1, 4, LS);
unlock_all(1);
unlock_all(2);
unlock_all(3);
......@@ -110,7 +114,7 @@ pthread_mutex_t rt_mutex;
pthread_cond_t rt_cond;
int rt_num_threads;
int litmus;
int thread_number= 0, timeouts=0;
int thread_number= 0, timeouts= 0;
void run_test(const char *test, pthread_handler handler, int n, int m)
{
pthread_t t;
......@@ -121,7 +125,8 @@ void run_test(const char *test, pthread_handler handler, int n, int m)
diag("Testing %s with %d threads, %d iterations... ", test, n, m);
for (rt_num_threads= n ; n ; n--)
pthread_create(&t, &rt_attr, handler, &m);
if (pthread_create(&t, &rt_attr, handler, &m))
abort();
pthread_mutex_lock(&rt_mutex);
while (rt_num_threads)
pthread_cond_wait(&rt_cond, &rt_mutex);
......@@ -133,9 +138,9 @@ void run_test(const char *test, pthread_handler handler, int n, int m)
int Nrows= 100;
int Ntables= 10;
int table_lock_ratio= 10;
enum lock_type lock_array[6]={S,X,LS,LX,IS,IX};
char *lock2str[6]={"S","X","LS","LX","IS","IX"};
char *res2str[4]={
enum lock_type lock_array[6]= {S, X, LS, LX, IS, IX};
char *lock2str[6]= {"S", "X", "LS", "LX", "IS", "IX"};
char *res2str[4]= {
"DIDN'T GET THE LOCK",
"GOT THE LOCK",
"GOT THE LOCK NEED TO LOCK A SUBRESOURCE",
......@@ -160,12 +165,12 @@ pthread_handler_t test_lockman(void *arg)
if (table_lock_ratio && (x/Nrows/4) % table_lock_ratio == 0)
{ /* table lock */
res= lockman_getlock(&lockman, lo, table, lock_array[locklevel]);
DIAG(("loid=%2d, table %d lock %s, res=%s", loid, table,
DIAG(("loid %2d, table %d, lock %s, res %s", loid, table,
lock2str[locklevel], res2str[res]));
if (res == DIDNT_GET_THE_LOCK)
{
lockman_release_locks(&lockman, lo);
DIAG(("loid=%2d, release all locks", loid));
DIAG(("loid %2d, release all locks", loid));
timeout++;
continue;
}
......@@ -175,13 +180,13 @@ pthread_handler_t test_lockman(void *arg)
{ /* row lock */
locklevel&= 1;
res= lockman_getlock(&lockman, lo, table, lock_array[locklevel + 4]);
DIAG(("loid=%2d, row %d lock %s, res=%s", loid, row,
DIAG(("loid %2d, row %d, lock %s, res %s", loid, row,
lock2str[locklevel+4], res2str[res]));
switch (res)
{
case DIDNT_GET_THE_LOCK:
lockman_release_locks(&lockman, lo);
DIAG(("loid=%2d, release all locks", loid));
DIAG(("loid %2d, release all locks", loid));
timeout++;
continue;
case GOT_THE_LOCK:
......@@ -190,12 +195,12 @@ pthread_handler_t test_lockman(void *arg)
/* not implemented, so take a regular lock */
case GOT_THE_LOCK_NEED_TO_LOCK_A_SUBRESOURCE:
res= lockman_getlock(&lockman, lo, row, lock_array[locklevel]);
DIAG(("loid=%2d, ROW %d lock %s, res=%s", loid, row,
DIAG(("loid %2d, ROW %d, lock %s, res %s", loid, row,
lock2str[locklevel], res2str[res]));
if (res == DIDNT_GET_THE_LOCK)
{
lockman_release_locks(&lockman, lo);
DIAG(("loid=%2d, release all locks", loid));
DIAG(("loid %2d, release all locks", loid));
timeout++;
continue;
}
......@@ -234,7 +239,7 @@ int main()
return exit_status();
pthread_attr_init(&rt_attr);
pthread_attr_setdetachstate(&rt_attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setdetachstate(&rt_attr, PTHREAD_CREATE_DETACHED);
pthread_mutex_init(&rt_mutex, 0);
pthread_cond_init(&rt_cond, 0);
......@@ -261,13 +266,13 @@ int main()
Nrows= 100;
Ntables= 10;
table_lock_ratio= 10;
run_test("lockman", test_lockman, THREADS,CYCLES);
run_test("lockman", test_lockman, THREADS, CYCLES);
/* "real-life" simulation - many rows, no table locks */
Nrows= 1000000;
Ntables= 10;
table_lock_ratio= 0;
run_test("lockman", test_lockman, THREADS,10000);
run_test("lockman", test_lockman, THREADS, 10000);
for (i= 0; i < Nlos; i++)
{
......
......@@ -41,7 +41,7 @@ pthread_handler_t test_trnman(void *arg)
pthread_mutex_t mutexes[MAX_ITER];
pthread_cond_t conds[MAX_ITER];
for (i=0; i < MAX_ITER; i++)
for (i= 0; i < MAX_ITER; i++)
{
pthread_mutex_init(&mutexes[i], MY_MUTEX_INIT_FAST);
pthread_cond_init(&conds[i], 0);
......@@ -60,7 +60,7 @@ pthread_handler_t test_trnman(void *arg)
}
}
for (i=0; i < MAX_ITER; i++)
for (i= 0; i < MAX_ITER; i++)
{
pthread_mutex_destroy(&mutexes[i]);
pthread_cond_destroy(&conds[i]);
......@@ -84,7 +84,8 @@ void run_test(const char *test, pthread_handler handler, int n, int m)
diag("Testing %s with %d threads, %d iterations... ", test, n, m);
for (rt_num_threads= n ; n ; n--)
pthread_create(&t, &rt_attr, handler, &m);
if (pthread_create(&t, &rt_attr, handler, &m))
abort();
pthread_mutex_lock(&rt_mutex);
while (rt_num_threads)
pthread_cond_wait(&rt_cond, &rt_mutex);
......@@ -94,11 +95,10 @@ void run_test(const char *test, pthread_handler handler, int n, int m)
}
#define ok_read_from(T1, T2, RES) \
i=trnman_can_read_from(trn[T1], trid[T2]); \
i= trnman_can_read_from(trn[T1], trn[T2]->trid); \
ok(i == RES, "trn" #T1 " %s read from trn" #T2, i ? "can" : "cannot")
#define start_transaction(T) \
trn[T]= trnman_new_trn(&mutexes[T], &conds[T]); \
trid[T]= trn[T]->trid
trn[T]= trnman_new_trn(&mutexes[T], &conds[T])
#define commit(T) trnman_commit_trn(trn[T])
#define abort(T) trnman_abort_trn(trn[T])
......@@ -106,12 +106,11 @@ void run_test(const char *test, pthread_handler handler, int n, int m)
void test_trnman_read_from()
{
TRN *trn[Ntrns];
TrID trid[Ntrns];
pthread_mutex_t mutexes[Ntrns];
pthread_cond_t conds[Ntrns];
int i;
for (i=0; i < Ntrns; i++)
for (i= 0; i < Ntrns; i++)
{
pthread_mutex_init(&mutexes[i], MY_MUTEX_INIT_FAST);
pthread_cond_init(&conds[i], 0);
......@@ -119,19 +118,19 @@ void test_trnman_read_from()
start_transaction(0); /* start trn1 */
start_transaction(1); /* start trn2 */
ok_read_from(1,0,0);
ok_read_from(1, 0, 0);
commit(0); /* commit trn1 */
start_transaction(2); /* start trn4 */
abort(2); /* abort trn4 */
start_transaction(3); /* start trn5 */
ok_read_from(3,0,1);
ok_read_from(3,1,0);
ok_read_from(3,2,0);
ok_read_from(3, 0, 1);
ok_read_from(3, 1, 0);
ok_read_from(3, 2, 0);
commit(1); /* commit trn2 */
ok_read_from(3,1,0);
ok_read_from(3, 1, 0);
commit(3); /* commit trn5 */
for (i=0; i < Ntrns; i++)
for (i= 0; i < Ntrns; i++)
{
pthread_mutex_destroy(&mutexes[i]);
pthread_cond_destroy(&conds[i]);
......@@ -148,7 +147,7 @@ int main()
return exit_status();
pthread_attr_init(&rt_attr);
pthread_attr_setdetachstate(&rt_attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setdetachstate(&rt_attr, PTHREAD_CREATE_DETACHED);
pthread_mutex_init(&rt_mutex, 0);
pthread_cond_init(&rt_cond, 0);
......@@ -158,7 +157,7 @@ int main()
trnman_init();
test_trnman_read_from();
run_test("trnman", test_trnman, THREADS,CYCLES);
run_test("trnman", test_trnman, THREADS, CYCLES);
diag("mallocs: %d", trnman_allocated_transactions);
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment