MacPython Logo from __future__ import *

buy music albums Silver Apples buy mp3 albums Tarrus Riley buy tracks mp3 Kravits buy Reaper albums mp3 buy Kravits albums music buy music Evita CD online albums mp3 Silver Apples download Madonna CD music buy tracks music Kravits download music albums Silver Apples

2005-01-30

Disabling a CPU with the CHUD framework

Filed under: c, debugging, macosx — bob @ 2:14 pm

Xcode Tools has an optional component, CHUD Tools (Computer Hardware Understanding Development Tools), that consists of some useful performance tools and low-level hardware facilities. My Dual 2ghz G5 has been having some serious stability problems lately, with what I believe is a dying CPU or logic board. When I saw errant CPU messages in the system log after experiencing unexplicable kernel panics and crashes I decided to see what would happen if I toggled the second CPU off with the Hardware preference pane that ships with CHUD. It worked! My G5 is now usable (though I will of course still get it repaired, but it's not convenient to do so at this time).

Unfortunately, when I reboot the machine, this setting is lost and all bets are off as to whether I'll be able to disable the second CPU before the machine crashes, so I decided to look into what I could do. I opened up the Hardware preference pane nib with Interface Builder to see what message was sent to change the CPU count (unsurprisingly, setCPUCount:), then I used class-dump to find the implementation address of that message. I then did an otool disassembly of the Hardware preference pane (otool -tVv ...) so that I could see what the code looked like at that address. It called an unconspicuously named function chudSetNumProcessors from the CHUDCore.framework subframework of the umbrella CHUD.framework, which happens to ship with documented headers!

At first, I tried writing a simple C program that naively called right into chudSetNumProcessors, which returned an error code that I didn't expect (from the documentation): something about the kext not being loaded. I knew the kext was indeed loaded, because the Hardware preference pane works and I've used Shark recently, so I looked at the headers for initialization functions. Unsurprisingly, I needed to call chudInitialize before trying to talk to the CHUD kext, so I ended up with the following program:

/*
% cc -o setNumProcessors setNumProcessors.c -framework CHUD
*/

#include <unistd.h>
#include <CHUD/CHUD.h>

int main(int argc, char **argv) {
    int rval = 0;
    int status = chudInitialize();
    if (status != chudSuccess) {
        fprintf(stderr, "FATAL: Could not initialize chud, error %dn", chudInitialize());
        return -1;
    }
    if (argc == 2) {
        int cpuCount;
        int curCPUCount = chudProcessorCount();
        int physCPUCount = chudPhysicalProcessorCount();
        sscanf(argv[1], "%d", &#038;cpuCount);
        if (cpuCount < 1 || cpuCount > physCPUCount) {
            fprintf(stderr, "CPU count of %d not acceptable, expecting between 1 and %dn", cpuCount, physCPUCount);
            rval = -1;
        } else {
            int res;
            res = chudSetNumProcessors(cpuCount);
            if (res != chudSuccess) {
                fprintf(stderr, "Could not change CPU count to %d, error %dn", cpuCount, res);
                rval = -1;
            }
        }
    } else if (argc > 2) {
        fprintf(stderr, "Must take zero or one argumentsn");
        rval = -1;
    }
    printf("CPU Count: %d of %dn", chudProcessorCount(), chudPhysicalProcessorCount());
    chudCleanup();
    return -1;
}

Now I can call this setNumProcessors application early on in the boot process and increase my odds of being able to use my computer on reboot!

UPDATE: rentzsch commented with a better solution. It's also possible to disable multiprocessing even earlier by twiddling a setting in Open Firmware (QA1141).

2 Comments »

  1. Nice writeup. It’s cool CHUD can dynamically enable and disable multiprocessing. If you’re having trouble getting the machine to boot to a stage where you can run your own code, be aware you can disable the multiprocessing with Open Firmware as well.

    http://developer.apple.com/qa/qa2001/qa1141.html

    Comment by rentzsch — 2005-01-30 @ 2:23 pm

  2. Great article! Thanks

    Comment by stu — 2006-03-21 @ 3:08 am

RSS feed for comments on this post.

Leave a comment

WP-Hashcash: protecting you from spam.

Powered by WordPress