Wolfgang Thallergcc16 merge934c3885 months agoHistory
224 lines · 6.4 KB · C++
RawDownload
/* Copyright (C) 2021-2026 Free Software Foundation, Inc.   Contributed by Oracle.    This file is part of GNU Binutils.    This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3, or (at your option)   any later version.    This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.    You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, 51 Franklin Street - Fifth Floor, Boston,   MA 02110-1301, USA.  */ #include "config.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h> #include "DbeThread.h"#include "util.h"#include "vec.h" static voidcleanup_free_mutex (void* arg) {  //  pthread_mutex_t *p_mutex = (pthread_mutex_t *) arg;  //  if (p_mutex)  //    pthread_mutex_unlock (p_mutex);} static void*thread_pool_loop (void* arg){  DbeThreadPool *thrp = (DbeThreadPool*) arg;  Dprintf (DEBUG_THREADS, "thread_pool_loop:%d starting thread=%llu\n",	   __LINE__, (unsigned long long) pthread_self ());   /* set my cancel state to 'enabled', and cancel type to 'defered'. */  pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);  pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL);   /* set thread cleanup handler */  pthread_cleanup_push (cleanup_free_mutex, (void*) & (thrp->p_mutex));  for (;;)    {      DbeQueue *q = thrp->get_queue ();      if (q)	{ /* a request is pending */	  Dprintf (DEBUG_THREADS,		   "thread_pool_loop:%d thread=%llu queue=%d start\n",		   __LINE__, (unsigned long long) pthread_self (), q->id);	  q->func (q->arg);	  Dprintf (DEBUG_THREADS,		   "thread_pool_loop:%d thread=%llu queue=%d done\n",		   __LINE__, (unsigned long long) pthread_self (), q->id);	  delete q;	  continue;	}      if (thrp->no_new_queues)	{	  Dprintf (DEBUG_THREADS, "thread_pool_loop:%d exit thread=%llu\n",		   __LINE__, (unsigned long long) pthread_self ());	  pthread_exit (NULL);	}      Dprintf (DEBUG_THREADS,	       "thread_pool_loop:%d before pthread_cond_wait thread=%llu\n",	       __LINE__, (unsigned long long) pthread_self ());      pthread_mutex_lock (&thrp->p_mutex);      pthread_cond_wait (&thrp->p_cond_var, &thrp->p_mutex);      Dprintf (DEBUG_THREADS,	       "thread_pool_loop:%d after pthread_cond_wait thread=%llu\n",	       __LINE__, (unsigned long long) pthread_self ());      pthread_mutex_unlock (&thrp->p_mutex);    }   // never reached, but we must use it here. See `man pthread_cleanup_push`  pthread_cleanup_pop (0);} DbeThreadPool::DbeThreadPool (int _max_threads){  static const int DBE_NTHREADS_DEFAULT = 4;  char *s = getenv ("GPROFNG_DBE_NTHREADS");  if (s)    {      max_threads = atoi (s);      if (max_threads < 0)	max_threads = 0;      if (_max_threads > 0 && max_threads < _max_threads)	max_threads = _max_threads;    }  else    {      max_threads = _max_threads;      if (max_threads < 0)	max_threads = DBE_NTHREADS_DEFAULT;    }  Dprintf (DEBUG_THREADS, "DbeThreadPool:%d  max_threads %d ---> %d\n",	   __LINE__, _max_threads, max_threads);  pthread_mutex_init (&p_mutex, NULL);  pthread_cond_init (&p_cond_var, NULL);  threads = new Vector <pthread_t>(max_threads);  queue = NULL;  last_queue = NULL;  no_new_queues = false;  queues_cnt = 0;  total_queues = 0;} DbeThreadPool::~DbeThreadPool (){  delete threads;} DbeQueue *DbeThreadPool::get_queue (){  pthread_mutex_lock (&p_mutex);  DbeQueue *q = queue;  Dprintf (DEBUG_THREADS,   "get_queue:%d thr: %lld id=%d queues_cnt=%d threads_cnt=%d max_threads=%d\n",	   __LINE__, (unsigned long long) pthread_self (),	   q ? q->id : -1, queues_cnt, (int) threads->size (), max_threads);  if (q)    {      queue = q->next;      queues_cnt--;    }  pthread_mutex_unlock (&p_mutex);  return q;} voidDbeThreadPool::put_queue (DbeQueue *q){  if (max_threads == 0)    {      // nothing runs in parallel      q->id = ++total_queues;      Dprintf (DEBUG_THREADS, NTXT ("put_queue:%d thr=%lld max_threads=%d queue (%d) runs on the worked thread\n"),	       __LINE__, (unsigned long long) pthread_self (), max_threads, q->id);      q->func (q->arg);      delete q;      return;    }   pthread_mutex_lock (&p_mutex);  // nothing runs in parallel  q->id = ++total_queues;  Dprintf (DEBUG_THREADS, "put_queue:%d thr=%lld max_threads=%d queue (%d)\n",	   __LINE__, (unsigned long long) pthread_self (), max_threads, q->id);  if (queue)    {      last_queue->next = q;      last_queue = q;    }  else    {      queue = q;      last_queue = q;    }  queues_cnt++;  Dprintf (DEBUG_THREADS,	   "put_queue:%d id=%d queues_cnt=%d threads_cnt=%d max_threads=%d\n",	   __LINE__, q->id, queues_cnt, (int) threads->size (), max_threads);  if (queues_cnt > threads->size () && threads->size () < max_threads)    {      pthread_t thr;      int r = pthread_create (&thr, NULL, thread_pool_loop, (void *) this);      Dprintf (DEBUG_THREADS,	       "put_queue:%d pthread_create returns %d thr=%llu\n",	       __LINE__, r, (unsigned long long) thr);      if (r)	fprintf (stderr, GTXT ("pthread_create failed. errnum=%d (%s)\n"), r,		 STR (strerror (r)));      else	threads->append (thr);    }  pthread_cond_signal (&p_cond_var);  pthread_mutex_unlock (&p_mutex);} voidDbeThreadPool::wait_queues (){  pthread_mutex_lock (&p_mutex);  no_new_queues = true;  pthread_mutex_unlock (&p_mutex);  pthread_cond_broadcast (&p_cond_var);  for (;;) // Run requests on the worked thread too    {      DbeQueue *q = get_queue ();      if (q == NULL)	break;      Dprintf (DEBUG_THREADS, "wait_queues:%d thread=%llu queue=%d start\n",	       __LINE__, (unsigned long long) pthread_self (), q->id);      q->func (q->arg);      Dprintf (DEBUG_THREADS, "wait_queues:%d thread=%llu queue=%d done\n",	       __LINE__, (unsigned long long) pthread_self (), q->id);      delete q;    }  for (int i = 0, sz = threads->size (); i < sz; i++)    {      void *retval;      pthread_join (threads->get (i), &retval);    }} DbeQueue::DbeQueue (int (*_func) (void *arg), void *_arg){  func = _func;  arg = _arg;  next = NULL;} DbeQueue::~DbeQueue () { }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t