blob: 90990bc0b7fc04fd8dfdc6217fc0aec9bbd32194 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @file
* @ingroup Thread
*/
#include <windows.h>
#include <stdlib.h>
#include "hycomp.h"
#include "hymutex.h"
#define CDEV_CURRENT_FUNCTION ostypes
/* ostypes */
typedef HANDLE OSTHREAD;
typedef DWORD TLSKEY;
typedef HANDLE COND;
#define WRAPPER_TYPE void _cdecl
typedef void *WRAPPER_ARG;
#define WRAPPER_RETURN() return
typedef HANDLE OSSEMAPHORE;
#undef CDEV_CURRENT_FUNCTION
#include "thrtypes.h"
#include "thrdsup.h"
const int priority_map[] = HY_PRIORITY_MAP;
/* Unused ID variable. */
DWORD unusedThreadID;
HyThreadLibrary default_library;
extern void VMCALL hythread_init (HyThreadLibrary * lib);
extern void VMCALL hythread_shutdown (void);
extern void fixupLocks386 (void);
#define CDEV_CURRENT_FUNCTION _prototypes_private
static BOOL WINAPI yield PROTOTYPE ((void));
#if (!defined(HYVM_STATIC_LINKAGE))
BOOL APIENTRY DllMain
PROTOTYPE ((HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved));
#endif /* !HYVM_STATIC_LINKAGE */
#undef CDEV_CURRENT_FUNCTION
BOOL (WINAPI * f_yield) (void);
#define CDEV_CURRENT_FUNCTION yield
static BOOL WINAPI
yield (void)
{
Sleep (1);
return 0;
}
#undef CDEV_CURRENT_FUNCTION
#define CDEV_CURRENT_FUNCTION DllMain
#if (!defined(HYVM_STATIC_LINKAGE))
/*
* Initialize OS-specific threading helpers.
*
* @param hModule handle to module being loaded
* @param ul_reason_for_call reason why DllMain being called
* @param lpReserved reserved
* @return TRUE on success, FALSE on failure.
*/
BOOL APIENTRY
DllMain (HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hythread_library_t lib = GLOBAL_DATA (default_library);
hythread_init (lib);
if (lib->initStatus == 1)
{
OSVERSIONINFO versionInfo;
fixupLocks386 ();
/* SwitchToThread is not implemented on Win98 */
versionInfo.dwOSVersionInfoSize = sizeof (versionInfo);
if (GetVersionEx (&versionInfo))
{
if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
HMODULE kernel32 = GetModuleHandle ("kernel32");
if (kernel32 != NULL)
{
f_yield =
(BOOL (WINAPI *) (void)) GetProcAddress (kernel32,
"SwitchToThread");
}
}
}
if (f_yield == NULL)
f_yield = yield;
}
return lib->initStatus == 1;
}
case DLL_PROCESS_DETACH:
hythread_shutdown ();
}
return TRUE;
}
#endif /* !HYVM_STATIC_LINKAGE */
#undef CDEV_CURRENT_FUNCTION
#define CDEV_CURRENT_FUNCTION init_thread_library
#if (defined(HYVM_STATIC_LINKAGE))
/**
* Perform OS-specific initializations for the threading library.
*
* @return 0 on success or non-zero value on failure.
*/
IDATA
init_thread_library (void)
{
hythread_library_t lib = GLOBAL_DATA (default_library);
if (lib->initStatus == 0)
{
HANDLE mutex = CreateMutex (NULL, TRUE, "hythread_init_mutex");
if (mutex == NULL)
return -1;
if (lib->initStatus == 0)
{
hythread_init (lib);
if (lib->initStatus == 1)
{
atexit (hythread_shutdown);
}
}
ReleaseMutex (mutex);
CloseHandle (mutex);
if (lib->initStatus == 1)
{
OSVERSIONINFO versionInfo;
fixupLocks386 ();
/* SwitchToThread is not implemented on Win98 */
versionInfo.dwOSVersionInfoSize = sizeof (versionInfo);
if (GetVersionEx (&versionInfo))
{
if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
HMODULE kernel32 = GetModuleHandle ("kernel32");
if (kernel32 != NULL)
{
f_yield =
(BOOL (WINAPI *) (void)) GetProcAddress (kernel32,
"SwitchToThread");
}
}
}
if (f_yield == NULL)
f_yield = yield;
}
}
return lib->initStatus != 1;
}
#endif /* HYVM_STATIC_LINKAGE */
#undef CDEV_CURRENT_FUNCTION
#define CDEV_CURRENT_FUNCTION initialize_thread_priority
/**
* Initialize a thread's priority.
*
* Here the threading library priority value is converted to the appropriate
* OS-specific value.
*
* @param[in] thread a thread
* @return none
*/
void
initialize_thread_priority (hythread_t thread)
{
IDATA priority, i;
thread->priority = HYTHREAD_PRIORITY_NORMAL;
if (priority_map[HYTHREAD_PRIORITY_MIN] ==
priority_map[HYTHREAD_PRIORITY_MAX])
return;
priority = GetThreadPriority (thread->handle);
/* are priorities mapped backwards? (WinCE does this.) */
if (THREAD_PRIORITY_IDLE > THREAD_PRIORITY_TIME_CRITICAL)
{
for (i = HYTHREAD_PRIORITY_MAX; i >= HYTHREAD_PRIORITY_MIN; i--)
{
if (priority <= priority_map[i])
{
thread->priority = i;
return;
}
}
}
else
{
for (i = HYTHREAD_PRIORITY_MIN; i <= HYTHREAD_PRIORITY_MAX; i++)
{
if (priority <= priority_map[i])
{
thread->priority = i;
return;
}
}
}
}
#undef CDEV_CURRENT_FUNCTION