예제 #1
0
파일: Trace.c 프로젝트: lukemaurer/ghc
void traceCapEvent_ (Capability   *cap,
                     EventTypeNum  tag)
{
#ifdef DEBUG
    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
        ACQUIRE_LOCK(&trace_utx);

        tracePreface();
        switch (tag) {
        case EVENT_CAP_CREATE:   // (cap)
            debugBelch("cap %d: initialised\n", cap->no);
            break;
        case EVENT_CAP_DELETE:   // (cap)
            debugBelch("cap %d: shutting down\n", cap->no);
            break;
        case EVENT_CAP_ENABLE:   // (cap)
            debugBelch("cap %d: enabling capability\n", cap->no);
            break;
        case EVENT_CAP_DISABLE:  // (cap)
            debugBelch("cap %d: disabling capability\n", cap->no);
            break;
        }
        RELEASE_LOCK(&trace_utx);
    } else
#endif
    {
        if (eventlog_enabled) {
            postCapEvent(tag, (EventCapNo)cap->no);
        }
    }
}
예제 #2
0
파일: Stats.c 프로젝트: Sciumo/ghc
void
stat_startGC (gc_thread *gct)
{
    nat bell = RtsFlags.GcFlags.ringBell;

    if (bell) {
	if (bell > 1) {
	    debugBelch(" GC ");
	    rub_bell = 1;
	} else {
	    debugBelch("\007");
	}
    }

#if USE_PAPI
    if(papi_is_reporting) {
      /* Switch to counting GC events */
      papi_stop_mutator_count();
      papi_start_gc_count();
    }
#endif

    getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed);
    gct->gc_start_thread_cpu  = getThreadCPUTime();

    if (RtsFlags.GcFlags.giveStats != NO_GC_STATS)
    {
        gct->gc_start_faults = getPageFaults();
    }
}
예제 #3
0
파일: Trace.c 프로젝트: NathanHowell/ghc
void traceCapsetEvent_ (EventTypeNum tag,
                        CapsetID capset,
                        StgWord info)
{
#ifdef DEBUG
    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
        ACQUIRE_LOCK(&trace_utx);

        tracePreface();
        switch (tag) {
        case EVENT_CAPSET_CREATE:   // (capset, capset_type)
            debugBelch("created capset %lu of type %d\n", (lnat)capset, (int)info);
            break;
        case EVENT_CAPSET_DELETE:   // (capset)
            debugBelch("deleted capset %lu\n", (lnat)capset);
            break;
        case EVENT_CAPSET_ASSIGN_CAP:  // (capset, capno)
            debugBelch("assigned cap %lu to capset %lu\n",
                       (lnat)info, (lnat)capset);
            break;
        case EVENT_CAPSET_REMOVE_CAP:  // (capset, capno)
            debugBelch("removed cap %lu from capset %lu\n",
                       (lnat)info, (lnat)capset);
            break;
        }
        RELEASE_LOCK(&trace_utx);
    } else
