/* Copyright (C) 2009 PrimeBase Technologies GmbH
 *
 * PrimeBase XT
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 *
 * 2009-01-20	Vladimir Kolesnikov
 *
 * H&G2JCtL
 */

#ifndef __xt_locklist_h__
#define __xt_locklist_h__

/*
 * XT_THREAD_LOCK_INFO and DEBUG_LOCKING code must be updated to avoid calls to xt_get_self() as it can be called before hton->slot is
 * assigned by MySQL which is used by xt_get_self()
 */

#ifdef DEBUG
//#define XT_THREAD_LOCK_INFO
#ifndef XT_WIN
/* We need DEBUG_LOCKING in order to enable pthread function wrappers */
//#define DEBUG_LOCKING
#endif
#endif

#include "xt_defs.h"

struct XTThread;
struct XTSpinLock;
struct xt_mutex_struct;
struct xt_rwlock_struct;
struct XTMutexXSLock;
struct XTSpinXSLock;

#ifdef XT_THREAD_LOCK_INFO

#define XT_THREAD_LOCK_INFO_MAX_COUNT 50

#ifdef XT_WIN
#define LOCKLIST_ARG_SUFFIX(name) #name " in " __FUNCTION__ "() at " __FILE__ ":" QUOTE(__LINE__)
#else
#define LOCKLIST_ARG_SUFFIX(name) #name " in " QUOTE(__PRETTY_FUNCTION__) "() at " QUOTE(__FILE__) ":" QUOTE(__LINE__)
#endif

/*
 * An instance of XTThreadLockInfo class keeps information about a lock kept by a thread.
 * There's a list of XTThreadLockInfo instances per thread. An instance can be included
 * into several thread lists in case of shared locks.
 */
typedef struct XTThreadLockInfo {

	enum LockType { SPIN_LOCK, MUTEX, RW_LOCK, FAST_RW_LOCK, SPIN_RW_LOCK };

	LockType		  li_lock_type;

	union {
		XTSpinLock       *li_spin_lock;	  // SPIN_LOCK
		XTMutexXSLock	 *li_fast_rwlock; // FAST_RW_LOCK
		XTSpinXSLock	 *li_spin_rwlock; // SPIN_RW_LOCK
		xt_mutex_struct  *li_mutex;		  // MUTEX
		xt_rwlock_struct *li_rwlock;	  // RW_LOCK
	};
} 
XTThreadLockInfoRec, *XTThreadLockInfoPtr;

void xt_thread_lock_info_init(XTThreadLockInfoPtr ptr, XTSpinLock *lock);
void xt_thread_lock_info_init(XTThreadLockInfoPtr ptr, XTMutexXSLock *lock);
void xt_thread_lock_info_init(XTThreadLockInfoPtr ptr, XTSpinXSLock *lock);
void xt_thread_lock_info_init(XTThreadLockInfoPtr ptr, xt_mutex_struct *lock);
void xt_thread_lock_info_init(XTThreadLockInfoPtr ptr, xt_rwlock_struct *lock);
void xt_thread_lock_info_free(XTThreadLockInfoPtr ptr);

void xt_thread_lock_info_add_owner (XTThreadLockInfoPtr ptr);
void xt_thread_lock_info_release_owner (XTThreadLockInfoPtr ptr);

void xt_trace_thread_locks(XTThread *self);

#endif // XT_THREAD_LOCK_INFO
#endif // __xt_locklist_h__
