2002-10-25 18:28:17 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Access Method
|
|
|
|
* MODULE: thd_priority.h
|
|
|
|
* DESCRIPTION: Thread priorities scheduler
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* 2002.10.20 Alexander Peshkoff: Created this scheduler, changing
|
|
|
|
* priorities of Win32 threads. to avoid side effects of Windows
|
|
|
|
* native priorities scheduling.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
2003-10-03 03:53:34 +02:00
|
|
|
#ifndef JRD_OS_THD_PRIORITY_H
|
|
|
|
#define JRD_OS_THD_PRIORITY_H
|
2002-10-25 18:28:17 +02:00
|
|
|
|
2002-11-03 17:48:07 +01:00
|
|
|
#ifdef WIN_NT
|
2003-03-01 17:30:55 +01:00
|
|
|
#if defined(SUPERSERVER) && !defined(EMBEDDED)
|
2002-10-25 18:28:17 +02:00
|
|
|
// Comment this definition to build without priority scheduler
|
|
|
|
// OR:
|
|
|
|
// Uncomment this definition to build with priority scheduler
|
2002-11-03 17:48:07 +01:00
|
|
|
#define THREAD_PSCHED
|
2002-10-25 18:28:17 +02:00
|
|
|
#endif
|
2002-10-31 12:26:15 +01:00
|
|
|
#endif
|
2002-10-25 18:28:17 +02:00
|
|
|
|
|
|
|
#ifdef THREAD_PSCHED
|
|
|
|
|
|
|
|
#include "../jrd/thd.h"
|
2003-01-16 18:47:10 +01:00
|
|
|
#include "../common/classes/alloc.h"
|
2002-10-25 18:28:17 +02:00
|
|
|
#include <process.h>
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
// Each thread, issuing THREAD_EXIT / THREAD_ENTER, must
|
|
|
|
// have associated with it THPS class. That is
|
|
|
|
// what thread local storage points to, instead of
|
|
|
|
// struct thdd. We keep pointer to this struct inside this
|
|
|
|
// class.
|
|
|
|
class ThreadPriorityScheduler {
|
|
|
|
private:
|
|
|
|
static MUTX_T mutex; // locks modification of thps chains
|
|
|
|
static MemoryPool * pool; // where we should place our thps
|
|
|
|
static ThreadPriorityScheduler * chain; // where starts thps chain
|
|
|
|
static ThreadPriorityScheduler * news; // where starts new thps chain
|
2003-09-04 23:26:15 +02:00
|
|
|
static bool initialized;
|
2002-10-25 18:28:17 +02:00
|
|
|
static DWORD specific_key; // for thread LS access
|
2003-09-04 23:26:15 +02:00
|
|
|
static bool shutdown; // server shutting down
|
2002-10-25 18:28:17 +02:00
|
|
|
|
|
|
|
ThreadPriorityScheduler * next; // next thread in list
|
|
|
|
union {
|
|
|
|
struct thdd *context; // current context
|
|
|
|
DWORD id; // ID on startup
|
|
|
|
};
|
|
|
|
HANDLE handle; // thread handle for SetPriority
|
|
|
|
USHORT ticks; // ticks left till keepalive verification
|
|
|
|
// use separate bytes for flags in order to guarantee there
|
|
|
|
// modification independence by different threads without
|
|
|
|
// affecting each other
|
|
|
|
UCHAR inside; // executing between ENTER and EXIT
|
|
|
|
UCHAR goneout; // pass through EXIT since last scheduling
|
|
|
|
UCHAR gonein; // pass through ENTER since last scheduling
|
|
|
|
UCHAR flags; // flags that can't be modified concurrently
|
|
|
|
static ThreadPriorityScheduler *Attach(void);
|
|
|
|
static unsigned int __stdcall Scheduler(LPVOID);
|
|
|
|
static ThreadPriorityScheduler *InternalGet(void);
|
|
|
|
public:
|
|
|
|
static void Enter(void);
|
|
|
|
static void Exit(void);
|
|
|
|
static thdd *Get(void);
|
|
|
|
static void Set(thdd *val);
|
2003-09-04 23:26:15 +02:00
|
|
|
static bool Boosted(void);
|
2002-10-25 18:28:17 +02:00
|
|
|
static void Cleanup(void);
|
|
|
|
static void Init(void);
|
|
|
|
static void Attach(HANDLE tHandle, DWORD thread_id, int &p);
|
|
|
|
static void Attach(HANDLE tHandle, DWORD thread_id, UCHAR flags);
|
|
|
|
};
|
|
|
|
|
|
|
|
// thps_flags values
|
|
|
|
#define THPS_PSCHED 1 // thread controlled by priority scheduler
|
|
|
|
#define THPS_UP 2 // candidate for priority boost
|
|
|
|
#define THPS_LOW 4 // candidate for priority decrement
|
|
|
|
#define THPS_BOOSTED 8 // thread controlled by priority scheduler
|
|
|
|
|
|
|
|
#define THPS_ENTER() ThreadPriorityScheduler::Enter()
|
|
|
|
#define THPS_EXIT() ThreadPriorityScheduler::Exit()
|
|
|
|
#define THPS_GET(WhenMissing) ThreadPriorityScheduler::Get()
|
|
|
|
#define THPS_SET(WhenMissing, val) ThreadPriorityScheduler::Set(val)
|
|
|
|
#define THPS_INIT() ThreadPriorityScheduler::Init()
|
|
|
|
#define THPS_FINI() ThreadPriorityScheduler::Cleanup()
|
|
|
|
#define THPS_ATTACH(handle, thread_id, priority) \
|
|
|
|
ThreadPriorityScheduler::Attach(handle, thread_id, priority)
|
2002-11-11 19:09:01 +01:00
|
|
|
#define THPS_BOOSTDONE() ThreadPriorityScheduler::Boosted()
|
2002-10-25 18:28:17 +02:00
|
|
|
|
|
|
|
#else // THREAD_PSCHED
|
|
|
|
|
|
|
|
#define THPS_ENTER()
|
|
|
|
#define THPS_EXIT()
|
|
|
|
#define THPS_GET(WhenMissing) WhenMissing
|
|
|
|
#define THPS_SET(WhenMissing, val) WhenMissing
|
|
|
|
#define THPS_INIT()
|
|
|
|
#define THPS_FINI()
|
|
|
|
#define THPS_ATTACH(handle, thread_id, priority)
|
2003-09-04 23:26:15 +02:00
|
|
|
#define THPS_BOOSTDONE() false
|
2002-10-25 18:28:17 +02:00
|
|
|
|
|
|
|
#endif // THREAD_PSCHED
|
|
|
|
|
2003-10-03 03:53:34 +02:00
|
|
|
#endif // JRD_OS_THD_PRIORITY_H
|