1
0
Files
irix-657m-src/eoe/lib/libpthread/inc/q.h
2022-09-29 17:59:04 +03:00

149 lines
3.8 KiB
C

#ifndef _Q_H_
#define _Q_H_
/**************************************************************************
* *
* Copyright (C) 1996 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include "common.h"
#define Q_DECLARE(que) q_t que = { &que, &que }
#define Q_INIT(que) ((que)->next = (que)->prev = que)
#define Q_HEAD(que, typ) Q_NEXT(que, typ)
#define Q_NEXT(que, typ) ((typ)(((q_t *)(que))->next))
#define Q_TAIL(que) ((que)->prev)
#define Q_END(que, elt) ((que) == (q_t *)(elt))
#define Q_EMPTY(que) ((que)->next == (que))
#define Q_ADD_FIRST(que, elt) \
MACRO_BEGIN \
((q_t *)(elt))->next = (que)->next; \
((q_t *)(elt))->prev = (que); \
(que)->next->prev = (q_t *)(elt); \
(que)->next = (q_t *)(elt); \
MACRO_END
#define Q_ADD_LAST(que, elt) \
MACRO_BEGIN \
((q_t *)(elt))->next = (que); \
((q_t *)(elt))->prev = (que)->prev; \
(que)->prev->next = (q_t *)(elt); \
(que)->prev = (q_t *)(elt); \
MACRO_END
#define Q_REM_FIRST(que, elt, typ) \
MACRO_BEGIN \
if ((que)->next == (que)) { \
(elt) = 0; \
} else { \
(elt) = (typ)((que)->next); \
(que)->next = (que)->next->next; \
(que)->next->prev = (que); \
} \
MACRO_END
#define Q_UNLINK(elt) \
MACRO_BEGIN \
q_t *_q = (q_t *)(elt); \
_q->next->prev = _q->prev; \
_q->prev->next = _q->next; \
MACRO_END
#define Q_INSERT_TAIL(que, elt, type, fld) \
MACRO_BEGIN \
q_t *_prev; \
\
for (_prev = (que)->prev; \
_prev != (que) && ((type*)_prev)->fld < (elt)->fld;\
_prev = _prev->prev) { \
} \
Q_ADD_FIRST(_prev, elt); \
MACRO_END
#define Q_INSERT_HEAD(que, elt, type, fld) \
MACRO_BEGIN \
q_t *_next; \
\
for (_next = (que)->next; \
_next != (que) && ((type*)_next)->fld > (elt)->fld;\
_next = _next->next) { \
} \
Q_ADD_LAST(_next, elt); \
MACRO_END
#define Q_PRINT(que) do { \
MACRO_BEGIN \
q_t *_q = (&(que))->next; \
dbg_printf("%s:\n", #que); \
dbg_printf("\t0x%x: 0x%x, 0x%x\n", \
&que, (&(que))->next, (&(que))->prev); \
while (_q != &(que)) { \
dbg_printf("\t0x%x: 0x%x, 0x%x\n", \
_q, _q->next, _q->prev); \
_q = _q->next; \
} \
MACRO_END
typedef struct q {
struct q *next;
struct q *prev;
} q_t;
/* Singly linked queues.
*
* These lists do not require locks but should be only used when
* the caller cannot be preempted as they spin to resolve collisions.
*/
#define QS_DECLARE(qs) qs_t * volatile qs
#define QS_INIT(que) (*(que) = 0)
#define QS_BUSY ((qs_t *)1uL)
#define QS_ADD_FIRST(head, elt) \
MACRO_BEGIN \
ASSERT(sched_entered()); \
for (;;) { \
((qs_t *)(elt))->qs_next = *(head); \
if (((qs_t *)(elt))->qs_next != QS_BUSY \
&& cmp_and_swap((void *)head, \
((qs_t *)(elt))->qs_next, elt)) { \
break; \
} \
} \
MACRO_END
#define QS_REM_FIRST(head, elt, typ) \
MACRO_BEGIN \
ASSERT(sched_entered()); \
for (;;) { \
if (!(elt = (typ)*(head))) { \
break; \
} \
if (elt != (typ)QS_BUSY \
&& cmp_and_swap((void *)head, elt, QS_BUSY)) { \
*(head) = ((qs_t *)(elt))->qs_next; \
break; \
} \
} \
MACRO_END
typedef struct qs {
struct qs *qs_next;
} qs_t;
#endif /* !_Q_H_ */