Changeset 39708 in webkit


Ignore:
Timestamp:
Jan 8, 2009 8:47:14 AM (15 years ago)
Author:
ap@webkit.org
Message:

2009-01-08 Jian Li <jianli@chromium.org>

Reviewed by Alexey Proskuryakov.

Add Win32 implementation of ThreadSpecific.
https://bugs.webkit.org/show_bug.cgi?id=22614

  • JavaScriptCore.vcproj/WTF/WTF.vcproj:
  • wtf/ThreadSpecific.h: (WTF::ThreadSpecific::ThreadSpecific): (WTF::ThreadSpecific::~ThreadSpecific): (WTF::ThreadSpecific::get): (WTF::ThreadSpecific::set): (WTF::ThreadSpecific::destroy):
  • wtf/ThreadSpecificWin.cpp: Added. (WTF::ThreadSpecificThreadExit):
  • wtf/ThreadingWin.cpp: (WTF::wtfThreadEntryPoint):
Location:
trunk/JavaScriptCore
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r39707 r39708  
     12009-01-08  Jian Li  <jianli@chromium.org>
     2
     3        Reviewed by Alexey Proskuryakov.
     4
     5        Add Win32 implementation of ThreadSpecific.
     6        https://bugs.webkit.org/show_bug.cgi?id=22614
     7
     8        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
     9        * wtf/ThreadSpecific.h:
     10        (WTF::ThreadSpecific::ThreadSpecific):
     11        (WTF::ThreadSpecific::~ThreadSpecific):
     12        (WTF::ThreadSpecific::get):
     13        (WTF::ThreadSpecific::set):
     14        (WTF::ThreadSpecific::destroy):
     15        * wtf/ThreadSpecificWin.cpp: Added.
     16        (WTF::ThreadSpecificThreadExit):
     17        * wtf/ThreadingWin.cpp:
     18        (WTF::wtfThreadEntryPoint):
     19
    1202009-01-08  Justin McPherson <justin.mcpherson@nokia.com>
    221
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj

    r39487 r39708  
    1 <?xml version="1.0" encoding="Windows-1252"?>
     1<?xml version="1.0" encoding="windows-1251"?>
    22<VisualStudioProject
    33        ProjectType="Visual C++"
    4         Version="8.00"
     4        Version="8,00"
    55        Name="WTF"
    66        ProjectGUID="{AA8A5A85-592B-4357-BC60-E0E91E026AF6}"
     
    420420                </File>
    421421                <File
     422                        RelativePath="..\..\wtf\Threading.cpp"
     423                        >
     424                </File>
     425                <File
    422426                        RelativePath="..\..\wtf\Threading.h"
    423427                        >
    424428                </File>
    425429                <File
    426                         RelativePath="..\..\wtf\Threading.cpp"
    427                         >
    428                 </File>
    429                 <File
    430430                        RelativePath="..\..\wtf\ThreadingWin.cpp"
    431431                        >
     
    433433                <File
    434434                        RelativePath="..\..\wtf\ThreadSpecific.h"
     435                        >
     436                </File>
     437                <File
     438                        RelativePath="..\..\wtf\ThreadSpecificWin.cpp"
    435439                        >
    436440                </File>
  • trunk/JavaScriptCore/wtf/ThreadSpecific.h

    r39672 r39708  
    11/*
    22 * Copyright (C) 2008 Apple Inc. All rights reserved.
     3 * Copyright (C) 2009 Jian Li <jianli@chromium.org>
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2728 */
    2829
     30/* Thread local storage is implemented by using either pthread API or Windows
     31 * native API. There is subtle semantic discrepancy for the cleanup function
     32 * implementation as noted below:
     33 *   @ In pthread implementation, the destructor function will be called
     34 *     repeatedly if there is still non-NULL value associated with the function.
     35 *   @ In Windows native implementation, the destructor function will be called
     36 *     only once.
     37 * This semantic discrepancy does not impose any problem because nowhere in
     38 * WebKit the repeated call bahavior is utilized.
     39 */
     40
    2941#ifndef WTF_ThreadSpecific_h
    3042#define WTF_ThreadSpecific_h
     
    3244#include <wtf/Noncopyable.h>
    3345
    34 #if USE(PTHREADS) || PLATFORM(WIN)
    35 // Windows currently doesn't use pthreads for basic threading, but implementing destructor functions is easier
    36 // with pthreads, so we use it here.
     46#if USE(PTHREADS)
    3747#include <pthread.h>
     48#elif PLATFORM(WIN_OS)
     49#include <windows.h>
    3850#endif
    3951
    4052namespace WTF {
     53
     54#if !USE(PTHREADS) && PLATFORM(WIN_OS)
     55// ThreadSpecificThreadExit should be called each time when a thread is detached.
     56// This is done automatically for threads created with WTF::createThread.
     57void ThreadSpecificThreadExit();
     58#endif
    4159
    4260template<typename T> class ThreadSpecific : Noncopyable {
     
    4967
    5068private:
     69#if !USE(PTHREADS) && PLATFORM(WIN_OS)
     70    friend void ThreadSpecificThreadExit();
     71#endif
     72   
    5173    T* get();
    5274    void set(T*);
    5375    void static destroy(void* ptr);
    5476
    55 #if USE(PTHREADS) || PLATFORM(WIN)
     77#if USE(PTHREADS) || PLATFORM(WIN_OS)
    5678    struct Data : Noncopyable {
    5779        Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {}
     
    5981        T* value;
    6082        ThreadSpecific<T>* owner;
     83#if !USE(PTHREADS)
     84        void (*destructor)(void*);
     85#endif
    6186    };
    62 
     87#endif
     88
     89#if USE(PTHREADS)
    6390    pthread_key_t m_key;
     91#elif PLATFORM(WIN_OS)
     92    int m_index;
    6493#endif
    6594};
    6695
    67 #if USE(PTHREADS) || PLATFORM(WIN)
     96#if USE(PTHREADS)
    6897template<typename T>
    6998inline ThreadSpecific<T>::ThreadSpecific()
     
    94123}
    95124
     125#elif PLATFORM(WIN_OS)
     126
     127// The maximum number of TLS keys that can be created. For simplification, we assume that:
     128// 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies.
     129// 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
     130const int kMaxTlsKeySize = 256;
     131
     132extern long g_tls_key_count;
     133extern DWORD g_tls_keys[kMaxTlsKeySize];
     134
     135template<typename T>
     136inline ThreadSpecific<T>::ThreadSpecific()
     137    : m_index(-1)
     138{
     139    DWORD tls_key = TlsAlloc();
     140    if (tls_key == TLS_OUT_OF_INDEXES)
     141        CRASH();
     142
     143    m_index = InterlockedIncrement(&g_tls_key_count) - 1;
     144    if (m_index >= kMaxTlsKeySize)
     145        CRASH();
     146    g_tls_keys[m_index] = tls_key;
     147}
     148
     149template<typename T>
     150inline ThreadSpecific<T>::~ThreadSpecific()
     151{
     152    // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached.
     153    TlsFree(g_tls_keys[m_index]);
     154}
     155
     156template<typename T>
     157inline T* ThreadSpecific<T>::get()
     158{
     159    Data* data = static_cast<Data*>(TlsGetValue(g_tls_keys[m_index]));
     160    return data ? data->value : 0;
     161}
     162
     163template<typename T>
     164inline void ThreadSpecific<T>::set(T* ptr)
     165{
     166    ASSERT(!get());
     167    Data* data = new Data(ptr, this);
     168    data->destructor = &ThreadSpecific<T>::destroy;
     169    TlsSetValue(g_tls_keys[m_index], data);
     170}
     171
     172#else
     173#error ThreadSpecific is not implemented for this platform.
     174#endif
     175
    96176template<typename T>
    97177inline void ThreadSpecific<T>::destroy(void* ptr)
     
    99179    Data* data = static_cast<Data*>(ptr);
    100180
     181#if USE(PTHREADS)
    101182    // We want get() to keep working while data destructor works, because it can be called indirectly by the destructor.
    102183    // Some pthreads implementations zero out the pointer before calling destroy(), so we temporarily reset it.
    103184    pthread_setspecific(data->owner->m_key, ptr);
     185#endif
     186   
    104187    data->value->~T();
    105188    fastFree(data->value);
     189
     190#if USE(PTHREADS)
    106191    pthread_setspecific(data->owner->m_key, 0);
    107     delete data;
    108 }
    109 
     192#elif PLATFORM(WIN_OS)
     193    TlsSetValue(g_tls_keys[data->owner->m_index], 0);
    110194#else
    111195#error ThreadSpecific is not implemented for this platform.
    112196#endif
     197
     198    delete data;
     199}
    113200
    114201template<typename T>
  • trunk/JavaScriptCore/wtf/ThreadingWin.cpp

    r39604 r39708  
    6565
    6666#include "MainThread.h"
     67#if !USE(PTHREADS) && PLATFORM(WIN_OS)
     68#include "ThreadSpecific.h"
     69#endif
    6770#include <process.h>
    6871#include <windows.h>
     
    175178
    176179    void* result = invocation.function(invocation.data);
     180
     181#if !USE(PTHREADS) && PLATFORM(WIN_OS)
     182    // Do the TLS cleanup.
     183    ThreadSpecificThreadExit();
     184#endif
    177185
    178186    return reinterpret_cast<unsigned>(result);
Note: See TracChangeset for help on using the changeset viewer.