<commit_before>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* 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.
*
* The Original Code is [Open Source Virtual Machine.].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2004-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#include "MMgc.h"

#ifndef TLS_OUT_OF_INDEXES
    #define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
#endif

bool VMPI_tlsCreate(uintptr_t* tlsId)
{
    DWORD id = TlsAlloc();
    *tlsId = (uintptr_t)id;
    return (id != TLS_OUT_OF_INDEXES);
}

void VMPI_tlsDestroy(uintptr_t tlsId)
{
    TlsFree((DWORD)tlsId);
}

bool VMPI_tlsSetValue(uintptr_t tlsId, void* value)
{
    return TlsSetValue((DWORD)tlsId, value) == TRUE;
}

void* VMPI_tlsGetValue(uintptr_t tlsId)
{
    return TlsGetValue((DWORD)tlsId);
}

bool VMPI_threadCreate(vmpi_thread_t* thread, vmpi_thread_attr_t* attr, vmpi_thread_start_t start_fn, vmpi_thread_arg_t arg)
{
    DWORD id;
    SIZE_T stackSize = attr == NULL || attr->stackSize == VMPI_threadAttrDefaultStackSize() ? 0 : attr->stackSize;
    HANDLE threadHandle = CreateThread(NULL, stackSize, start_fn, arg, 0, &id);
    if (threadHandle) {
        *thread = (vmpi_thread_t)id;
        CloseHandle(threadHandle);
        if (attr != NULL && attr->priority != THREAD_PRIORITY_NORMAL) {
            SetThreadPriority(threadHandle, attr->priority);
        }
        // The SetThreadStackGuarantee API is not available in all versions of Windows we care about,
        // so we can't honor any specific guard size request.
        return true;
    } else {
        return false;
    }
}

bool VMPI_threadDetach(vmpi_thread_t thread)
{
    // Not applicable
    (void)thread;
    return true;
}

void VMPI_threadSleep(int32_t timeout_millis)
{
    Sleep(timeout_millis);
}

#ifdef UNDER_CE

void VMPI_threadJoin(vmpi_thread_t thread)
{
    (void)thread;
    AvmAssertMsg(false, "Not supported under CE");
}

void VMPI_condVarWait(vmpi_condvar_t* condvar, vmpi_mutex_t* mutex)
{
    (void)condvar;
    (void)mutex;
    AvmAssertMsg(false, "Not supported under CE");
}

bool VMPI_condVarTimedWait(vmpi_condvar_t* condvar, vmpi_mutex_t* mutex, int32_t timeout_millis)
{
    (void)condvar;
    (void)mutex;
    (void)timeout_millis;
    AvmAssertMsg(false, "Not supported under CE");
    return false;
}

void VMPI_condVarBroadcast(vmpi_condvar_t* condvar)
{
    (void)condvar;
    AvmAssertMsg(false, "Not supported under CE");
}

void VMPI_condVarSignal(vmpi_condvar_t* condvar)
{
    (void)condvar;
    AvmAssertMsg(false, "Not supported under CE");
}

#else

void VMPI_threadJoin(vmpi_thread_t thread)
{
    HANDLE threadHandle = OpenThread(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF, false, (DWORD)thread);
    if (threadHandle) {
        WaitForSingleObject(threadHandle, INFINITE);
        CloseHandle(threadHandle);
    }
}