#endif
    {
        if (eventlog_enabled) {
            postCapsetEvent(tag, capset, info);
        }
    }
}
예제 #4
0
int main (int argc, char *argv[])
{
    int i, j, b;

    bdescr *a[ARRSIZE];

    srand(SEED);

    hs_init(&argc, &argv);

   // repeatedly sweep though the array, allocating new random-sized
   // objects and deallocating the old ones.
   for (i=0; i < LOOPS; i++)
   {
       for (j=0; j < ARRSIZE; j++)
       {
           if (i > 0)
           {
               IF_DEBUG(block_alloc, debugBelch("A%d: freeing %p, %d blocks @ %p\n", j, a[j], a[j]->blocks, a[j]->start));
               freeGroup_lock(a[j]);
               DEBUG_ONLY(checkFreeListSanity());
           }
           b = (rand() % MAXALLOC) + 1;
           a[j] = allocGroup_lock(b);
           IF_DEBUG(block_alloc, debugBelch("A%d: allocated %p, %d blocks @ %p\n", j, a[j], b, a[j]->start));
           // allocating zero blocks isn't allowed
           DEBUG_ONLY(checkFreeListSanity());
       }
   }

   for (j=0; j < ARRSIZE; j++)
   {
       freeGroup_lock(a[j]);
   }
    
    // this time, sweep forwards allocating new blocks, and then
    // backwards deallocating them.
    for (i=0; i < LOOPS; i++)
    {
        for (j=0; j < ARRSIZE; j++)
        {
            b = (rand() % MAXALLOC) + 1;
            a[j] = allocGroup_lock(b);
            IF_DEBUG(block_alloc, debugBelch("B%d,%d: allocated %p, %d blocks @ %p\n", i, j, a[j], b, a[j]->start));
            DEBUG_ONLY(checkFreeListSanity());
        }
        for (j=ARRSIZE-1; j >= 0; j--)
        {
            IF_DEBUG(block_alloc, debugBelch("B%d,%d: freeing %p, %d blocks @ %p\n", i, j, a[j], a[j]->blocks, a[j]->start));
            freeGroup_lock(a[j]);
            DEBUG_ONLY(checkFreeListSanity());
        }
    }
    
    DEBUG_ONLY(checkFreeListSanity());

    hs_exit(); // will do a memory leak test

    exit(0);
}
예제 #5
0
파일: Profiling.c 프로젝트: gridaphobe/ghc
static void
initProfilingLogFile(void)
{
    char *prog;

    prog = arenaAlloc(prof_arena, strlen(prog_name) + 1);
    strcpy(prog, prog_name);
#ifdef mingw32_HOST_OS
    // on Windows, drop the .exe suffix if there is one
    {
        char *suff;
        suff = strrchr(prog,'.');
        if (suff != NULL && !strcmp(suff,".exe")) {
            *suff = '\0';
        }
    }
#endif

    if (RtsFlags.CcFlags.doCostCentres == 0 &&
        RtsFlags.ProfFlags.doHeapProfile != HEAP_BY_RETAINER &&
        RtsFlags.ProfFlags.retainerSelector == NULL)
    {
        /* No need for the <prog>.prof file */
        prof_filename = NULL;
        prof_file = NULL;
    }
    else
    {
        /* Initialise the log file name */
        prof_filename = arenaAlloc(prof_arena, strlen(prog) + 6);
        sprintf(prof_filename, "%s.prof", prog);

        /* open the log file */
        if ((prof_file = fopen(prof_filename, "w")) == NULL) {
            debugBelch("Can't open profiling report file %s\n", prof_filename);
            RtsFlags.CcFlags.doCostCentres = 0;
            // The following line was added by Sung; retainer/LDV profiling may need
            // two output files, i.e., <program>.prof/hp.
            if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER)
                RtsFlags.ProfFlags.doHeapProfile = 0;
            return;
        }
    }

    if (RtsFlags.ProfFlags.doHeapProfile) {
        /* Initialise the log file name */
        hp_filename = arenaAlloc(prof_arena, strlen(prog) + 6);
        sprintf(hp_filename, "%s.hp", prog);

        /* open the log file */
        if ((hp_file = fopen(hp_filename, "w")) == NULL) {
            debugBelch("Can't open profiling report file %s\n",
                    hp_filename);
            RtsFlags.ProfFlags.doHeapProfile = 0;
            return;
        }
    }
}
예제 #6
0
파일: Printer.c 프로젝트: Seraphime/ghc
STATIC_INLINE void
printStdObjHdr( const StgClosure *obj, char* tag )
{
    debugBelch("%s(",tag);
    printPtr((StgPtr)obj->header.info);
#ifdef PROFILING
    debugBelch(", %s", obj->header.prof.ccs->cc->label);
#endif
}
예제 #7
0
파일: Trace.c 프로젝트: lukemaurer/ghc
static void tracePreface (void)
{
#ifdef THREADED_RTS
    debugBelch("%12lx: ", (unsigned long)osThreadId());
#endif
    if (RtsFlags.TraceFlags.timestamp) {
        debugBelch("%9" FMT_Word64 ": ", stat_getElapsedTime());
    }
}
예제 #8
0
파일: Profiling.c 프로젝트: errord/ghc
static void
initProfilingLogFile(void)
{
    char *prog;

    prog = arenaAlloc(prof_arena, strlen(prog_name) + 1);
    strcpy(prog, prog_name);
#ifdef mingw32_HOST_OS
    // on Windows, drop the .exe suffix if there is one
    {
        char *suff;
        suff = strrchr(prog,'.');
        if (suff != NULL && !strcmp(suff,".exe")) {
            *suff = '\0';
        }
    }
#endif

    if (RtsFlags.CcFlags.doCostCentres == 0 && !doingRetainerProfiling())
    {
        /* No need for the <prog>.prof file */
        prof_filename = NULL;
        prof_file = NULL;
    }
    else
    {
        /* Initialise the log file name */
        prof_filename = arenaAlloc(prof_arena, strlen(prog) + 6);
        sprintf(prof_filename, "%s.prof", prog);

        /* open the log file */
        if ((prof_file = fopen(prof_filename, "w")) == NULL) {
            debugBelch("Can't open profiling report file %s\n", prof_filename);
            RtsFlags.CcFlags.doCostCentres = 0;
            // Retainer profiling (`-hr` or `-hr<cc> -h<x>`) writes to
            // both <program>.hp as <program>.prof.
            if (doingRetainerProfiling()) {
                RtsFlags.ProfFlags.doHeapProfile = 0;
            }
        }
    }

    if (RtsFlags.ProfFlags.doHeapProfile) {
        /* Initialise the log file name */
        hp_filename = arenaAlloc(prof_arena, strlen(prog) + 6);
        sprintf(hp_filename, "%s.hp", prog);

        /* open the log file */
        if ((hp_file = fopen(hp_filename, "w")) == NULL) {
            debugBelch("Can't open profiling report file %s\n",
                    hp_filename);
            RtsFlags.ProfFlags.doHeapProfile = 0;
        }
    }
}
예제 #9
0
파일: Trace.c 프로젝트: lukemaurer/ghc
static void vtraceCap_stderr(Capability *cap, char *msg, va_list ap)
{
    ACQUIRE_LOCK(&trace_utx);

    tracePreface();
    debugBelch("cap %d: ", cap->no);
    vdebugBelch(msg,ap);
    debugBelch("\n");

    RELEASE_LOCK(&trace_utx);
}
예제 #10
0
파일: Printer.c 프로젝트: Seraphime/ghc
void printPtr( StgPtr p )
{
    const char *raw;
    raw = lookupGHCName(p);
    if (raw != NULL) {
        debugBelch("<%s>", raw);
        debugBelch("[%p]", p);
    } else {
        debugBelch("%p", p);
    }
}
예제 #11
0
StgPtr
printStackObj( StgPtr sp )
{
    /*debugBelch("Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */

        StgClosure* c = (StgClosure*)(*sp);
        printPtr((StgPtr)*sp);
        if (c == (StgClosure*)&stg_ctoi_R1p_info) {
           debugBelch("\t\t\tstg_ctoi_ret_R1p_info\n" );
	} else
        if (c == (StgClosure*)&stg_ctoi_R1n_info) {
           debugBelch("\t\t\tstg_ctoi_ret_R1n_info\n" );
	} else
        if (c == (StgClosure*)&stg_ctoi_F1_info) {
           debugBelch("\t\t\tstg_ctoi_ret_F1_info\n" );
	} else
        if (c == (StgClosure*)&stg_ctoi_D1_info) {
           debugBelch("\t\t\tstg_ctoi_ret_D1_info\n" );
	} else
        if (c == (StgClosure*)&stg_ctoi_V_info) {
           debugBelch("\t\t\tstg_ctoi_ret_V_info\n" );
	} else
        if (get_itbl(c)->type == BCO) {
           debugBelch("\t\t\t");
           debugBelch("BCO(...)\n"); 
        }
        else {
           debugBelch("\t\t\t");
           printClosure ( (StgClosure*)(*sp));
        }
        sp += 1;

    return sp;
    
}
예제 #12
0
static void printZcoded( const char *raw )
{
    nat j = 0;
    
    while ( raw[j] != '\0' ) {
        if (raw[j] == 'Z') {
            debugBelch("%c", unZcode(raw[j+1]));
            j = j + 2;
        } else {
            debugBelch("%c", unZcode(raw[j+1]));
            j = j + 1;
        }
    }
}
예제 #13
0
파일: Printer.c 프로젝트: goldfirere/ghc
void
printMutableList(bdescr *bd)
{
    StgPtr p;

    debugBelch("mutable list %p: ", bd);

    for (; bd != NULL; bd = bd->link) {
        for (p = bd->start; p < bd->free; p++) {
            debugBelch("%p (%s), ", (void *)*p, info_type((StgClosure *)*p));
        }
    }
    debugBelch("\n");
}
예제 #14
0
static void
printSmallBitmap( StgPtr spBottom, StgPtr payload, StgWord bitmap, nat size )
{
    nat i;

    for(i = 0; i < size; i++, bitmap >>= 1 ) {
	debugBelch("   stk[%ld] (%p) = ", (long)(spBottom-(payload+i)), payload+i);
	if ((bitmap & 1) == 0) {
	    printPtr((P_)payload[i]);
	    debugBelch("\n");
	} else {
	    debugBelch("Word# %" FMT_Word "\n", (W_)payload[i]);
	}
    }
}
예제 #15
0
파일: Printer.c 프로젝트: Seraphime/ghc
void
findPtr(P_ p, int follow)
{
  uint32_t g, n;
  bdescr *bd;
  const int arr_size = 1024;
  StgPtr arr[arr_size];
  int i = 0;
  searched = 0;

  for (n = 0; n < n_capabilities; n++) {
      bd = nurseries[i].blocks;
      i = findPtrBlocks(p,bd,arr,arr_size,i);
      if (i >= arr_size) return;
  }

  for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
      bd = generations[g].blocks;
      i = findPtrBlocks(p,bd,arr,arr_size,i);
      bd = generations[g].large_objects;
      i = findPtrBlocks(p,bd,arr,arr_size,i);
      if (i >= arr_size) return;
  }
  if (follow && i == 1) {
      debugBelch("-->\n");
      findPtr(arr[0], 1);
  }
}
예제 #16
0
파일: BlockAlloc.c 프로젝트: GuySteele/ghc
void returnMemoryToOS(nat n /* megablocks */)
{
    static bdescr *bd;
    StgWord size;

    bd = free_mblock_list;
    while ((n > 0) && (bd != NULL)) {
        size = BLOCKS_TO_MBLOCKS(bd->blocks);
        if (size > n) {
            StgWord newSize = size - n;
            char *freeAddr = MBLOCK_ROUND_DOWN(bd->start);
            freeAddr += newSize * MBLOCK_SIZE;
            bd->blocks = MBLOCK_GROUP_BLOCKS(newSize);
            freeMBlocks(freeAddr, n);
            n = 0;
        }
        else {
            char *freeAddr = MBLOCK_ROUND_DOWN(bd->start);
            n -= size;
            bd = bd->link;
            freeMBlocks(freeAddr, size);
        }
    }
    free_mblock_list = bd;

    osReleaseFreeMemory();

    IF_DEBUG(gc,
        if (n != 0) {
            debugBelch("Wanted to free %d more MBlocks than are freeable\n",
                       n);
        }
    );
예제 #17
0
파일: Printer.c 프로젝트: Seraphime/ghc
static void
printThunkPayload( StgThunk *obj )
{
    StgWord i, j;
    const StgInfoTable* info;

    info = get_itbl((StgClosure *)obj);
    for (i = 0; i < info->layout.payload.ptrs; ++i) {
        debugBelch(", ");
        printPtr((StgPtr)obj->payload[i]);
    }
    for (j = 0; j < info->layout.payload.nptrs; ++j) {
        debugBelch(", %pd#",obj->payload[i+j]);
    }
    debugBelch(")\n");
}
예제 #18
0
파일: MPIComm.c 프로젝트: jberthold/ghc
/* MP_sync synchronises all nodes in a parallel computation:
 * sets:
 *     thisPE - GlobalTaskId: node's own task Id
 *                     (logical node address for messages)
 * Returns: Bool: success (1) or failure (0)
 *
 * MPI Version:
 *   the number of nodes is checked by counting nodes in WORLD
 *   (could also be done by sync message)
 *   Own ID is known before, but returned only here.
 */
rtsBool MP_sync(void) {
    // initialise counters/constants and allocate/attach the buffer

    // buffer size default is 20, use RTS option -qq<N> to change it
    maxMsgs = RtsFlags.ParFlags.sendBufferSize;
    // and resulting buffer space

    // checks inside RtsFlags.c:
    // DATASPACEWORDS * sizeof(StgWord) < INT_MAX / 2
    // maxMsgs <= max(20,nPEs)
    // Howver, they might be just too much in combination.
    if (INT_MAX / sizeof(StgWord) < DATASPACEWORDS * maxMsgs) {
        IF_PAR_DEBUG(mpcomm,
                     debugBelch("requested buffer sizes too large, adjusting...\n"));
        do {
            maxMsgs--;
        } while (maxMsgs > 0 &&
                 INT_MAX / sizeof(StgWord) < DATASPACEWORDS * maxMsgs);
        if (maxMsgs == 0) {
            // should not be possible with checks inside RtsFlags.c, see above
            barf("pack buffer too large to allocate, aborting program.");
        } else {
            IF_PAR_DEBUG(mpcomm,
                         debugBelch("send buffer size reduced to %d messages.\n",
                                    maxMsgs));
        }
    }

    bufsize = maxMsgs * DATASPACEWORDS * sizeof(StgWord);

    mpiMsgBuffer = (void*) stgMallocBytes(bufsize, "mpiMsgBuffer");

    requests = (MPI_Request*)
               stgMallocBytes(maxMsgs * sizeof(MPI_Request),"requests");

    msgCount = 0; // when maxMsgs reached

    thisPE = mpiMyRank + 1;

    IF_PAR_DEBUG(mpcomm,
                 debugBelch("Node %d synchronising.\n", thisPE));

    MPI_Barrier(MPI_COMM_WORLD); // unnecessary...
    // but currently used to synchronize system times

    return rtsTrue;
}
예제 #19
0
파일: Trace.c 프로젝트: NathanHowell/ghc
static void traceSchedEvent_stderr (Capability *cap, EventTypeNum tag, 
                                    StgTSO *tso, 
                                    StgWord info1 STG_UNUSED,
                                    StgWord info2 STG_UNUSED)
{
    ACQUIRE_LOCK(&trace_utx);

    tracePreface();
    switch (tag) {
    case EVENT_CREATE_THREAD:   // (cap, thread)
        debugBelch("cap %d: created thread %lu\n", 
                   cap->no, (lnat)tso->id);
        break;
    case EVENT_RUN_THREAD:      //  (cap, thread)
        debugBelch("cap %d: running thread %lu (%s)\n", 
                   cap->no, (lnat)tso->id, what_next_strs[tso->what_next]);
        break;
    case EVENT_THREAD_RUNNABLE: // (cap, thread)
        debugBelch("cap %d: thread %lu appended to run queue\n", 
                   cap->no, (lnat)tso->id);
        break;
    case EVENT_MIGRATE_THREAD:  // (cap, thread, new_cap)
        debugBelch("cap %d: thread %lu migrating to cap %d\n", 
                   cap->no, (lnat)tso->id, (int)info1);
        break;
    case EVENT_THREAD_WAKEUP:   // (cap, thread, info1_cap)
        debugBelch("cap %d: waking up thread %lu on cap %d\n", 
                   cap->no, (lnat)tso->id, (int)info1);
        break;
        
    case EVENT_STOP_THREAD:     // (cap, thread, status)
        if (info1 == 6 + BlockedOnBlackHole) {
            debugBelch("cap %d: thread %lu stopped (blocked on black hole owned by thread %lu)\n",
                       cap->no, (lnat)tso->id, (long)info2);
        } else {
            debugBelch("cap %d: thread %lu stopped (%s)\n",
                       cap->no, (lnat)tso->id, thread_stop_reasons[info1]);
        }
        break;
    case EVENT_SHUTDOWN:        // (cap)
        debugBelch("cap %d: shutting down\n", cap->no);
        break;
    default:
        debugBelch("cap %d: thread %lu: event %d\n\n", 
                   cap->no, (lnat)tso->id, tag);
        break;
    }

    RELEASE_LOCK(&trace_utx);
}
예제 #20
0
파일: Trace.c 프로젝트: NathanHowell/ghc
static void traceGcEvent_stderr (Capability *cap, EventTypeNum tag)
{
    ACQUIRE_LOCK(&trace_utx);

    tracePreface();
    switch (tag) {
      case EVENT_REQUEST_SEQ_GC:  // (cap)
          debugBelch("cap %d: requesting sequential GC\n", cap->no);
          break;
      case EVENT_REQUEST_PAR_GC:  // (cap)
          debugBelch("cap %d: requesting parallel GC\n", cap->no);
          break;
      case EVENT_GC_START:        // (cap)
          debugBelch("cap %d: starting GC\n", cap->no);
          break;
      case EVENT_GC_END:          // (cap)
          debugBelch("cap %d: finished GC\n", cap->no);
          break;
      case EVENT_GC_IDLE:         // (cap)
          debugBelch("cap %d: GC idle\n", cap->no);
          break;
      case EVENT_GC_WORK:         // (cap)
          debugBelch("cap %d: GC working\n", cap->no);
          break;
      case EVENT_GC_DONE:         // (cap)
          debugBelch("cap %d: GC done\n", cap->no);
          break;
      default:
          barf("traceGcEvent: unknown event tag %d", tag);
          break;
    }

    RELEASE_LOCK(&trace_utx);
}
예제 #21
0
파일: MPIComm.c 프로젝트: jberthold/ghc
/* MP_start starts up the node:
 *   - connects to the MP-System used,
 *   - determines wether we are main thread
 *   - starts up other nodes in case we are first and
 *     the MP-System requires to spawn nodes from here.
 * Parameters:
 *     IN    argv  - char**: program arguments
 * Sets:
 *           nPEs - int: no. of PEs to expect/start
 *  IAmMainThread - rtsBool: wether this node is main PE
 * Returns: Bool: success or failure
 *
 * MPI Version:
 *   nodes are spawned by startup script calling mpirun
 *   This function only connects to MPI and determines the main PE.
 */
rtsBool MP_start(int* argc, char** argv[]) {

    IF_PAR_DEBUG(mpcomm,
                 debugBelch("MPI_Init: starting MPI-Comm...\n"));

    MPI_Init(argc, argv); // MPI sez: can modify args

    MPI_Comm_rank(MPI_COMM_WORLD, &mpiMyRank);
    IF_PAR_DEBUG(mpcomm,
                 debugBelch("I am node %d.\n", mpiMyRank));

    if (!mpiMyRank) // we declare node 0 as main PE.
        IAmMainThread = rtsTrue;

    MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize);

    // we should have a correct argument...
    ASSERT(argv && (*argv)[1]);
    nPEs = atoi((*argv)[1]);

    if (nPEs) { // we have been given a size, so check it:
        IF_PAR_DEBUG(mpcomm,
                     debugBelch("Expecting to find %d processors, found %d.",
                                nPEs, mpiWorldSize));
        if ((int)nPEs > mpiWorldSize)
            IF_PAR_DEBUG(mpcomm,
                         debugBelch("WARNING: Too few processors started!"));
    } else {  // otherwise, no size was given
        IF_PAR_DEBUG(mpcomm,
                     debugBelch("No size, given, started program on %d processors.",
                                mpiWorldSize));
    }
    nPEs = mpiWorldSize; //  (re-)set size from MPI (in any case)

    // System communicator sysComm is duplicated from COMM_WORLD
    // but has its own context
    MPI_Comm_dup(MPI_COMM_WORLD, &sysComm);

    // adjust args (ignoring nPEs argument added by the start script)
    (*argv)[1] = (*argv)[0];   /* ignore the nPEs argument */
    (*argv)++;
    (*argc)--;

    return rtsTrue;
}
예제 #22
0
파일: Select.c 프로젝트: Chobbes/ghc
/* Argument 'wait' says whether to wait for I/O to become available,
 * or whether to just check and return immediately.  If there are
 * other threads ready to run, we normally do the non-waiting variety,
 * otherwise we wait (see Schedule.c).
 *
 * SMP note: must be called with sched_mutex locked.
 *
 * Windows: select only works on sockets, so this doesn't really work,
 * though it makes things better than before. MsgWaitForMultipleObjects
 * should really be used, though it only seems to work for read handles,
 * not write handles.
 *
 */
