00001 /** @file 00002 00003 Thread 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 00023 @section details Details 00024 00025 Thread class provides the basic functionality for threads. Typically, 00026 there will be additional derived classes. Having a common base class 00027 for all threads is useful in many cases. I discuss below the use of 00028 Threads in the context of Event Subsystem. Hopefully this would be 00029 typical of other situations. 00030 00031 EventProcessor needs to create a bunch of threads. It declares a 00032 class called EThread, derived from Thread. It is the responsibility of 00033 the EventProcessor to create and manage all the threads needed in the 00034 Event Subsystem (Note: we have removed the original ThreadManager class 00035 which used to create and manage *all* the threads in the system). By 00036 monitoring, we mean checking the heartbeat of each thread and the 00037 number of threads in the system etc. 00038 00039 A derived class should either provide the function (and arguments) 00040 needed by the Thread class (see start()), or should define the virtual 00041 function execute(). 00042 00043 The Thread class maintains a thread_key which registers *all* 00044 the threads in the system (that have been created using Thread or 00045 a derived class), using thread specific data calls. Whenever, you 00046 call this_thread() you get a pointer to the Thread that is currently 00047 executing you. Additionally, the EThread class (derived from Thread) 00048 maintains its own independent key. All (and only) the threads created 00049 in the Event Subsystem are registered with this key. Thus, whenever you 00050 call this_ethread() you get a pointer to EThread. If you happen to call 00051 this_ethread() from inside a thread which is not an EThread, you will 00052 get a NULL value (since that thread will not be registered with the 00053 EThread key). This will hopefully make the use of this_ethread() safer. 00054 Note that an event created with EThread can also call this_thread(), 00055 in which case, it will get a pointer to Thread (rather than to EThread). 00056 00057 */ 00058 00059 #ifndef _I_Thread_h 00060 #define _I_Thread_h 00061 00062 #if !defined(_I_EventSystem_h) && !defined(_P_EventSystem_h) 00063 #error "include I_EventSystem.h or P_EventSystem.h" 00064 -- -include I_Event.h or P_Event.h 00065 #endif 00066 #include "libts.h" 00067 #include "I_ProxyAllocator.h" 00068 class Thread; 00069 class ProxyMutex; 00070 00071 #define THREADAPI 00072 #define THREADAPI_RETURN_TYPE void * 00073 typedef THREADAPI_RETURN_TYPE(THREADAPI * ThreadFunction) (void *arg); 00074 00075 extern ProxyMutex *global_mutex; 00076 00077 static const int MAX_THREAD_NAME_LENGTH = 16; 00078 static const int DEFAULT_STACKSIZE = 1048576; // 1MB 00079 00080 00081 /** 00082 Base class for the threads in the Event System. Thread is the base 00083 class for all the thread classes in the Event System. Objects of the 00084 Thread class represent spawned or running threads and provide minimal 00085 information for its derived classes. Thread objects have a reference 00086 to a ProxyMutex, that is used for atomic operations internally, and 00087 an ink_thread member that is used to identify the thread in the system. 00088 00089 You should not create an object of the Thread class, they are typically 00090 instantiated after some thread startup mechanism exposed by a processor, 00091 but even then you would probably deal with processor functions and 00092 not the Thread object itself. 00093 00094 */ 00095 class Thread 00096 { 00097 public: 00098 00099 /*-------------------------------------------*\ 00100 | Common Interface | 00101 \*-------------------------------------------*/ 00102 00103 /** 00104 System-wide thread identifier. The thread identifier is represented 00105 by the platform independent type ink_thread and it is the system-wide 00106 value assigned to each thread. It is exposed as a convenience for 00107 processors and you should not modify it directly. 00108 00109 */ 00110 ink_thread tid; 00111 00112 /** 00113 Thread lock to ensure atomic operations. The thread lock available 00114 to derived classes to ensure atomic operations and protect critical 00115 regions. Do not modify this member directly. 00116 00117 */ 00118 ProxyMutex *mutex; 00119 00120 // PRIVATE 00121 void set_specific(); 00122 Thread(); 00123 virtual ~ Thread(); 00124 00125 static ink_hrtime cur_time; 00126 inkcoreapi static ink_thread_key thread_data_key; 00127 Ptr<ProxyMutex> mutex_ptr; 00128 00129 // For THREAD_ALLOC 00130 ProxyAllocator eventAllocator; 00131 ProxyAllocator netVCAllocator; 00132 ProxyAllocator sslNetVCAllocator; 00133 ProxyAllocator httpClientSessionAllocator; 00134 ProxyAllocator httpServerSessionAllocator; 00135 ProxyAllocator hdrHeapAllocator; 00136 ProxyAllocator strHeapAllocator; 00137 ProxyAllocator cacheVConnectionAllocator; 00138 ProxyAllocator openDirEntryAllocator; 00139 ProxyAllocator ramCacheCLFUSEntryAllocator; 00140 ProxyAllocator ramCacheLRUEntryAllocator; 00141 ProxyAllocator evacuationBlockAllocator; 00142 ProxyAllocator ioDataAllocator; 00143 ProxyAllocator ioAllocator; 00144 ProxyAllocator ioBlockAllocator; 00145 ProxyAllocator ioBufAllocator[DEFAULT_BUFFER_SIZES]; 00146 00147 private: 00148 // prevent unauthorized copies (Not implemented) 00149 Thread(const Thread &); 00150 Thread & operator =(const Thread &); 00151 00152 public: 00153 ink_thread start(const char* name, size_t stacksize=DEFAULT_STACKSIZE, ThreadFunction f=NULL, void *a=NULL); 00154 00155 virtual void execute() 00156 { } 00157 }; 00158 00159 extern ink_hrtime ink_get_hrtime(); 00160 extern ink_hrtime ink_get_based_hrtime(); 00161 extern Thread *this_thread(); 00162 00163 #endif /*_I_Thread_h*/