diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/atomic/generic-msvc.h | 12 | ||||
-rw-r--r-- | include/lf.h | 8 | ||||
-rw-r--r-- | include/maria.h | 4 | ||||
-rw-r--r-- | include/my_pthread.h | 14 | ||||
-rw-r--r-- | include/waiting_threads.h | 122 |
5 files changed, 45 insertions, 115 deletions
diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index bd3365fc243..58c6e7d8b9a 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 MySQL AB +/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -52,11 +52,11 @@ LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); #endif /*_M_IX86*/ #define MY_ATOMIC_MODE "msvc-intrinsics" -#define IL_EXCHG_ADD32(X,Y) InterlockedExchangeAdd((volatile LONG *)(X),(Y)) -#define IL_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) -#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer -#define IL_EXCHG32 InterlockedExchange -#define IL_EXCHGptr InterlockedExchangePointer +#define IL_EXCHG_ADD32(X,Y) InterlockedExchangeAdd((volatile LONG *)(X),(Y)) +#define IL_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) +#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer +#define IL_EXCHG32(X,Y) InterlockedExchange((volatile LONG *)(X),(Y)) +#define IL_EXCHGptr InterlockedExchangePointer #define make_atomic_add_body(S) \ v= IL_EXCHG_ADD ## S (a, v) #define make_atomic_cas_body(S) \ diff --git a/include/lf.h b/include/lf.h index 0976aa4927f..11c06099399 100644 --- a/include/lf.h +++ b/include/lf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 MySQL AB +/* Copyright (C) 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -187,8 +187,8 @@ typedef struct st_lf_allocator { uchar * volatile top; uint element_size; uint32 volatile mallocs; - void (*constructor)(uchar *); - void (*destructor)(uchar *); + void (*constructor)(uchar *); /* called, when an object is malloc()'ed */ + void (*destructor)(uchar *); /* called, when an object is free()'d */ } LF_ALLOCATOR; void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset); @@ -219,7 +219,7 @@ lock_wrap(lf_alloc_new, void *, #define LF_HASH_UNIQUE 1 /* lf_hash overhead per element (that is, sizeof(LF_SLIST) */ -#define LF_HASH_OVERHEAD (sizeof(int*)*4) +extern const int LF_HASH_OVERHEAD; typedef struct { LF_DYNARRAY array; /* hash itself */ diff --git a/include/maria.h b/include/maria.h index 37dbfe6833b..c5bd8641c38 100644 --- a/include/maria.h +++ b/include/maria.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 MySQL AB +/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -33,6 +33,8 @@ extern "C" { #include <myisamchk.h> #include <mysql/plugin.h> +#define MARIA_CANNOT_ROLLBACK + /* Limit max keys according to HA_MAX_POSSIBLE_KEY; See myisamchk.h for details */ diff --git a/include/my_pthread.h b/include/my_pthread.h index 1596495a40f..538457a523a 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -430,19 +430,19 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); /* adapt for two different flavors of struct timespec */ #ifdef HAVE_TIMESPEC_TS_SEC -#define TV_sec ts_sec -#define TV_nsec ts_nsec +#define MY_tv_sec ts_sec +#define MY_tv_nsec ts_nsec #else -#define TV_sec tv_sec -#define TV_nsec tv_nsec +#define MY_tv_sec tv_sec +#define MY_tv_nsec tv_nsec #endif /* HAVE_TIMESPEC_TS_SEC */ #ifndef set_timespec_time_nsec #define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \ ulonglong nsec= (NSEC); \ ulonglong now= (TIME) + (nsec/100); \ - (ABSTIME).TV_sec= (now / ULL(10000000)); \ - (ABSTIME).TV_nsec= (now % ULL(10000000) * 100 + (nsec % 100)); \ + (ABSTIME).MY_tv_sec= (now / ULL(10000000)); \ + (ABSTIME).MY_tv_nsec= (now % ULL(10000000) * 100 + (nsec % 100)); \ } while(0) #endif /* !set_timespec_time_nsec */ diff --git a/include/waiting_threads.h b/include/waiting_threads.h index c4e5b24fe43..45c3b140915 100644 --- a/include/waiting_threads.h +++ b/include/waiting_threads.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 MySQL AB +/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -24,16 +24,18 @@ C_MODE_START typedef struct st_wt_resource_id WT_RESOURCE_ID; +typedef struct st_wt_resource WT_RESOURCE; typedef struct st_wt_resource_type { - int (*compare)(void *a, void *b); - const void *(*make_key)(WT_RESOURCE_ID *id, uint *len); + my_bool (*compare)(const void *a, const void *b); + const void *(*make_key)(const WT_RESOURCE_ID *id, uint *len); /* not used */ } WT_RESOURCE_TYPE; struct st_wt_resource_id { ulonglong value; - WT_RESOURCE_TYPE *type; + const WT_RESOURCE_TYPE *type; }; +/* the below differs from sizeof(WT_RESOURCE_ID) by the amount of padding */ #define sizeof_WT_RESOURCE_ID (sizeof(ulonglong)+sizeof(void*)) #define WT_WAIT_STATS 24 @@ -43,93 +45,17 @@ extern uint32 wt_wait_stats[WT_WAIT_STATS+1]; extern uint32 wt_cycle_stats[2][WT_CYCLE_STATS+1]; extern uint32 wt_success_stats; -/* - 'lock' protects 'owners', 'state', and 'waiter_count' - 'id' is read-only - - a resource is picked up from a hash in a lock-free manner - it's returned pinned, so it cannot be freed at once - but it may be freed right after the pin is removed - to free a resource it should be - 1. have no owners - 2. have no waiters - - two ways to access a resource: - 1. find it in a hash - - it's returned pinned. - a) take a lock in exclusive mode - b) check the state, it should be ACTIVE - c) unpin - 2. by a direct reference - - could only used if a resource cannot be freed - e.g. accessing a resource by thd->waiting_for is safe, - a resource cannot be freed as there's a thread waiting for it -*/ -typedef struct st_wt_resource { - WT_RESOURCE_ID id; - uint waiter_count; - enum { ACTIVE, FREE } state; -#ifndef DBUG_OFF - pthread_mutex_t *mutex; -#endif - /* - before the 'lock' all elements are mutable, after (and including) - - immutable in the sense that lf_hash_insert() won't memcpy() over them. - See wt_init(). - */ -#ifdef WT_RWLOCKS_USE_MUTEXES - /* - we need a special rwlock-like 'lock' to allow readers bypass - waiting writers, otherwise readers can deadlock. For example: - - A waits on resource x, owned by B, B waits on resource y, owned - by A, we have a cycle (A->x->B->y->A) - Both A and B start deadlock detection: - - A locks x B locks y - A goes deeper B goes deeper - A locks y B locks x - - with mutexes it would deadlock. With rwlocks it won't, as long - as both A and B are taking read locks (and they do). - But other threads may take write locks. Assume there's - C who wants to start waiting on x, and D who wants to start - waiting on y. - - A read-locks x B read-locks y - A goes deeper B goes deeper - => C write-locks x (to add a new edge) D write-locks y - .. C is blocked D is blocked - A read-locks y B read-locks x - - Now, if a read lock can bypass a pending wrote lock request, we're fine. - If it can not, we have a deadlock. - - writer starvation is technically possible, but unlikely, because - the contention is expected to be low. - */ - struct { - pthread_cond_t cond; - pthread_mutex_t mutex; - uint readers: 16; - uint pending_writers: 15; - uint write_locked: 1; - } lock; -#else - rw_lock_t lock; -#endif - pthread_cond_t cond; - DYNAMIC_ARRAY owners; -} WT_RESOURCE; - typedef struct st_wt_thd { /* XXX - there's no protection (mutex) against concurrent access of - the dynarray below. it is assumed that a caller will have it - automatically (not to protect this array but to protect its - own - caller's - data structures, and we'll get it for free. - If not, we'll need to add a mutex + there's no protection (mutex) against concurrent access of the + dynarray below. it is assumed that a caller will have it anyway + (not to protect this array but to protect its own - caller's - + data structures), and we'll get it for free. A caller needs to + ensure that a blocker won't release a resource before a blocked + thread starts waiting, which is usually done with a mutex. + + If the above assumption is wrong, we'll need to add a mutex here. */ DYNAMIC_ARRAY my_resources; /* @@ -141,8 +67,10 @@ typedef struct st_wt_thd { LF_PINS *pins; /* pointers to values */ - ulong *timeout_short, *deadlock_search_depth_short; - ulong *timeout_long, *deadlock_search_depth_long; + const ulong *timeout_short; + const ulong *deadlock_search_depth_short; + const ulong *timeout_long; + const ulong *deadlock_search_depth_long; /* weight relates to the desirability of a transaction being killed if it's @@ -169,13 +97,13 @@ typedef struct st_wt_thd { */ ulong volatile weight; /* - 'killed' is indirectly protected by waiting_for->lock - - a killed thread needs to clear its 'waiting_for', and thus needs a lock. + 'killed' is indirectly protected by waiting_for->lock because + a killed thread needs to clear its 'waiting_for' and thus needs a lock. That is a thread needs an exclusive lock to read 'killed' reliably. But other threads may change 'killed' from 0 to 1, a shared lock is enough for that. */ - my_bool volatile killed; + my_bool killed; #ifndef DBUG_OFF const char *name; #endif @@ -189,13 +117,13 @@ typedef struct st_wt_thd { void wt_init(void); void wt_end(void); -void wt_thd_lazy_init(WT_THD *, ulong *, ulong *, ulong *, ulong *); +void wt_thd_lazy_init(WT_THD *, const ulong *, const ulong *, const ulong *, const ulong *); void wt_thd_destroy(WT_THD *); -int wt_thd_will_wait_for(WT_THD *, WT_THD *, WT_RESOURCE_ID *); +int wt_thd_will_wait_for(WT_THD *, WT_THD *, const WT_RESOURCE_ID *); int wt_thd_cond_timedwait(WT_THD *, pthread_mutex_t *); -void wt_thd_release(WT_THD *, WT_RESOURCE_ID *); +void wt_thd_release(WT_THD *, const WT_RESOURCE_ID *); #define wt_thd_release_all(THD) wt_thd_release((THD), 0) -int wt_resource_id_memcmp(void *, void *); +int wt_resource_id_memcmp(const void *, const void *); C_MODE_END |