#ifndef	QUARK_ID_H
#define	QUARK_ID_H

#include <public/quark/types.h>

/* TaskID
 *
 * 31........0
 * Nest(4) | Chief(11) | Site(17)
 * Type(4) | Task(11)  | ver0(10) | Thread(7)
 *                   OR
 * Type(4) | Task(11)  | Port(17)
 */

/* Object Clan Location Identification
 */
#define	QID_NESTSHIFT	(28+32)
#define	QID_NESTMASK	(0xfLL << QID_NESTSHIFT)
#define	QID_CHIEFSHIFT	(17+32)
#define	QID_CHIEFMASK	(0x7ffLL << QID_CHIEFSHIFT)
#define	QID_SITESHIFT	(0+32)
#define	QID_SITEMASK	(0x1ffffLL << QID_SITESHIFT)

#define	QGET_CLAN(x)	(x & 0xffffffff00000000LL)


/* Object Type Identification
 */
#define	QID_TYPESHIFT	(28+0)
#define	QID_TYPEMASK	(0xfLL << QID_TYPESHIFT)

#define	QIDTYPE_THREAD	1LL
#define	QIDTYPE_MSGPORT	2LL

/* Task ID
 */
#define	QID_TASKSHIFT	(17+0)
#define	QID_TASKMASK	(0x7ffLL << QID_TASKSHIFT)

/* ver0(10) | Thread(7)
 * marked as subtype
 */
#define	QID_SUBTYPESHIFT	(0)
#define	QID_SUBTYPEMASK	(0x1ffffLL << QID_SUBTYPESHIFT)

/* Thread Subtype
 */
#define	QID_VERSIONSHIFT	(10+0)
#define	QID_VERSIONMASK	(0x3ffLL << QID_VERSIONSHIFT)
#define	QID_THREADSHIFT	(0+0)
#define	QID_THREADMASK	(0x7fLL << QID_THREADSHIFT)


/* MsgPort SubType
 */
#define	QID_PORTSHIFT	(0)
#define	QID_PORTMASK	(0x1ffffLL << QID_PORTSHIFT)


#define	QID_TASKMAX	2048
#define	QID_THREADMAX	127
#define	QID_PORTMAX	0x1ffff
#define	QID_ILLEGAL	(-1LL)
#define	QID_NULL	(0LL)


#define	QGETID_NEST(x)		((x & QID_NESTMASK) >> QID_NESTSHIFT)
#define	QGETID_CHIEF(x)		((x & QID_CHIEFMASK) >> QID_CHIEFSHIFT)
#define	QGETID_SITE(x)		((x & QID_SITEMASK) >> QID_SITESHIFT)
#define	QGETID_TYPE(x)		((x & QID_TYPEMASK) >> QID_TYPESHIFT)
#define	QGETID_TASK(x)		((x & QID_TASKMASK) >> QID_TASKSHIFT)
#define	QGETID_THREAD(x)	((x & QID_THREADMASK) >> QID_THREADSHIFT)
#define	QGETID_PORT(x)		((x & QID_PORTMASK) >> QID_PORTSHIFT)
#define	QGETID_VER(x)		((x & QID_VERSIONMASK) >> QID_VER0SHIFT)

#define	QSETID_NEST(x)		(x << QID_NESTSHIFT)
#define	QSETID_CHIEF(x)		(x << QID_CHIEFSHIFT)
#define	QSETID_SITE(x)		(x << QID_SITESHIFT)
#define	QSETID_TYPE(x)		(x << QID_TYPESHIFT)
#define	QSETID_TASK(x)		(x << QID_TASKSHIFT)
#define	QSETID_THREAD(x)	(x << QID_THREADSHIFT)
#define	QSETID_PORT(x)		(x << QID_PORTSHIFT)
#define	QSETID_VERSION(x)	(x << QID_VERSIONHIFT)

#define	QPID_CREATE(x)	(QSETID_TYPE( QIDTYPE_THREAD) | QSETID_TASK(x))

#define	QTID_CREATE(x)	QSETID_THREAD(x)

#define	QGET_PID(x)	((q_pid_t) (x & (u_int64_t) ~QID_THREADMASK))


/* x == PortID
 * y == PID/TID
 */
#define	QMID_CREATE(x,y)	(QSETID_TYPE(QIDTYPE_MSGPORT) | QSETID_PORT(x) | (y & (u_int64_t) ~(QID_PORTMASK | QID_TYPEMASK)) )



#define	QPID_SAME(x,y)	((x & (u_int64_t) ~QID_SUBTYPEMASK) == (y & (u_int64_t) ~QID_SUBTYPEMASK))


#define	QGETID_UPPER(x)	(x>>32 & 0xffffffff)
#define	QGETID_LOWER(x)	(x & 0xffffffff)


#endif
