blob: 2cb7f0a043520dbb90e20afb5c2e0ae2616ed5ef [file] [log] [blame]
/*
* 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.
*/
#include "open/platform_types.h"
#include "open/hythread_ext.h"
#include "port_mutex.h"
#include "port_thread_internal.h"
volatile port_shared_data_t* port_shared_data = NULL;
static port_shared_data_t* g_port_shared_data = NULL;
static port_shared_data_t g_port_shared_data_struct;
#define MEM_PROTECT_SIZE 0x100
#ifdef _EM64T_
#define GUARD_STACK_SIZE (64*1024)
#else /* IA-32 */
#define GUARD_STACK_SIZE (find_guard_page_size())
#endif
static size_t find_guard_page_size()
{
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwPageSize;
}
static int init_psd_structure(port_shared_data_t* data)
{
DWORD key;
if ((key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return -1;
data->tls_key = key;
InitializeCriticalSection(&data->crit_section);
data->foreign_stack_size = 0;
data->guard_page_size = find_guard_page_size();
data->guard_stack_size = GUARD_STACK_SIZE;
data->mem_protect_size = MEM_PROTECT_SIZE;
return 0;
}
__declspec(dllexport) int port_init_shared_data(volatile port_shared_data_t** p_psd)
{
int err = 0;
static CRITICAL_SECTION struct_lock;
static int lock_initialized = 0;
if (*p_psd)
return 0;
if (lock_initialized == 0)
{ /* Probable race condition because of using static flag */
InitializeCriticalSection(&struct_lock);
lock_initialized = 1;
}
EnterCriticalSection(&struct_lock);
/* If another thread had filled the pointer */
if (*p_psd)
{
LeaveCriticalSection(&struct_lock);
return 0;
}
/* If structure is already initialized */
if (!g_port_shared_data)
{
err = init_psd_structure(&g_port_shared_data_struct);
if (err == 0)
g_port_shared_data = &g_port_shared_data_struct;
}
if (g_port_shared_data)
*p_psd = g_port_shared_data;
LeaveCriticalSection(&struct_lock);
return err;
}
int init_port_shared_data()
{
if (port_shared_data)
return 0;
return port_init_shared_data(&port_shared_data);
}