236 lines
6.8 KiB
C
236 lines
6.8 KiB
C
/****************************************************************************
|
|
|
|
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
|
|
| All Rights Reserved.
|
|
|
|
|
| This program is free software; you can redistribute it and/or
|
|
| modify it under the terms of version 2 of the GNU General Public
|
|
| License as published by the Free Software Foundation.
|
|
|
|
|
| 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, contact Novell, Inc.
|
|
|
|
|
| To contact Novell about this file by physical or electronic mail,
|
|
| you may find current contact information at www.novell.com
|
|
|
|
|
|***************************************************************************
|
|
|
|
|
| NetWare Advance File Services (NSS) Initialization module
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
|
|
|
| $Author: taysom $
|
|
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
|
|
|
|
| $RCSfile$
|
|
| $Revision: 465 $
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
| This module is used to:
|
|
| Defines and macros for mailbox protocol
|
|
|
|
|
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
|
|
|
|
| This header file should ONLY be used for NSS internal development.
|
|
| This includes Semantic Agents (SA) and Loadable Storage Services (LSS).
|
|
| Any other use may cause conflicts which NSS will NOT fix.
|
|
+-------------------------------------------------------------------------*/
|
|
#ifndef _MAILBOX_H_
|
|
#define _MAILBOX_H_
|
|
|
|
#ifndef _OMNI_H_
|
|
# include <omni.h>
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
* An implementation of the mailbox protocol for solving the single
|
|
* reader/writer problem. Assumes the memory for mailbox is dynamically
|
|
* allocated though static data can be used, it is not optimized for
|
|
* that.
|
|
*
|
|
* INVARIANTS:
|
|
* 1. A full mailbox, always has one free entry.
|
|
* 2. The give always points to a free entry.
|
|
* 3. The give is not advanced until the entry have been filled.
|
|
*
|
|
*
|
|
* start, end, take, and give could be integers used to index an array
|
|
* instead of pointers.
|
|
*
|
|
* MB_INIT Initialize mailbox
|
|
* MB_EMPTY Mailbox is empty
|
|
* MB_NOT_EMPTY Mailbox is not empty
|
|
* MB_FULL Mailboxes can be full.
|
|
* MB_ENQ Place an item in a mailbox slot
|
|
* MB_CHANGE Tests if mailbox went from empty to nont empty after
|
|
* somthing was placed in it.
|
|
* MB_GRAB Grabs the next slot in the mail box so we can fill it in
|
|
* returns NULL if fails
|
|
* MB_POKE Updates pointers for a slot previously GRABbed (Assumes Safe)
|
|
* MB_DEQ Take next item from mailbox. Preservse FIFO ordering.
|
|
* MB_PEEK Peek next item in mailbox. Return NULL on failure.
|
|
* MB_DROP Drop next item from mailbox. (Assumes safe)
|
|
*/
|
|
|
|
#define MBOX_FULL -1
|
|
#define MBOX_EMPTY -2
|
|
|
|
typedef struct Mailbox_s
|
|
{
|
|
void *start; /* Start of memory for mail box */
|
|
void *end; /* End of memory for mail box (points to first
|
|
* location beyond end of memory).
|
|
*/
|
|
void volatile *give; /* Data itemes are added at this end */
|
|
void volatile *take; /* Data items are taken from this end */
|
|
#if NSS_DEBUG IS_ENABLED
|
|
SLONG high; /* High water mark */
|
|
#endif
|
|
} Mailbox_s;
|
|
|
|
extern void mbInit(Mailbox_s *mbox, void *start, void *end);
|
|
|
|
#define MB_INIT(_mb, _start, _end) mbInit((_mb), (_start), (_end))
|
|
|
|
#define MB_EMPTY(_mb) ((_mb)->take == (_mb)->give)
|
|
#define MB_NOT_EMPTY(_mb) ((_mb)->take != (_mb)->give)
|
|
#define MB_FULL(_mb, _type) \
|
|
( \
|
|
(((ADDR)(_mb)->give + sizeof(_type)) == ((ADDR)(_mb)->end)) \
|
|
? ((_mb)->take == (_mb)->start) \
|
|
: ((_mb)->take == (void *)((ADDR)(_mb)->give + sizeof(_type))) \
|
|
)
|
|
|
|
extern void mbSetHigh(Mailbox_s *);
|
|
#if NSS_DEBUG IS_ENABLED
|
|
#define SET_HIGH(_m) mbSetHigh(_m)
|
|
#else
|
|
#define SET_HIGH(_m) ((void)0)
|
|
#endif
|
|
|
|
#define MB_ENQ(_mb, _status, _item, _type) \
|
|
{ \
|
|
Mailbox_s *_mbox = (_mb); \
|
|
_type *_next; \
|
|
\
|
|
_next = _mbox->give; \
|
|
*_next = (_item); \
|
|
++_next; \
|
|
if (_next == _mbox->end) \
|
|
{ \
|
|
_next = _mbox->start; \
|
|
} \
|
|
if (_next == _mbox->take) \
|
|
{ \
|
|
_status = MBOX_FULL; \
|
|
} \
|
|
else \
|
|
{ \
|
|
_mbox->give = _next; \
|
|
_status = zOK; \
|
|
SET_HIGH(_mbox); \
|
|
} \
|
|
}
|
|
|
|
#define MB_NEXT(_mb, _item, _type) \
|
|
{ \
|
|
Mailbox_s *_mbox = (_mb); \
|
|
_type volatile *_next; \
|
|
\
|
|
_next = _mbox->give; \
|
|
_item = (_type *)_next; \
|
|
++_next; \
|
|
if (_next == _mbox->end) \
|
|
{ \
|
|
_next = _mbox->start; \
|
|
} \
|
|
if (_next == _mbox->take) \
|
|
{ \
|
|
_item = NULL; \
|
|
} \
|
|
}
|
|
|
|
#define MB_GIVE(_mb, _type) \
|
|
{ \
|
|
Mailbox_s *_mbox = (_mb); \
|
|
_type volatile *_next; \
|
|
\
|
|
_next = _mbox->give; \
|
|
++_next; \
|
|
if (_next == _mbox->end) \
|
|
{ \
|
|
_next = _mbox->start; \
|
|
} \
|
|
zASSERT(_next != _mbox->take); \
|
|
_mbox->give = _next; \
|
|
SET_HIGH(_mbox); \
|
|
}
|
|
|
|
#define MB_DEQ(_mb, _status, _item, _type) \
|
|
{ \
|
|
Mailbox_s *_mbox = (_mb); \
|
|
_type *_next; \
|
|
\
|
|
_next = _mbox->take; \
|
|
if (_next == _mbox->give) \
|
|
{ \
|
|
_status = MBOX_EMPTY; \
|
|
} \
|
|
else \
|
|
{ \
|
|
_item = *_next; \
|
|
++_next; \
|
|
if (_next == _mbox->end) \
|
|
{ \
|
|
_next = _mbox->start; \
|
|
} \
|
|
_mbox->take = _next; \
|
|
_status = zOK; \
|
|
} \
|
|
}
|
|
|
|
#define MB_PEEK(_mb, _item, _type) \
|
|
{ \
|
|
Mailbox_s *_mbox = (_mb); \
|
|
_type volatile *_next; \
|
|
\
|
|
_next = _mbox->take; \
|
|
if (_next == _mbox->give) \
|
|
{ \
|
|
_item = NULL; \
|
|
} \
|
|
else \
|
|
{ \
|
|
_item = (_type *)_next; \
|
|
} \
|
|
}
|
|
|
|
#define MB_DROP(_mb, _type) \
|
|
{ \
|
|
Mailbox_s *_mbox = (_mb); \
|
|
_type volatile *_next; \
|
|
\
|
|
_next = _mbox->take; \
|
|
++_next; \
|
|
if (_next == _mbox->end) \
|
|
{ \
|
|
_next = _mbox->start; \
|
|
} \
|
|
_mbox->take = _next; \
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|