LCOV - code coverage report
Current view: top level - threads - threadlist.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 29 91 31.9 %
Date: 2017-07-14 10:03:36 Functions: 5 11 45.5 %

          Line data    Source code
       1             : /* src/threads/threadlist.cpp - thread list maintenance
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : 
      26             : #include "config.h"
      27             : 
      28             : #include <stdint.h>
      29             : #include <algorithm>
      30             : #include <functional>
      31             : 
      32             : #include "threads/mutex.hpp"
      33             : #include "threads/threadlist.hpp"
      34             : #include "threads/thread.hpp"
      35             : 
      36             : #include "toolbox/list.hpp"
      37             : #include "toolbox/logging.hpp"
      38             : 
      39             : #include "vm/jit/stacktrace.hpp"
      40             : 
      41             : ThreadList *ThreadList::the_threadlist = 0;
      42             : 
      43             : /**
      44             :  * Dumps info for all threads running in the VM.  This function is
      45             :  * called when SIGQUIT (<ctrl>-\) is sent to the VM.
      46             :  */
      47           0 : void ThreadList::dump_threads()
      48             : {
      49             :         // XXX we should stop the world here and remove explicit
      50             :         //     thread suspension from the loop below.
      51             :         // Lock the thread lists.
      52           0 :         MutexLocker lock(_mutex);
      53             : 
      54           0 :         printf("Full thread dump CACAO "VERSION_FULL":\n");
      55             : 
      56             :         // Iterate over all started threads.
      57           0 :         threadobject* self = THREADOBJECT;
      58           0 :         for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
      59           0 :                 threadobject* t = *it;
      60             : 
      61             :                 // Ignore threads which are in state NEW.
      62           0 :                 if (t->state == THREAD_STATE_NEW)
      63           0 :                         continue;
      64             : 
      65             :                 /* Suspend the thread (and ignore return value). */
      66             : 
      67           0 :                 if (t != self)
      68           0 :                         (void) threads_suspend_thread(t, SUSPEND_REASON_DUMP);
      69             : 
      70             :                 /* Print thread info. */
      71             : 
      72           0 :                 printf("\n");
      73           0 :                 thread_print_info(t);
      74           0 :                 printf("\n");
      75             : 
      76             :                 /* Print trace of thread. */
      77             : 
      78           0 :                 stacktrace_print_of_thread(t);
      79             : 
      80             :                 /* Resume the thread (and ignore return value). */
      81             : 
      82           0 :                 if (t != self)
      83           0 :                         (void) threads_resume_thread(t, SUSPEND_REASON_DUMP);
      84           0 :         }
      85           0 : }
      86             : 
      87             : 
      88             : /**
      89             :  * Fills the passed list with all currently active threads. Creating a copy
      90             :  * of the thread list here, is the only way to ensure we do not end up in a
      91             :  * dead-lock when iterating over the list.
      92             :  *
      93             :  * @param list list class to be filled
      94             :  */
      95           0 : void ThreadList::get_active_threads(List<threadobject*> &list)
      96             : {
      97           0 :         MutexLocker lock(_mutex);
      98             : 
      99             :         // Use the assignment operator to create a copy of the thread list.
     100           0 :         list = _active_thread_list;
     101           0 : }
     102             : 
     103             : 
     104             : /**
     105             :  * Fills the passed list with all currently active threads which should be
     106             :  * visible to Java. Creating a copy of the thread list here, is the only way
     107             :  * to ensure we do not end up in a dead-lock when iterating over the list.
     108             :  *
     109             :  * @param list list class to be filled
     110             :  */
     111           0 : void ThreadList::get_active_java_threads(List<threadobject*> &list)
     112             : {
     113           0 :         MutexLocker lock(_mutex);
     114             : 
     115             :         // Iterate over all active threads.
     116           0 :         for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
     117           0 :                 threadobject* t = *it;
     118             : 
     119             :                 // We skip internal threads.
     120           0 :                 if (t->flags & THREAD_FLAG_INTERNAL)
     121           0 :                         continue;
     122             : 
     123           0 :                 list.push_back(t);
     124           0 :         }
     125           0 : }
     126             : 
     127             : 
     128             : /**
     129             :  * Get the next free thread object.
     130             :  *
     131             :  * Gets the next free thread object and a thread index for it.
     132             :  * The results are stored into the passed pointers.
     133             :  *
     134             :  * If no free thread is available `*thread' will contain NULL.
     135             :  * `*index' will always, even if no free thread is available,
     136             :  * contain a valid index you can use for a new thread.
     137             :  */
     138         793 : void ThreadList::get_free_thread(threadobject **thread, int32_t *index) {
     139         793 :         MutexLocker lock(_mutex);
     140             : 
     141             :         // Do we have free threads in the free-list?
     142         793 :         if (_free_thread_list.empty() == false) {
     143             :                 // Yes, get the index and remove it from the free list.
     144           0 :                 threadobject* t = _free_thread_list.front();
     145           0 :                 _free_thread_list.pop_front();
     146             : 
     147           0 :                 *thread = t;
     148           0 :                 *index  = t->index;
     149             :         } else {
     150         793 :                 *thread = NULL;
     151         793 :                 *index  = ++_last_index;
     152           0 :         }
     153         793 : }
     154             : 
     155             : 
     156             : /**
     157             :  * Return the number of daemon threads visible to Java.
     158             :  *
     159             :  * NOTE: This function does a linear-search over the threads list,
     160             :  *       because it is only used by the management interface.
     161             :  *
     162             :  * @return number of daemon threads
     163             :  */
     164           0 : int32_t ThreadList::get_number_of_daemon_java_threads(void)
     165             : {
     166           0 :         int number = 0;
     167             : 
     168             :         // Lock the thread lists.
     169           0 :         MutexLocker lock(_mutex);
     170             : 
     171             :         // Iterate over all active threads.
     172           0 :         for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
     173           0 :                 threadobject* t = *it;
     174             : 
     175             :                 // We skip internal threads.
     176           0 :                 if (t->flags & THREAD_FLAG_INTERNAL)
     177           0 :                         continue;
     178             : 
     179           0 :                 if (thread_is_daemon(t))
     180           0 :                         number++;
     181             :         }
     182             : 
     183           0 :         return number;
     184             : }
     185             : 
     186             : 
     187             : /**
     188             :  * Return the number of non-daemon threads.
     189             :  *
     190             :  * NOTE: This function does a linear-search over the threads list,
     191             :  *       because it is only used for joining the threads.
     192             :  *
     193             :  * @return number of non daemon threads
     194             :  */
     195         131 : int32_t ThreadList::get_number_of_non_daemon_threads(void)
     196             : {
     197         131 :         MutexLocker lock(_mutex);
     198             : 
     199         131 :         int nondaemons = 0;
     200             : 
     201         655 :         for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
     202         524 :                 threadobject* t = *it;
     203             : 
     204         524 :                 if (!thread_is_daemon(t))
     205         131 :                         nondaemons++;
     206             :         }
     207             : 
     208         131 :         return nondaemons;
     209             : }
     210             : 
     211             : // Comparator class.
     212             : class comparator : public std::binary_function<threadobject*, int32_t, bool> {
     213             : public:
     214          15 :         bool operator() (const threadobject* t, const int32_t index) const {
     215          15 :                 return (t->index == index);
     216             :         }
     217             : };
     218             : 
     219             : /**
     220             :  * Return the thread object with the given index.
     221             :  *
     222             :  * @return thread object
     223             :  */
     224           5 : threadobject* ThreadList::get_thread_by_index(int32_t index)
     225             : {
     226           5 :         MutexLocker lock(_mutex);
     227             : 
     228           5 :         List<threadobject*>::iterator it = find_if(_active_thread_list.begin(), _active_thread_list.end(), std::bind2nd(comparator(), index));
     229             : 
     230             :         // No thread found.
     231           5 :         if (it == _active_thread_list.end()) {
     232           0 :                 return NULL;
     233             :         }
     234             : 
     235           5 :         threadobject* t = *it;
     236             : 
     237             :         // The thread found is in state new.
     238           5 :         if (t->state == THREAD_STATE_NEW) {
     239           1 :                 return NULL;
     240             :         }
     241             : 
     242           4 :         return t;
     243             : }
     244             : 
     245             : 
     246             : /**
     247             :  * Return the Java thread object from the given thread object.
     248             :  *
     249             :  * @return Java thread object
     250             :  */
     251           0 : threadobject* ThreadList::get_thread_from_java_object(java_handle_t* h)
     252             : {
     253           0 :         MutexLocker lock(_mutex);
     254             : 
     255           0 :         for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
     256           0 :                 threadobject* t = *it;
     257             : 
     258             :                 bool equal;
     259           0 :                 LLNI_equals(t->object, h, equal);
     260             : 
     261           0 :                 if (equal == true) {
     262           0 :                         return t;
     263             :                 }
     264             :         }
     265             : 
     266           0 :         return NULL;
     267             : }
     268             : 
     269         282 : void ThreadList::deactivate_thread(threadobject *t)
     270             : {
     271         282 :         MutexLocker lock(_mutex);
     272             : 
     273         282 :         remove_from_active_thread_list(t);
     274         282 :         threads_impl_clear_heap_pointers(t); // allow it to be garbage collected
     275         282 : }
     276             : 
     277             : /**
     278             :  * Release the thread.
     279             :  *
     280             :  * @return free thread index
     281             :  */
     282           0 : void ThreadList::release_thread(threadobject* t, bool needs_deactivate)
     283             : {
     284           0 :         MutexLocker lock(_mutex);
     285             : 
     286           0 :         if (needs_deactivate)
     287             :                 // Move thread from active thread list to free thread list.
     288           0 :                 remove_from_active_thread_list(t);
     289             :         else
     290           0 :                 assert(!t->is_in_active_list);
     291             : 
     292           0 :         _free_thread_list.push_back(t);
     293           0 : }
     294             : 
     295             : 
     296             : /*
     297             :  * These are local overrides for various environment variables in Emacs.
     298             :  * Please do not remove this and leave it at the end of the file, where
     299             :  * Emacs will automagically detect them.
     300             :  * ---------------------------------------------------------------------
     301             :  * Local variables:
     302             :  * mode: c++
     303             :  * indent-tabs-mode: t
     304             :  * c-basic-offset: 4
     305             :  * tab-width: 4
     306             :  * End:
     307             :  * vim:noexpandtab:sw=4:ts=4:
     308             :  */

Generated by: LCOV version 1.11