void
awaitEvent(rtsBool wait)
{
    StgTSO *tso, *prev, *next;
    fd_set rfd,wfd;
    int numFound;
    int maxfd = -1;
    rtsBool seen_bad_fd = rtsFalse;
    struct timeval tv, *ptv;
    LowResTime now;

    IF_DEBUG(scheduler,
             debugBelch("scheduler: checking for threads blocked on I/O");
             if (wait) {
                 debugBelch(" (waiting)");
             }
             debugBelch("\n");
             );
예제 #23
0
파일: Stats.c 프로젝트: Chobbes/ghc
/* -----------------------------------------------------------------------------
   stat_describe_gens

   Produce some detailed info on the state of the generational GC.
   -------------------------------------------------------------------------- */
void
statDescribeGens(void)
{
  nat g, mut, lge, i;
  W_ gen_slop;
  W_ tot_live, tot_slop;
  W_ gen_live, gen_blocks;
  bdescr *bd;
  generation *gen;
  
  debugBelch(
"----------------------------------------------------------\n"
"  Gen     Max  Mut-list  Blocks    Large     Live     Slop\n"
"       Blocks     Bytes          Objects                  \n"
"----------------------------------------------------------\n");

  tot_live = 0;
  tot_slop = 0;

  for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
      gen = &generations[g];

      for (bd = gen->large_objects, lge = 0; bd; bd = bd->link) {
          lge++;
      }

      gen_live   = genLiveWords(gen);
      gen_blocks = genLiveBlocks(gen);

      mut = 0;
      for (i = 0; i < n_capabilities; i++) {
          mut += countOccupied(capabilities[i]->mut_lists[g]);

          // Add the pinned object block.
          bd = capabilities[i]->pinned_object_block;
          if (bd != NULL) {
              gen_live   += bd->free - bd->start;
              gen_blocks += bd->blocks;
          }

          gen_live   += gcThreadLiveWords(i,g);
          gen_blocks += gcThreadLiveBlocks(i,g);
      }

      debugBelch("%5d %7" FMT_Word " %9d", g, (W_)gen->max_blocks, mut);

      gen_slop = gen_blocks * BLOCK_SIZE_W - gen_live;

      debugBelch("%8" FMT_Word " %8d %8" FMT_Word " %8" FMT_Word "\n", gen_blocks, lge,
                 gen_live*(W_)sizeof(W_), gen_slop*(W_)sizeof(W_));
      tot_live += gen_live;
      tot_slop += gen_slop;
  }
  debugBelch("----------------------------------------------------------\n");
  debugBelch("%41s%8" FMT_SizeT " %8" FMT_SizeT "\n",
             "",tot_live*sizeof(W_),tot_slop*sizeof(W_));
  debugBelch("----------------------------------------------------------\n");
  debugBelch("\n");
}
예제 #24
0
void printPtr( StgPtr p )
{
    const char *raw;
    raw = lookupGHCName(p);
    if (raw != NULL) {
        printZcoded(raw);
    } else {
        debugBelch("%p", p);
    }
}
예제 #25
0
파일: Trace.c 프로젝트: lukemaurer/ghc
static void vtrace_stderr(char *msg, va_list ap)
{
    ACQUIRE_LOCK(&trace_utx);

    tracePreface();
    vdebugBelch(msg,ap);
    debugBelch("\n");

    RELEASE_LOCK(&trace_utx);
}
예제 #26
0
파일: Printer.c 프로젝트: Seraphime/ghc
extern void DEBUG_LoadSymbols( const char *name )
{
    bfd* abfd;
    char **matching;

    bfd_init();
    abfd = bfd_openr(name, "default");
    if (abfd == NULL) {
        barf("can't open executable %s to get symbol table", name);
    }
    if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
        barf("mismatch");
    }

    {
        long storage_needed;
        asymbol **symbol_table;
        long number_of_symbols;
        long num_real_syms = 0;
        long i;

        storage_needed = bfd_get_symtab_upper_bound (abfd);

        if (storage_needed < 0) {
            barf("can't read symbol table");
        }
        symbol_table = (asymbol **) stgMallocBytes(storage_needed,"DEBUG_LoadSymbols");

        number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);

        if (number_of_symbols < 0) {
            barf("can't canonicalise symbol table");
        }

        if (add_to_fname_table == NULL)
            add_to_fname_table = allocHashTable();

        for( i = 0; i != number_of_symbols; ++i ) {
            symbol_info info;
            bfd_get_symbol_info(abfd,symbol_table[i],&info);
            if (isReal(info.type, info.name)) {
                insertHashTable(add_to_fname_table,
                                info.value, (void*)info.name);
                num_real_syms += 1;
            }
        }

        IF_DEBUG(interpreter,
                 debugBelch("Loaded %ld symbols. Of which %ld are real symbols\n",
                         number_of_symbols, num_real_syms)
                 );

        stgFree(symbol_table);
    }
}
예제 #27
0
파일: Task.c 프로젝트: Eufavn/ghc
void
printAllTasks(void)
{
    Task *task;
    for (task = all_tasks; task != NULL; task = task->all_next) {
	debugBelch("task %p is %s, ", taskId(task), task->stopped ? "stopped" : "alive");
	if (!task->stopped) {
	    if (task->cap) {
		debugBelch("on capability %d, ", task->cap->no);
	    }
	    if (task->incall->tso) {
	      debugBelch("bound to thread %lu",
                         (unsigned long)task->incall->tso->id);
	    } else {
		debugBelch("worker");
	    }
	}
	debugBelch("\n");
    }
}		       
예제 #28
0
파일: Sanity.c 프로젝트: jweijers/ghc
void findSlop(bdescr *bd)
{
    W_ slop;

    for (; bd != NULL; bd = bd->link) {
        slop = (bd->blocks * BLOCK_SIZE_W) - (bd->free - bd->start);
        if (slop > (1024/sizeof(W_))) {
            debugBelch("block at %p (bdescr %p) has %" FMT_SizeT "KB slop\n",
                       bd->start, bd, slop / (1024/sizeof(W_)));
        }
    }
}
예제 #29
0
static void
printLargeBitmap( StgPtr spBottom, StgPtr payload, StgLargeBitmap* large_bitmap, nat size )
{
    StgWord bmp;
    nat i, j;

    i = 0;
    for (bmp=0; i < size; bmp++) {
	StgWord bitmap = large_bitmap->bitmap[bmp];
	j = 0;
	for(; i < size && j < BITS_IN(W_); j++, i++, bitmap >>= 1 ) {
	    debugBelch("   stk[%" FMT_Word "] (%p) = ", (W_)(spBottom-(payload+i)), payload+i);
	    if ((bitmap & 1) == 0) {
		printPtr((P_)payload[i]);
		debugBelch("\n");
	    } else {
		debugBelch("Word# %" FMT_Word "\n", (W_)payload[i]);
	    }
	}
    }
}
예제 #30
0
파일: Stats.c 프로젝트: kod3r/ghc
void
stat_startGC (Capability *cap, gc_thread *gct)
{
    nat bell = RtsFlags.GcFlags.ringBell;

    if (bell) {
	if (bell > 1) {
	    debugBelch(" GC ");
	    rub_bell = 1;
	} else {
	    debugBelch("\007");
	}
    }

#if USE_PAPI
    if(papi_is_reporting) {
      /* Switch to counting GC events */
      papi_stop_mutator_count();
      papi_start_gc_count();
    }
#endif

    getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed);

    // Post EVENT_GC_START with the same timestamp as used for stats
    // (though converted from Time=StgInt64 to EventTimestamp=StgWord64).
    // Here, as opposed to other places, the event is emitted on the cap
    // that initiates the GC and external tools expect it to have the same
    // timestamp as used in +RTS -s calculcations.
    traceEventGcStartAtT(cap,
                         TimeToNS(gct->gc_start_elapsed - start_init_elapsed));

    gct->gc_start_thread_cpu = getThreadCPUTime();

    if (RtsFlags.GcFlags.giveStats != NO_GC_STATS)
    {
        gct->gc_start_faults = getPageFaults();
    }
}