bool VMPI_condVarTimedWaitInternal(vmpi_condvar_t* condvar, vmpi_mutex_t* mutex, int32_t timeout_millis, bool infinite)
{

    // We use the same emulation technique as FP.
    // Although post-notify scheduling is not exactly fair, the algorithm is simple.
    // If we want something fairer then use <NAME>'s 8a algorithm.

    // Add the calling thread to the condition variable's list of waiting threads.
    // Note that the linked list is implicitly guarded by the mutex paired with the conditional variable.
    WaitingThread thisThread;
    thisThread.threadID = GetCurrentThreadId();
    thisThread.notified = false;
    thisThread.next = NULL;
    if (condvar->head == NULL) {
        condvar->head = &thisThread;
    } else {
        condvar->tail->next = &thisThread;<commit_msg>Bug 618057 - Missing from previous change, remove now unnecessary casts (r=lhansen)<commit_after>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* 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.
*
* The Original Code is [Open Source Virtual Machine.].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2004-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#include "MMgc.h"

#ifndef TLS_OUT_OF_INDEXES
    #define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
#endif

bool VMPI_tlsCreate(uintptr_t* tlsId)
{
    DWORD id = TlsAlloc();
    *tlsId = (uintptr_t)id;
    return (id != TLS_OUT_OF_INDEXES);
}

void VMPI_tlsDestroy(uintptr_t tlsId)
{
    TlsFree((DWORD)tlsId);
}

bool VMPI_tlsSetValue(uintptr_t tlsId, void* value)
{
    return TlsSetValue((DWORD)tlsId, value) == TRUE;
}

void* VMPI_tlsGetValue(uintptr_t tlsId)
{
    return TlsGetValue((DWORD)tlsId);
}

bool VMPI_threadCreate(vmpi_thread_t* thread, vmpi_thread_attr_t* attr, vmpi_thread_start_t start_fn, vmpi_thread_arg_t arg)
{
    DWORD id;
    SIZE_T stackSize = attr == NULL || attr->stackSize == VMPI_threadAttrDefaultStackSize() ? 0 : attr->stackSize;
    HANDLE threadHandle = CreateThread(NULL, stackSize, start_fn, arg, 0, &id);
    if (threadHandle) {
        *thread = id;
        CloseHandle(threadHandle);
        if (attr != NULL && attr->priority != THREAD_PRIORITY_NORMAL) {
            SetThreadPriority(threadHandle, attr->priority);
        }
        // The SetThreadStackGuarantee API is not available in all versions of Windows we care about,
        // so we can't honor any specific guard size request.
        return true;
    } else {
        return false;
    }
}

bool VMPI_threadDetach(vmpi_thread_t thread)
{
    // Not applicable
    (void)thread;
    return true;
}

void VMPI_threadSleep(int32_t timeout_millis)
{
    Sleep(timeout_millis);
}

#ifdef UNDER_CE

void VMPI_threadJoin(vmpi_thread_t thread)
{
    (void)thread;
    AvmAssertMsg(false, "Not supported under CE");
}

void VMPI_condVarWait(vmpi_condvar_t* condvar, vmpi_mutex_t* mutex)
{
    (void)condvar;
    (void)mutex;
    AvmAssertMsg(false, "Not supported under CE");
}

bool VMPI_condVarTimedWait(vmpi_condvar_t* condvar, vmpi_mutex_t* mutex, int32_t timeout_millis)
{
    (void)condvar;
    (void)mutex;
    (void)timeout_millis;
    AvmAssertMsg(false, "Not supported under CE");
    return false;
}

void VMPI_condVarBroadcast(vmpi_condvar_t* condvar)
{
    (void)condvar;
    AvmAssertMsg(false, "Not supported under CE");
}

void VMPI_condVarSignal(vmpi_condvar_t* condvar)
{
    (void)condvar;
    AvmAssertMsg(false, "Not supported under CE");
}

#else

void VMPI_threadJoin(vmpi_thread_t thread)
{
    HANDLE threadHandle = OpenThread(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF, false, thread);
    if (threadHandle) {
        WaitForSingleObject(threadHandle, INFINITE);
        CloseHandle(threadHandle);
    }
}

bool VMPI_condVarTimedWaitInternal(vmpi_condvar_t* condvar, vmpi_mutex_t* mutex, int32_t timeout_millis, bool infinite)
{

    // We use the same emulation technique as FP.
    // Although post-notify scheduling is not exactly fair, the algorithm is simple.
    // If we want something fairer then use <NAME>'s 8a algorithm.

    // Add the calling thread to the condition variable's list of waiting threads.
    // Note that the linked list is implicitly guarded by the mutex paired with the conditional variable.
    WaitingThread thisThread;
    thisThread.threadID = GetCurrentThreadId();
    thisThread.notified = false;
    thisThread.next = NULL;
    if (condvar->head == NULL) {
        condvar->head = &thisThread;
    } else {
        condvar->tail->next = &thisThread;
{'fraction_non_alphanumeric': 0.09314100114635078, 'fraction_numerical': 0.007642338555598013, 'mean_word_length': 3.8715681712424383, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1158457', 'n_tokens_mistral': 3514, 'n_tokens_neox': 3339, 'n_words': 1141}