1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/*
28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * are met:
7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     documentation and/or other materials provided with the distribution.
13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */
25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h"
27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Threading.h"
28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <string.h>
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WTF {
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
33ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstruct NewThreadContext {
34ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_FAST_ALLOCATED;
35ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochpublic:
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NewThreadContext(ThreadFunction entryPoint, void* data, const char* name)
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        : entryPoint(entryPoint)
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        , data(data)
398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        , name(name)
408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ThreadFunction entryPoint;
44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    void* data;
458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const char* name;
46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Mutex creationMutex;
48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project};
49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void* threadEntryPoint(void* contextData)
51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
54d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Block until our creating thread has completed any extra setup work, including
55d0825bca7fe65beaee391d30da42e937db621564Steve Block    // establishing ThreadIdentifier.
56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        MutexLocker locker(context->creationMutex);
58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
60d0825bca7fe65beaee391d30da42e937db621564Steve Block    initializeCurrentThreadInternal(context->name);
61d0825bca7fe65beaee391d30da42e937db621564Steve Block
62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Grab the info that we need out of the context, then deallocate it.
63635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ThreadFunction entryPoint = context->entryPoint;
64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    void* data = context->data;
65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    delete context;
66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return entryPoint(data);
68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Visual Studio has a 31-character limit on thread names. Longer names will
738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // be truncated silently, but we'd like callers to know about the limit.
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if !LOG_DISABLED
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (strlen(name) > 31)
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name);
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
8144991d7282295431aa1809bf22c45850d69ec428Steve Block    // Prevent the thread body from executing until we've established the thread identifier.
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    MutexLocker locker(context->creationMutex);
83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return createThreadInternal(threadEntryPoint, context, name);
85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if PLATFORM(MAC) || PLATFORM(WIN)
88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
89635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// This function is deprecated but needs to be kept around for backward
90635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// compatibility. Use the 3-argument version of createThread above.
91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectThreadIdentifier createThread(ThreadFunction entryPoint, void* data);
93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return createThread(entryPoint, data, 0);
97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} // namespace WTF
101