13

I'd like to add two extra fields of type StgWord32 to the thread state object (TSO). Based on the information I found on the GHC-Wiki and from looking at the source code, I have extended the struct in /includes/rts/storage/TSO.h and changed the program that creates different offsets (creating DerivedConstants.h). The compiler, the rts, and a simple application re-compile, but at the end of the execution (in hs_exit_) the garbage collector complains:

 internal error: scavenge_stack: weird activation record found on stack: 45

I guess it has to to with cmm and/or the STG implementation details (the offsets are generated since the structs are not visible at cmm level, correct me if I'm wrong). Is the order of fields significant? Have I missed a file that should be changed?

I use a debug build of the compiler and RTS and a rather dated ghc 6.12.3 on a 64bit architecture. Any hints to relevant documentation and comments on the difference between ghc 6 and 7 regarding TSO handling are welcome, too.

jev
  • 2,023
  • 1
  • 17
  • 26
  • 1
    What are you trying to achieve? Perhaps there is a different, simpler way. – Petr Apr 13 '15 at 20:02
  • I want to carry around some extra information with each thread to record for instance the ids of parent threads and use it when making load balancing decisions – jev Apr 13 '15 at 23:02

2 Answers2

2

The error that you are getting comes from: ghc/rts/sm/Scav.c. Specifically at line 1917:

 default:
    barf("scavenge_stack: weird activation record found on stack: %d", (int)(info->i.type));

It looks like you need to also modify ClosureTypes.h, which you can find in ghc/includes/rts/storage. This file seems to contain the different kinds of headers that can appear in a heap object. I've also run into some strange bootstrapping errors, where if I try to rebuild using the stage-1 compiler, I get the error you mentioned, but if I do a clean build, then it compiles just fine.

Matt
  • 4,029
  • 3
  • 20
  • 37
  • Thanks for the suggestion. I wonder why do you think I should introduce a new closure type? I'd like to keep the standard TSO closure type but add a field to the TSO object. To me it looks like some offsets are wrong an the info field get overwritten by accident. – jev Jul 13 '15 at 21:50
  • On second thought, you probably don't need to create a new heap object, especially if the new field you are adding isn't a pointer. Did you try doing a clean build? That has solved this problem for me in the past. – Matt Jul 13 '15 at 23:50
  • unfortunately a clean build didn't help (I can't assume to have working stage-2 compiler either) – jev Aug 01 '15 at 18:39
1

A workaround that turned out good enough for me was to introduce a separate data structure for each Capability that would hold the additional information for each lightweight thread. I have used a HashTable (see rts/Hash.h and .c) mapping from thread id to the custom info struct. The entries were added when the threads were created from sparks (in schduleActiveteSpark).

Timing the creation, insertion, lookup and destruction of the entries and the table showed negligible overhead for small programs. The main overhead results from the actual usage of the information and should ideally be kept outside of the innermost scheduler loop. For the THREADED_RTS build one needs to ensure that other Capabilities don't access tables that are not their own (or use a mutex if such access is required, which is potential source of additional overhead).

jev
  • 2,023
  • 1
  • 17
  • 26