1a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*--------------------------------------------------------------------*/ 2a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*--- Callgrind ---*/ 3a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*--- ct_threads.c ---*/ 4a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*--------------------------------------------------------------------*/ 5a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 6a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* 7a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo This file is part of Callgrind, a Valgrind tool for call tracing. 8a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 90f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj Copyright (C) 2002-2013, Josef Weidendorfer (Josef.Weidendorfer@gmx.de) 10a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 11a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo This program is free software; you can redistribute it and/or 12a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo modify it under the terms of the GNU General Public License as 13a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo published by the Free Software Foundation; either version 2 of the 14a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo License, or (at your option) any later version. 15a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 16a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo This program is distributed in the hope that it will be useful, but 17a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo WITHOUT ANY WARRANTY; without even the implied warranty of 18a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo General Public License for more details. 20a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 21a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo You should have received a copy of the GNU General Public License 22a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo along with this program; if not, write to the Free Software 23a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 24a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 02111-1307, USA. 25a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 26a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo The GNU General Public License is contained in the file COPYING. 27a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo*/ 28a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 29a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo#include "global.h" 30a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 31e7a50823636c1628b946fe570a5bf7fb17a31888sewardj#include "pub_tool_threadstate.h" 32a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 33a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* forward decls */ 34a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_state* exec_state_save(void); 35a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_state* exec_state_restore(void); 36a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_state* push_exec_state(int); 37a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_state* top_exec_state(void); 38a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 39a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_stack current_states; 40a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 41a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 42a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*------------------------------------------------------------*/ 43a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*--- Support for multi-threading ---*/ 44a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*------------------------------------------------------------*/ 45a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 46a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 47a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* 48a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * For Valgrind, MT is cooperative (no preemting in our code), 49a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * so we don't need locks... 50a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * 51a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * Per-thread data: 52a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * - BBCCs 53a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * - call stack 54a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * - call hash 55a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * - event counters: last, current 56a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * 57a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * Even when ignoring MT, we need this functions to set up some 58a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * datastructures for the process (= Thread 1). 59a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 60a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 61a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* current running thread */ 62a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendoThreadId CLG_(current_tid); 63a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 641e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianstatic thread_info** thread; 65a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 66a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendothread_info** CLG_(get_threads)() 67a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 68a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return thread; 69a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 70a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 71a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendothread_info* CLG_(get_current_thread)() 72a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 73a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return thread[CLG_(current_tid)]; 74a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 75a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 76a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(init_threads)() 77a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 781e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian UInt i; 791e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian 801e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian thread = CLG_MALLOC("cl.threads.it.1", VG_N_THREADS * sizeof thread[0]); 811e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian 82a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo for(i=0;i<VG_N_THREADS;i++) 83a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo thread[i] = 0; 84a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_tid) = VG_INVALID_THREADID; 85a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 86a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 87a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* switches through all threads and calls func */ 88a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(forall_threads)(void (*func)(thread_info*)) 89a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 90a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Int t, orig_tid = CLG_(current_tid); 91a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 92a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo for(t=1;t<VG_N_THREADS;t++) { 93a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (!thread[t]) continue; 94a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(switch_thread)(t); 95a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo (*func)(thread[t]); 96a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 97a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(switch_thread)(orig_tid); 98a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 99a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 100a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 101a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic 102a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendothread_info* new_thread(void) 103a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 104a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo thread_info* t; 105a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 1069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj t = (thread_info*) CLG_MALLOC("cl.threads.nt.1", 1079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(thread_info)); 108a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 109a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* init state */ 110a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_exec_stack)( &(t->states) ); 111a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_call_stack)( &(t->calls) ); 112a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_fn_stack) ( &(t->fns) ); 113a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* t->states.entry[0]->cxt = CLG_(get_cxt)(t->fns.bottom); */ 114a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 115a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* event counters */ 116a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo t->lastdump_cost = CLG_(get_eventset_cost)( CLG_(sets).full ); 117a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo t->sighandler_cost = CLG_(get_eventset_cost)( CLG_(sets).full ); 118a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_cost)( CLG_(sets).full, t->lastdump_cost ); 119a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_cost)( CLG_(sets).full, t->sighandler_cost ); 120a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 121a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* init data containers */ 122a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_fn_array)( &(t->fn_active) ); 123a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_bbcc_hash)( &(t->bbccs) ); 124a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_jcc_hash)( &(t->jccs) ); 125a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 126a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return t; 127a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 128a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 129a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 130a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(switch_thread)(ThreadId tid) 131a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 132a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (tid == CLG_(current_tid)) return; 133a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 134a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUG(0, ">> thread %d (was %d)\n", tid, CLG_(current_tid)); 135a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 136a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(current_tid) != VG_INVALID_THREADID) { 137a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* save thread state */ 138a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo thread_info* t = thread[CLG_(current_tid)]; 139a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 140a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(t != 0); 141a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 142a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* current context (including signal handler contexts) */ 143a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state_save(); 144a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(copy_current_exec_stack)( &(t->states) ); 145a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(copy_current_call_stack)( &(t->calls) ); 146a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(copy_current_fn_stack) ( &(t->fns) ); 147a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 148a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(copy_current_fn_array) ( &(t->fn_active) ); 149a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* If we cumulate costs of threads, use TID 1 for all jccs/bccs */ 150a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (!CLG_(clo).separate_threads) t = thread[1]; 151a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(copy_current_bbcc_hash)( &(t->bbccs) ); 152a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(copy_current_jcc_hash) ( &(t->jccs) ); 153a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 154a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 155a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_tid) = tid; 156a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(tid < VG_N_THREADS); 157a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 158a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (tid != VG_INVALID_THREADID) { 159a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo thread_info* t; 160a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 161a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* load thread state */ 162a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 163a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (thread[tid] == 0) thread[tid] = new_thread(); 164a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo t = thread[tid]; 165a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 166a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* current context (including signal handler contexts) */ 167a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(set_current_exec_stack)( &(t->states) ); 168a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state_restore(); 169a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(set_current_call_stack)( &(t->calls) ); 170a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(set_current_fn_stack) ( &(t->fns) ); 171a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 172a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(set_current_fn_array) ( &(t->fn_active) ); 173a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* If we cumulate costs of threads, use TID 1 for all jccs/bccs */ 174a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (!CLG_(clo).separate_threads) t = thread[1]; 175a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(set_current_bbcc_hash) ( &(t->bbccs) ); 176a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(set_current_jcc_hash) ( &(t->jccs) ); 177a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 178a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 179a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 180a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 181a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(run_thread)(ThreadId tid) 182a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 183a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* check for dumps needed */ 184a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo static ULong bbs_done = 0; 1857b7d59405204f88cb944155d6bc5114025ebda98florian HChar buf[50]; // large enough 186a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 187a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(clo).dump_every_bb >0) { 188a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(stat).bb_executions - bbs_done > CLG_(clo).dump_every_bb) { 1899e326b7c9e06d22a868557b8606fc765a2cd6277weidendo VG_(sprintf)(buf, "--dump-every-bb=%llu", CLG_(clo).dump_every_bb); 190a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(dump_profile)(buf, False); 191a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo bbs_done = CLG_(stat).bb_executions; 192a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 193a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 194a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 195a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* now check for thread switch */ 196a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(switch_thread)(tid); 197a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 198a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 199a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(pre_signal)(ThreadId tid, Int sigNum, Bool alt_stack) 200a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 201a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state *es; 202a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 203a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUG(0, ">> pre_signal(TID %d, sig %d, alt_st %s)\n", 204a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo tid, sigNum, alt_stack ? "yes":"no"); 205a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 206a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* switch to the thread the handler runs in */ 207afdb011877cc9f363f52eef90238129fd04d8a27weidendo CLG_(switch_thread)(tid); 208a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 209a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* save current execution state */ 210a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state_save(); 211a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 212a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* setup new cxtinfo struct for this signal handler */ 213a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es = push_exec_state(sigNum); 214e89148708745a7b5ca969628d271ab64a508871fweidendo CLG_(zero_cost)( CLG_(sets).full, es->cost ); 215a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).cost = es->cost; 216a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->call_stack_bottom = CLG_(current_call_stack).sp; 217a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 21861453248457c7c64c9a12aac46c93aa675253e2dweidendo /* setup current state for a spontaneous call */ 21961453248457c7c64c9a12aac46c93aa675253e2dweidendo CLG_(init_exec_state)( &CLG_(current_state) ); 220a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).sig = sigNum; 22161453248457c7c64c9a12aac46c93aa675253e2dweidendo CLG_(push_cxt)(0); 222a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 223a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 224a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* Run post-signal if the stackpointer for call stack is at 225a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * the bottom in current exec state (e.g. a signal handler) 226a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * 227a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * Called from CLG_(pop_call_stack) 228a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 229a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(run_post_signal_on_call_stack_bottom)() 230a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 231a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es = top_exec_state(); 232a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(es != 0); 233a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(CLG_(current_state).sig >0); 234a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 235a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(current_call_stack).sp == es->call_stack_bottom) 236a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(post_signal)( CLG_(current_tid), CLG_(current_state).sig ); 237a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 238a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 239a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(post_signal)(ThreadId tid, Int sigNum) 240a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 241a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es; 242a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo UInt fn_number, *pactive; 243a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 244a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUG(0, ">> post_signal(TID %d, sig %d)\n", 245a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo tid, sigNum); 246a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 247afdb011877cc9f363f52eef90238129fd04d8a27weidendo /* thread switching potentially needed, eg. with instrumentation off */ 248afdb011877cc9f363f52eef90238129fd04d8a27weidendo CLG_(switch_thread)(tid); 249a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(sigNum == CLG_(current_state).sig); 250a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 251a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* Unwind call stack of this signal handler. 252a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * This should only be needed at finalisation time 253a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 254a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es = top_exec_state(); 255a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(es != 0); 256a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo while(CLG_(current_call_stack).sp > es->call_stack_bottom) 257a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(pop_call_stack)(); 258a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 259a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(current_state).cxt) { 260a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* correct active counts */ 261a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo fn_number = CLG_(current_state).cxt->fn[0]->number; 262a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo pactive = CLG_(get_fn_entry)(fn_number); 263a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo (*pactive)--; 264a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUG(0, " set active count of %s back to %d\n", 265a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).cxt->fn[0]->name, *pactive); 266a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 267a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 268a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(current_fn_stack).top > CLG_(current_fn_stack).bottom) { 269a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* set fn_stack_top back. 270a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * top can point to 0 if nothing was executed in the signal handler; 271a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * this is possible at end on unwinding handlers. 272a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 273a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (*(CLG_(current_fn_stack).top) != 0) { 274a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_fn_stack).top--; 275a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(*(CLG_(current_fn_stack).top) == 0); 276a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 277a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (CLG_(current_fn_stack).top > CLG_(current_fn_stack).bottom) 278a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_fn_stack).top--; 279a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 280a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 281a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* sum up costs */ 282a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(CLG_(current_state).cost == es->cost); 283a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(add_and_zero_cost)( CLG_(sets).full, 284a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo thread[CLG_(current_tid)]->sighandler_cost, 285a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).cost ); 286a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 287a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* restore previous context */ 288a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->sig = -1; 289a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo current_states.sp--; 290a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es = top_exec_state(); 291a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).sig = es->sig; 292a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state_restore(); 293a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 294a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* There is no way to reliable get the thread ID we are switching to 295a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * after this handler returns. So we sync with actual TID at start of 296a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * CLG_(setup_bb)(), which should be the next for callgrind. 297a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 298a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 299a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 300a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 301a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 302a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*------------------------------------------------------------*/ 303a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*--- Execution states in a thread & signal handlers ---*/ 304a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/*------------------------------------------------------------*/ 305a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 306a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* Each thread can be interrupted by a signal handler, and they 307a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * themselves again. But as there's no scheduling among handlers 308a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * of the same thread, we don't need additional stacks. 309a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * So storing execution contexts and 310a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * adding separators in the callstack(needed to not intermix normal/handler 311a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * functions in contexts) should be enough. 312a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 313a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 314a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* not initialized: call_stack_bottom, sig */ 315a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(init_exec_state)(exec_state* es) 316a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 317a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->collect = CLG_(clo).collect_atstart; 318a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->cxt = 0; 319a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->jmps_passed = 0; 320a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->bbcc = 0; 321a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->nonskipped = 0; 322a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 323a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 324a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 325a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_state* new_exec_state(Int sigNum) 326a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 327a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es; 3289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj es = (exec_state*) CLG_MALLOC("cl.threads.nes.1", 3299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(exec_state)); 330a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 331a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* allocate real cost space: needed as incremented by 332a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * simulation functions */ 333a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->cost = CLG_(get_eventset_cost)(CLG_(sets).full); 334e89148708745a7b5ca969628d271ab64a508871fweidendo CLG_(zero_cost)( CLG_(sets).full, es->cost ); 335a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(init_exec_state)(es); 336a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->sig = sigNum; 337a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->call_stack_bottom = 0; 338a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 339a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return es; 340a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 341a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 342a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(init_exec_stack)(exec_stack* es) 343a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 344a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Int i; 345a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 346a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* The first element is for the main thread */ 347a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->entry[0] = new_exec_state(0); 348a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo for(i=1;i<MAX_SIGHANDLERS;i++) 349a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->entry[i] = 0; 350a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->sp = 0; 351a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 352a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 353a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(copy_current_exec_stack)(exec_stack* dst) 354a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 355a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Int i; 356a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 357a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo dst->sp = current_states.sp; 358a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo for(i=0;i<MAX_SIGHANDLERS;i++) 359a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo dst->entry[i] = current_states.entry[i]; 360a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 361a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 362a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendovoid CLG_(set_current_exec_stack)(exec_stack* dst) 363a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 364a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Int i; 365a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 366a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo current_states.sp = dst->sp; 367a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo for(i=0;i<MAX_SIGHANDLERS;i++) 368a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo current_states.entry[i] = dst->entry[i]; 369a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 370a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 371a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 372a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* Get top context info struct of current thread */ 373a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic 374a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendoexec_state* top_exec_state(void) 375a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 376a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Int sp = current_states.sp; 377a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es; 378a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 379a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT((sp >= 0) && (sp < MAX_SIGHANDLERS)); 380a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es = current_states.entry[sp]; 381a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(es != 0); 382a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return es; 383a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 384a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 385a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* Allocates a free context info structure for a new entered 386a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * signal handler, putting it on the context stack. 387a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo * Returns a pointer to the structure. 388a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo */ 389a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic exec_state* push_exec_state(int sigNum) 390a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 391a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo Int sp; 392a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es; 393a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 394a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo current_states.sp++; 395a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo sp = current_states.sp; 396a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 397a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT((sigNum > 0) && (sigNum <= _VKI_NSIG)); 398a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT((sp > 0) && (sp < MAX_SIGHANDLERS)); 399a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es = current_states.entry[sp]; 400a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo if (!es) { 401a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es = new_exec_state(sigNum); 402a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo current_states.entry[sp] = es; 403a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 404a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo else 405a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->sig = sigNum; 406a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 407a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return es; 408a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 409a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 410a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo/* Save current context to top cxtinfo struct */ 411a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic 412a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendoexec_state* exec_state_save(void) 413a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 414a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es = top_exec_state(); 415a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 416a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->cxt = CLG_(current_state).cxt; 417a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->collect = CLG_(current_state).collect; 418a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->jmps_passed = CLG_(current_state).jmps_passed; 419a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->bbcc = CLG_(current_state).bbcc; 420a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->nonskipped = CLG_(current_state).nonskipped; 42161453248457c7c64c9a12aac46c93aa675253e2dweidendo CLG_ASSERT(es->cost == CLG_(current_state).cost); 422a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 423a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUGIF(1) { 424a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUG(1, " cxtinfo_save(sig %d): collect %s, jmps_passed %d\n", 425a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->sig, es->collect ? "Yes": "No", es->jmps_passed); 42609ee78ec9675201840d895623d49efba1ffe05d8weidendo CLG_(print_bbcc)(-9, es->bbcc); 427a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(print_cost)(-9, CLG_(sets).full, es->cost); 428a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 429a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 430a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo /* signal number does not need to be saved */ 431a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_ASSERT(CLG_(current_state).sig == es->sig); 432a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 433a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return es; 434a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 435a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 436a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendostatic 437a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendoexec_state* exec_state_restore(void) 438a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo{ 439a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo exec_state* es = top_exec_state(); 440a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 441a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).cxt = es->cxt; 442a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).collect = es->collect; 443a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).jmps_passed = es->jmps_passed; 444a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).bbcc = es->bbcc; 445a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).nonskipped = es->nonskipped; 446a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).cost = es->cost; 447a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(current_state).sig = es->sig; 448a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 449a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUGIF(1) { 450a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_DEBUG(1, " exec_state_restore(sig %d): collect %s, jmps_passed %d\n", 451a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo es->sig, es->collect ? "Yes": "No", es->jmps_passed); 45209ee78ec9675201840d895623d49efba1ffe05d8weidendo CLG_(print_bbcc)(-9, es->bbcc); 453a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(print_cxt)(-9, es->cxt, 0); 454a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo CLG_(print_cost)(-9, CLG_(sets).full, es->cost); 455a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo } 456a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo 457a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo return es; 458a17f2a36b7fde9ee842f92412eacbf94b66af59dweidendo} 459