/* * PROGRAM: JRD Access Method * MODULE: thd_priority.h * DESCRIPTION: Thread priorities scheduler - changes * priorities of Win32 threads to avoid side effects * of Windows native priorities scheduling. * * The contents of this file are subject to the Initial * Developer's 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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Alexander Peshkoff * for the Firebird Open Source RDBMS project. * * Copyright (c) 2003 Alexander Peshkoff * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. */ #ifndef _JRD_OS_THD_PRIORITY_H_ #define _JRD_OS_THD_PRIORITY_H_ #ifdef WIN_NT #if defined(SUPERSERVER) && !defined(EMBEDDED) // Comment this definition to build without priority scheduler // OR: // Uncomment this definition to build with priority scheduler #define THREAD_PSCHED #endif #endif #ifdef THREAD_PSCHED #include "../jrd/thd.h" #include "../common/classes/alloc.h" #include #include // 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 static BOOLEAN initialized; static DWORD specific_key; // for thread LS access static BOOLEAN shutdown; // server shutting down 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); static BOOLEAN Boosted(void); 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) #define THPS_BOOSTDONE() ThreadPriorityScheduler::Boosted() #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) #define THPS_BOOSTDONE() FALSE #endif // THREAD_PSCHED #endif // _JRD_OS_THD_PRIORITY_H_