403 lines
10 KiB
C
403 lines
10 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) module
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
|
|
|
| $Author: taysom $
|
|
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
|
|
|
|
| $RCSfile$
|
|
| $Revision: 465 $
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
| This module is used to:
|
|
| NSS Library source
|
|
|
|
|
| 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 _SCHEDULE_H_
|
|
#define _SCHEDULE_H_
|
|
|
|
#if zLINUX
|
|
#include "linuxmpk.h"
|
|
#endif
|
|
|
|
#ifndef _ZOMNI_H_
|
|
# include <zOmni.h>
|
|
#endif
|
|
|
|
#ifndef _PSSDEBUG_H_
|
|
# include <pssDebug.h>
|
|
#endif
|
|
|
|
#ifndef _INST_H_
|
|
# include <inst.h>
|
|
#endif
|
|
|
|
#ifndef _PSSMPK_H_
|
|
# include <pssmpk.h>
|
|
#endif
|
|
|
|
#ifndef _NSSOSAPIS_H_
|
|
# include <nssOSAPIs.h>
|
|
#endif
|
|
|
|
#ifndef _INLINES_H_
|
|
# include <inlines.h>
|
|
#endif
|
|
|
|
#ifndef _QUE_H_
|
|
#include <que.h>
|
|
#endif
|
|
|
|
#ifndef _OSMPKHDRS_H_
|
|
#include <osmpkhdrs.h>
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Pre-define struct(s) so Linux compiler doesn't complain */
|
|
struct WorkToDoStructure;
|
|
|
|
/*- AES structure defines -*/
|
|
#define AESNOTINUSE 0
|
|
#define AESBEINGUSED 1
|
|
|
|
/*- thread priority -*/
|
|
#define THREAD_HIGH 0
|
|
#define THREAD_MED 1
|
|
#define THREAD_LOW 2
|
|
|
|
|
|
/*- this structure is the same size as AESProcessStructure in aesproc.h -*/
|
|
typedef struct zAESP_s
|
|
{
|
|
LONG osReserved0; /* set NULL by user */
|
|
LONG timeDelay; /* always set by user */
|
|
LONG osReserved1; /* set NULL by user */
|
|
voidfunc_t ProcedureToCall; /* always set by user */
|
|
struct ResourceTagStructure *AESResourceTag; /* always set by user */
|
|
LONG osReserved2; /* set NULL by user */
|
|
} zAESP_s;
|
|
|
|
/*- this structure is only used in the do it yourself AES Process -*/
|
|
typedef struct zAESProc_s
|
|
{
|
|
zAESP_s zaesp;
|
|
LONG inUseFlag;
|
|
void *info;
|
|
} zAESProc_s;
|
|
|
|
extern CIRhead_t QueuedThreads;
|
|
extern CIRhead_t QueuedThreadsHigh;
|
|
extern BOOL waitForWorkHigh(void);
|
|
extern BOOL waitForWork(void);
|
|
|
|
typedef struct ThreadsQueue_s
|
|
{
|
|
CIRlink_t nextThread;
|
|
ADDR threadID;
|
|
} ThreadsQueue_s;
|
|
|
|
/*
|
|
* library prototypes
|
|
*/
|
|
extern void LB_delay(
|
|
NINT millisec);
|
|
|
|
|
|
/*
|
|
* Work To Do Scheduling routines
|
|
*/
|
|
extern void fillInWork(
|
|
void *process,
|
|
voidfunc_t procedureToCall,
|
|
void *userParameter);
|
|
|
|
/*
|
|
* Async Event Scheduling routines
|
|
*/
|
|
extern LONG makeAESP(
|
|
voidfunc_t procedureToCall,
|
|
LONG delayTime,
|
|
void *userParameter);
|
|
|
|
/*- Process Thread routines -*/
|
|
extern STATUS InitThreadProcess();
|
|
|
|
extern void UninitThreadProcess();
|
|
|
|
extern STATUS CreateThread(
|
|
voidfunc_t ExecuteRoutine,
|
|
char *threadName,
|
|
LONG priority,
|
|
LONG *retThreadID);
|
|
|
|
extern STATUS DestroyThread(
|
|
LONG threadID);
|
|
|
|
/* MP APIs*/
|
|
extern ERROR kDestroyThread(THREAD ThreadHandle);
|
|
|
|
extern THREAD kCurrentThread(void);
|
|
extern ERROR kDelayThread(unsigned int);
|
|
|
|
#define ThreadId() (ADDR)kCurrentThread()
|
|
|
|
extern ERROR kWakeUp(THREAD);
|
|
extern void kSleep();
|
|
extern void kYieldThread();
|
|
|
|
/*
|
|
* Routines that are in NetWare that we are calling directly to get the
|
|
* desired functionality.
|
|
*/
|
|
extern LONG GetRunningProcess(void);
|
|
extern void CDestroyProcess(LONG processID);
|
|
extern LONG CMakeProcess(
|
|
LONG schedulingPriority,
|
|
void (*codeAddress)(void),
|
|
void *stackTopAddress,
|
|
LONG stackLength,
|
|
BYTE *processName,
|
|
struct ResourceTagStructure *RTag); /* ProcessSignature */
|
|
|
|
/*
|
|
* Function prototypes for NetWare interfaces
|
|
*/
|
|
extern void CSleepUntilInterrupt(void);
|
|
extern void CRescheduleFromInterrupt(LONG processID);
|
|
extern void CYieldIfNeeded(void);
|
|
extern void CYieldUntilIdle(void);
|
|
|
|
|
|
#define Wait() \
|
|
{ \
|
|
DEBUG_PRINTF(TYIELDS,DBG_BOTH_NOINDENT, \
|
|
(LRED, "Thread Waiting(%08x):%s\n", ThreadId(), WHERE)); \
|
|
ZOS_Sleep(); \
|
|
DEBUG_PRINTF(TYIELDS,DBG_BOTH_NOINDENT, \
|
|
(LRED, "Returning from WAIT(%08x):%s\n", ThreadId(), WHERE)); \
|
|
}
|
|
|
|
#define Continue(pid) \
|
|
{ \
|
|
DEBUG_PRINTF(TYIELDS,DBG_BOTH_NOINDENT, \
|
|
(LRED, "Waking Thread(%08x):%s\n", pid, WHERE)); \
|
|
ZOS_WakeUp((THREAD)pid); \
|
|
}
|
|
|
|
|
|
#define Yield() \
|
|
{ \
|
|
DEBUG_PRINTF(TYIELDS,DBG_BOTH_NOINDENT, \
|
|
(LRED, "Yielding Thread(%08x):%s\n", ThreadId(), WHERE)); \
|
|
ZOS_YieldThread(); \
|
|
DEBUG_PRINTF(TYIELDS, DBG_BOTH_NOINDENT, \
|
|
(LRED, "Returning from YIELD(%08x):%s\n", ThreadId(), WHERE)); \
|
|
}
|
|
|
|
#ifdef __linux__
|
|
# define EnableInts() sti()
|
|
#else
|
|
void EnableInts(void);
|
|
#pragma aux EnableInts = \
|
|
"sti" \
|
|
modify exact [];
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* To allow other threads to run, we have to yield periodically in the
|
|
* the code. PERIODIC_YIELD checks if we should do a periodic yield.
|
|
*/
|
|
|
|
extern LONG TimeToYield;
|
|
|
|
#if zLINUX
|
|
|
|
#define PERIODIC_YIELD_COUNT 50
|
|
|
|
extern BOOL gYieldJiffy;
|
|
extern LONG gYieldCount;
|
|
extern LONG gYieldPeriodicCount;
|
|
|
|
#define PERIODIC_YIELD() \
|
|
if (TimeToYield != jiffies) \
|
|
{ \
|
|
TimeToYield = jiffies; \
|
|
if (gYieldJiffy) \
|
|
{ \
|
|
Yield(); \
|
|
} \
|
|
else if (gYieldCount++ == gYieldPeriodicCount) \
|
|
{ \
|
|
gYieldCount=0; \
|
|
Yield(); \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
#if zNETWARE
|
|
extern LONG CurrentTime;
|
|
|
|
#define PERIODIC_YIELD() \
|
|
if (TimeToYield != CurrentTime) \
|
|
{ \
|
|
TimeToYield = CurrentTime; \
|
|
Yield(); \
|
|
}
|
|
|
|
#endif
|
|
/*
|
|
* Snooze routines for letting threads sleep on a queue and then
|
|
* rousting them (scheduling) them all at the same time.
|
|
*/
|
|
|
|
STATUS snoozeSec(DQhead_t *list, NINT seconds);
|
|
void roust(DQhead_t *list, STATUS status);
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* This is the internal support definitions for NetWare WorkToDo routines.
|
|
* IMPORTANT NOTE: normally in NSS you should NOT be using this workToDo
|
|
* code. You should call WORK_Schedule (defined in
|
|
* xCache.h).
|
|
*-------------------------------------------------------------------------*/
|
|
/*- this structure is the same size as WorkToDoStructure in thread.h -*/
|
|
typedef struct zWork_s
|
|
{
|
|
LONG osReserved; /* set NULL by user */
|
|
voidfunc_t ProcedureToCall; /* always set by user */
|
|
struct ResourceTagStructure *WorkResourceTag; /* always set by user */
|
|
LONG reserved[2]; /* set NULL by user */
|
|
} zWork_s;
|
|
|
|
/*- this structure is only used in the do it yourself work to do -*/
|
|
typedef struct zWorkProc_s
|
|
{
|
|
struct zWork_s zwork;
|
|
void *info;
|
|
} zWorkProc_s;
|
|
|
|
typedef struct zWorkProc2_s
|
|
{
|
|
struct zWork_s zwork;
|
|
void *info;
|
|
void *info2;
|
|
} zWorkProc2_s;
|
|
|
|
|
|
#if MPK_REAL IS_ENABLED
|
|
#define WORK_PROCESS_INIT()
|
|
#else
|
|
#define WORK_PROCESS_INIT() Enable()
|
|
#endif
|
|
|
|
/**************************************************************************
|
|
*
|
|
*
|
|
* Abhijit
|
|
*
|
|
* MPK changes 6th Oct 1998
|
|
*
|
|
*
|
|
* Following are the changes to the library schedule routines which
|
|
* has been made to be compatible with the MPK APIS which are SMP
|
|
* aware.
|
|
*
|
|
* These APIS are to be added to the .imp file and put in the
|
|
* Modules.bld file
|
|
*
|
|
* The header files MPKAPIS.h, MPKLIB.h, MPKtypes.h, MPKOSLIB.h
|
|
* are to be included in the include search path in our environment
|
|
*
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
extern ERROR kScheduleWorkToDo(struct WorkToDoStructure *);
|
|
extern ERROR kScheduleFastWorkTo(struct WorkToDoStructure *);
|
|
extern ERROR kCancelWorkToDo(struct WorkToDoStructure *);
|
|
|
|
|
|
#define ScheduleWork(_work) \
|
|
ZOS_ScheduleWorkToDo((struct WorkToDoStructure *)_work)
|
|
|
|
#define ScheduleFastWork(_work) \
|
|
ZOS_ScheduleFastWorkToDo((struct WorkToDoStructure *)_work,1)
|
|
|
|
#define CancelWork(_work) \
|
|
ZOS_CancelWorkToDo((struct WorkToDoStructure *)_work)
|
|
|
|
|
|
/* When you use the CHECK macros uncomment the SIGNAL macros from the
|
|
* WORK_Run code
|
|
*/
|
|
#define CHECK_AND_WAIT_FOR_HIGH_WORK() \
|
|
((void)((WorkHighWaitingCount >= Config.work.waitingHigh) && waitForWorkHigh()))
|
|
|
|
#define CHECK_AND_WAIT_FOR_WORK() \
|
|
((void)((WorkWaitingCount >= Config.work.waiting) && waitForWork()))
|
|
|
|
#define SIGNAL_NEXT_THREAD() \
|
|
{ \
|
|
ThreadsQueue_s *_queue; \
|
|
if (WorkWaitingCount < (Config.work.waiting >> 1)) \
|
|
{ \
|
|
if (CIR_NOT_EMPTY(QueuedThreads)) \
|
|
{ \
|
|
CIR_DEQ_NO_CHECK(QueuedThreads, _queue, ThreadsQueue_s, \
|
|
nextThread); \
|
|
Continue(_queue->threadID); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define SIGNAL_NEXT_THREAD_HIGH() \
|
|
{ \
|
|
ThreadsQueue_s *_queue; \
|
|
if (WorkHighWaitingCount < (Config.work.waitingHigh >> 1)) \
|
|
{ \
|
|
if (CIR_NOT_EMPTY(QueuedThreadsHigh)) \
|
|
{ \
|
|
CIR_DEQ_NO_CHECK(QueuedThreadsHigh, _queue, ThreadsQueue_s, \
|
|
nextThread); \
|
|
Continue(_queue->threadID); \
|
|
} \
|
|
} \
|
|
}
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _SCHEDULE_H_ */
|