TweetFollow Us on Twitter

Oct 95 Tips
Volume Number:11
Issue Number:10
Column Tag:Tips & Tidbits

Tips & Tidbits

By Steve Sisak, Contributing Editor

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

TIP OF THE MONTH

Spotting the Elusive Ram Disk

Here is a handy function for performing a dynamic check for the existence of a RAM disk as created by Apple’s Memory control panel. I use it in some of my programs when speed is paramount. Since the user can remove the RAM disk at any time by turning it off from the Memory control panel, and can rename it at any time, the code here must be called before using the RAM disk. In other words, don’t check just once during your application startup and assume thereafter that it will still be there, check before each access if possible. Program defensively...

- Greg Poole


HasRamDisk.h
#pragma once

#ifdef __cplusplus
 extern "C" {
#endif
 extern Boolean  HasRamDisk( FSSpecPtr ramDiskSpec );
#ifdef __cplusplus
 }
#endif

HasRamDisk.c
/******************************************************************************
    HasRamDisk.c

    A dynamic check for the existence of a RAM disk as created by Apple's
    Memory control panel. Since the user can remove the RAM disk at any time
    by turning it off from the Memory control panel, and can rename it at any
    time, the code here needs to be called before assuming the existence of
    a RAM disk. In other words, don't check just once during your application
    startup and assume thereafter that it will still be there, check 
    before each access. Program defensively...
    
    history:

    modified:  xx/xx/xx  who are you? what did you do?
    created:   08/10/94         greg poole

    Greg Poole
    Vital Images, Inc.
    505 N. 4th Street
    Fairfield, IA 52556
    (515) 472-7726
    email: greg@vitalimages.com

 ******************************************************************************/

#include <string.h>
#include "HasRamDisk.h"

// this structure is based on the DRVR definition in MPWTypes.r
//
struct DRVRresourceRec
{
    // description of drvrFlags
    //
    //    struct
    //    {
    //           unsigned hiUnused     : 1;    // unused
    //           unsigned needLock     : 1;   // lock drvr in memory
    //           unsigned needTime     : 1;   // for periodic action
    //           unsigned needGoodbye  : 1;    // call before heap reinit
    //           unsigned statusEnable : 1;      // responds to status
    //           unsigned ctlEnable    : 1;           // responds to control
    //           unsigned writeEnable  : 1;  // responds to write
    //           unsigned readEnable   : 1;  // responds to read
    //           unsigned loUnused     : 8;    // low byte of drvrFlags word unused
    //    } drvrFlags;
 
 short  drvrFlags; // flags as defined above      
 unsigned short  driverDelay; // driver delay (ticks)
 short  deskAccEventMask; // desk acc event mask
 short  driverMenuID;// driver menu ID

 unsigned short  offsetOpen;// offset to DRVRRuntime open
 unsigned short  offsetPrime; // offset to DRVRRuntime prime
 unsigned short  offsetControl;// offset to DRVRRuntime control
 unsigned short  offsetStatus;// offset to DRVRRuntime status
 unsigned short  offsetClose; // offset to DRVRRuntime close

 Str31  driverName;// driver name
 char   driverCode[1];    // driver code
};
typedef struct DRVRresourceRec DRVRresourceRec;
typedef DRVRresourceRec *DRVRresourcePtr, **DRVRresourceHndl;

// constants
//
const char kDrvrHandleBit = 0x40;  
 // bit 7 of 'DRVR' dCtlFlags signals driver is handle
    // instead of pointer and needs to be locked in memory
const char kRamDiskName[] = "\p.EDisk";// Apple's RAM disk driver name


// pass in an FSSpecPtr to hold a reference to a RAM disk,
// returns TRUE if there is currently a RAM disk, FALSE if not
//
Boolean HasRamDisk( FSSpecPtr ramDiskSpec )
{
 BooleanhasRamDisk = FALSE, isHandle = FALSE;
 short  whichVol = 1;// start with first disk volume
 HVolumeParam    volPB;
 OSErr  theErr = noErr, anErr = noErr;
 DCtlHandle dctlHndl = NULL;
 DRVRresourcePtr drvrPtr = NULL;
 DRVRresourceHndldrvrHndl = NULL;
 Ptr    aPtr = NULL;
 Str31  volName;

 do// test each mounted disk volume
 {
 volPB.ioNamePtr = volName;
 volPB.ioVRefNum = 0;// 0 means use ioVolIndex
 volPB.ioVolIndex = whichVol; // use this to determine volume
 
 if ( (theErr=PBHGetVInfoSync( (HParmBlkPtr)&volPB )) == noErr)
 {
 // get this volume's device control entry from the unit table.
    // do not lock the dctlHndl, I spent a couple of days figuring
    // out that locking this handle causes a crash in the CompServer
    // because it is locked at interrupt time...
    //
 if ( (dctlHndl = GetDCtlEntry(volPB.ioVDRefNum)) != NULL )
 {
 // is the device's driver in a handle or a pointer?
    //
 if ((isHandle=(*dctlHndl)->dCtlFlags&kDrvrHandleBit)!= 0)
 {
 drvrHndl = (DRVRresourceHndl) (*dctlHndl)->dCtlDriver;
 drvrPtr = *drvrHndl;
 }
 else
 drvrPtr = (DRVRresourcePtr) (*dctlHndl)->dCtlDriver;

 // get this device's driver, check if it is a RAM disk
    //
 if ( !memcmp( drvrPtr->driverName, kRamDiskName,  
              *kRamDiskName+1 ) )
 {
 // this driver is the RAM disk driver, create an FSSpec to its root dir
    //
 anErr = FSMakeFSSpec( volPB.ioVRefNum, fsRtDirID, 
                                 volName, ramDiskSpec );
 if ( anErr == noErr )
 hasRamDisk = TRUE;
 break;
 }
 }
 }
 whichVol++; // go to next volume
 } 
 while ( theErr != nsvErr );

 return hasRamDisk;
 
} // end HasRamDisk


// define TEST_RAM_DISK for a standalone test
//
#define TEST_RAM_DISK

#if defined( TEST_RAM_DISK )

 // local function prototypes
    //
 static void InitTheMac( void );
 
 static void InitTheMac( void )
 {
 InitGraf( &qd.thePort );
 InitFonts();
 InitWindows();
 InitMenus();
 TEInit();
 InitDialogs( 0L );
 InitCursor();
 MaxApplZone();
 
 } // end InitTheMac

 void main( void )
 {
 FSSpec ramDiskSpec; 
 BooleanhasRamDisk;
 
 InitTheMac();
 hasRamDisk = HasRamDisk( &ramDiskSpec );
 
 } // end main

#endif // TEST_RAM_DISK

Anti-Tip of the Month

Since Greg Poole won the Tip-of-the-Month I thought we could have a little fun and also give him the Anti-Tip-of-the-Month as well for a different submission. (Don’t worry, Greg, you’re getting paid for this too.)

Greg writes:

Here’s a quick and clean way to swap data in place without having to resort to using a temporary memory location:

   short *aPtr, *bPtr;

        *aPtr ^= *bPtr;
        *bPtr ^= *aPtr;
        *aPtr ^= *bPtr;

While this is mathematically cool, lets take a look at the assembly code that it generates and see what’s really happening. First, for comparison, a couple of more pedestrian implementations:

void swap2(short *aPtr, short *bPtr)
{
    short a = *aPtr;    // a version with two temporaries
    short b = *bPtr;

    *aPtr = b;
    *bPtr = a;
}

void swap1(short *aPtr, short *bPtr)
{
    short a = *aPtr;    // a version with one temporary

    *aPtr = *bPtr;
    *bPtr = a;
}

void swap0(short *aPtr, short *bPtr)
{
    *aPtr ^= *bPtr;     // Greg’s tip
    *bPtr ^= *aPtr;
    *aPtr ^= *bPtr;
}

Now, let’s take a look at what the compiler actually generates for these functions. (I’m using CodeWarrior with all optimizations on for these examples.)

Recall that as processsors have gotten faster, memory has not. For instance 1/80ns (the speed on memory in most Macintoshes) = 12.5 MHz. This means that if adjacent instructions have to address memory with no intervening computation, it’s as if the processor has slowed to 12.5MHz.

First the 68K compiler, starting with the two temp case:

Name="swap2"(6)  Size=26
    MOVEA.L   $0004(A7),A1
    MOVEA.L   $0008(A7),A0
    MOVE.W    (A1),D0
    MOVE.W    (A0),D1
    MOVE.W    D1,(A1)
    MOVE.W    D0,(A0)
    RTS

Ignoring the two MOVEA.L’s which set up the address registers and the return, this takes four instructions, all of which touch memory. Notice, however that there are no cases where the result of an instruction is used an an input to the next instruction, meaning that most of the instructions can overlap in the processor pipeline.

Next with one temp:

Name="swap1"(4)  Size=24
    MOVEA.L   $0004(A7),A1
    MOVEA.L   $0008(A7),A0
    MOVE.W    (A1),D0
    MOVE.W    (A0),(A1)
    MOVE.W    D0,(A0)
    RTS

Here we have three instructions, all accessing memory and all can overlap. This is smaller than the example above. Whether it is faster depends on the relative timing of the MOVE.W (A0),(A1) instruction. (If anyone wants to time this, I’ll print the results.)

Now Greg’s ‘tip’:

Name="swap0"(1)  Size=30
    MOVEA.L   $0004(A7),A1
    MOVEA.L   $0008(A7),A0
    MOVE.W    (A0),D0
    EOR.W     D0,(A1)
    MOVE.W    (A1),D0
    EOR.W     D0,(A0)
    MOVE.W    (A0),D0
    EOR.W     D0,(A1)
    RTS

This generates six instructions, all of which touch memory. Furthermore three of these are read-modify-write cycles, which are slower that a read or write and each instruction depends on the result of the instructon directly before it, meaning it won’t overlap in the pipeline, making this both the largest and slowest implementation of the three.

Now lets look at the PowerPC code:

Name=".swap2"(6)  Size=20
    lha      r0,0(r3)
    lha      r5,0(r4)
    sth      r5,0(r3)
    sth      r0,0(r4)
    blr

Name=".swap1"(4)  Size=20
    lha      r5,0(r3)
    lha      r0,0(r4)
    sth      r0,0(r3)
    sth      r5,0(r4)
    blr

Note that both of the versions with temporaries generated the same code (4 instructions, all touching memory but pipelineable). This is because RISC processors typically don’t have memory to memory operations; instead, they must move data to a register before operating on it.

Now our ‘tip’:

Name=".swap0"(1)  Size=52
    lha      r5,0(r4)
    lha      r0,0(r3)
    xor      r0,r0,r5
    sth      r0,0(r3)
    lha      r5,0(r3)
    lha      r0,0(r4)
    xor      r0,r0,r5
    sth      r0,0(r4)
    lha      r4,0(r4)
    lha      r0,0(r3)
    xor      r0,r0,r4
    sth      r0,0(r3)
    blr

This implementation is by far the largest and slowest, generating 12 instructions, including 6 memory accesses. Furthermore there are 2 pipeline stalls. Clearly this implementation is the largest and slowest of all.

The moral of the story is: don’t get tricky. C programmers often try to minimize the number of lines of C in their program without consideration for what the compiler will generate. When in doubt, write clear code and give the optimizer a chance to maximize performance. Look at the compiler output. Your code will be easier to debug and probably faster too.

’Till next time,

- Steve

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

TechTool Pro 12.0 - Hard drive and syste...
TechTool Pro has long been one of the foremost utilities for keeping your Mac running smoothly and efficiently. With the release of version 11, it has become more proficient than ever. Main... Read more
Tor Browser 9.0.2 - Anonymize Web browsi...
The Tor Browser Bundle is an easy-to-use portable package of Tor, Vidalia, Torbutton, and a Firefox fork preconfigured to work together out of the box. It contains a modified copy of Firefox that... Read more
Postbox 7.0.9 - Powerful and flexible em...
Postbox is a new email application that helps you organize your work life and get stuff done. It has all the elegance and simplicity of Apple Mail, but with more power and flexibility to manage even... Read more
Notion 2.0.5 - A unified workspace for m...
Notion is the unified workspace for modern teams. Notion Features: Integration with Slack Documents Wikis Tasks Note: This application contains in-app and/or external module purchases. Version 2.0... Read more
Macs Fan Control 1.5.3.9 - Monitor and c...
Macs Fan Control allows you to monitor and control almost any aspect of your computer's fans, with support for controlling fan speed, temperature sensors pane, menu-bar icon, and autostart with... Read more
CleanMyMac X 4.5.4.4 - Delete files that...
CleanMyMac makes space for the things you love. Sporting a range of ingenious new features, CleanMyMac lets you safely and intelligently scan and clean your entire system, delete large, unused files... Read more
EtreCheck Pro 6.1.6 - For troubleshootin...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
BlueStacks 4.140.12 - Run Android applic...
BlueStacks App Player lets you run your Android apps fast and fullscreen on your Mac. Feature comparison chart Version 4.140.12: Highlights/Bug Fixes: You may now switch tabs without experiencing a... Read more
ESET Cyber Security 6.8.300.0 - Basic in...
ESET Cyber Security for Mac provides powerful protection against phishing, viruses, worms, and spyware. Offering similar functionality to ESET NOD32 Antivirus for Windows, ESET Cyber Security for... Read more
Wireshark 3.0.7 - Network protocol analy...
Wireshark is one of the world's foremost network protocol analyzers, and is the standard in many parts of the industry. It is the continuation of a project that started in 1998. Hundreds of... Read more

Latest Forum Discussions

See All

Dragon Raja is an upcoming MMORPG that b...
Dragon Raja is an upcoming MMORPG from Zulong Games. It’s proven to be an extremely popular title over in China. It’s set in a very cool-looking Cyberpunk world that oozes style. It’s now available for pre-register on Android. [Read more] | Read more »
Dream Detective is an object hunting gam...
Dream Detective is a very beautiful looking object hunting game from FunPlus and Game Century. I’m generally not massively fond of these types of games but this one certainly has an art style you don’t see often that really helps it stand out. It’... | Read more »
Fighting with colonialism in Queen'...
Sometimes it’s hard to stick with a game, even if you enjoy playing it. Perhaps it’s just too stressful, perhaps it disturbs you, or—as is the case with Queen’s Wish: The Conqueror—you might not be down with its narrative conceit. | Read more »
Play Sea Turtle Rescue and help save rea...
For most of us playing a mobile game is just a harmless way to kill some time, fight boredom or get a nice quick adrenaline fix. We don’t expect this to have any influence whatsoever on any other creature in the world. | Read more »
16-bit fun awaits in Super Arcade Racing...
Old is the new ‘new’, if the popularity of retro games is anything to go by, and nostalgia junkies now have one more reason to get excited. OutOfTheBit studio has just launched a top-down racing game that pays homage to those arcade favourites of... | Read more »
Go buy Xenowerk Tactics right now
Over the Thanksgiving break, a bunch of games went on sale, but one in particular is worth talking about. Xenowerk Tactics, in addition to falling to $3, got a huge content update alongside it’s price drop. Even though the game is back up to full... | Read more »
Intense VR first-person shooter Colonicl...
Our latest VR obsession is Colonicle, an intense VR FPS, recently released on Oculus and Google Play, courtesy of From Fake Eyes and Goboogie Games. It's a pulse-pounding multiplayer shooter which should appeal to genre fanatics and newcomers alike... | Read more »
Mario Kart Tour drifts onto the streets...
Mario Kart Tour will start its latest season in a new location next week, continuing its tour around the big cities of the world after already visiting Paris, Tokyo and New York. The next destination will be London and it will also be joined by a... | Read more »
Cut The Rope's Om Nom returns in a...
Cut the Rope's little green glutton Om Nom has returned to iOS and Android for another game. Instead of a puzzle game though Om Nom: Merge is an idle game that's centred around fusing various creatures to create new species. [Read more] | Read more »
Figment: Journey Into the Mind is a surr...
Figment: Journey Into the Mind is the latest game from Bedtime Digital Games, a company with a love for the surreal and dream-like settings. Figment is no different and has puzzles designed around the concept of the left and right sides of the... | Read more »

Price Scanner via MacPrices.net

Amazon launches massive Holiday iPad sale wit...
Amazon is offering new 10.2″ iPads for $80-$100 off Apple’s MSRP and new 10.5″ iPad Airs for $100 off Apple’s MSRP as part of their Holiday 2019 sale. These are the same iPads sold by Apple in their... Read more
Holiday Sale! 11″ iPad Pros for up to $200 of...
Amazon has new Apple 11″ iPad Pros in stock today and on sale for up to $200 off Apple’s MSRP as part of their Holiday 2019 sale. These are the same iPad Pros sold by Apple in its retail and online... Read more
Roundup of current 16″ MacBook Pro sales: $20...
Apple resellers are offering sale prices on new 16″ MacBook Pros ranging up to $200 off MSRP this weekend. Other savings include free overnight delivery and no sales tax in 48 states. Here are the... Read more
13″ 1.4GHz MacBook Pros on sale for $200-$220...
B&H Photo has new 2019 13″ 1.4GHz MacBook Pros on sale for up to $220 off Apple’s MSRP as part of their Holiday 2019 sale. Overnight shipping is free to many addresses in the US: – 2019 13″ 1.... Read more
B&H Photo is offering iMacs for the lowes...
Apple reseller B&H Photo has dropped prices on new iMacs and is now offering 21″ and 27″ for up to $500 off MSRP as part of their Holiday 2019 sale. Overnight shipping is free to many locations... Read more
Take $120-$170 off the cost of a new Mac mini...
Apple resellers are offering new 2018 4-Core and 6-Core Mac minis for $120-$170 off Apple’s MSRP as part of their Holiday 2019 sales: B&H Photo has 4-Core and 6-Core Mac minis on sale for up to $... Read more
Holiday Sale! Amazon offers flat $200 discoun...
Amazon has new 2019 13″ MacBook Airs on sale for $200 off Apple’s MSRP as part of their Holiday 2019 sale, with prices starting at $899, each including free shipping. These are the same MacBook Airs... Read more
Best Buy offers deep Holiday discount on Appl...
Best Buy has Space Gray Apple HomePods on sale today for only $199.99 as part of their Holiday 2019 sale. Their price is $100 off Apple’s MSRP, and it’s the cheapest price available for a new HomePod... Read more
21″ 3.6GHz Quad-Core 4K iMac now on sale for...
B&H Photo has the 2019 21″ 3.6GHz Quad-Core 4K iMac in stock today and on sale for $1149 as part of their Cyber Week 2019 sale, including free next day shipping to many locations in the US. That’... Read more
Get a 128GB 10.2″ iPad for $50-$60 off Apple’...
B&H Photo dropped prices this afternoon on 128GB 10.2″ WiFi iPads to $50-$60 off Apple’s MSRP. Prices start at $369, and overnight shipping is free to many addresses in the US. B&H’s prices... Read more

Jobs Board

Student Employment (Blue *Apple* Cafe) Spri...
Student Employment (Blue Apple Cafe) Spring 2019 Penn State University Campus/Location: Penn State Brandywine Campus City: Media, PA Date Announced: 12/20/2018 Date Read more
Best Buy *Apple* Computing Master - Best Bu...
**744135BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Store NUmber or Department:** 000299-Crabtree-Store **Job Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**747727BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Store NUmber or Department:** 000488-Chattanooga-Store **Job Description:** At Read more
Student Employment (Blue *Apple* Cafe) Spri...
Student Employment (Blue Apple Cafe) Spring 2019 Penn State University Campus/Location: Penn State Brandywine Campus City: Media, PA Date Announced: 12/20/2018 Date Read more
*Apple* Engineer - Randstad (United States)
Apple Engineer **job details:** + location:New York, NY + salary:$120,000 - $140,000 per year + date posted:Friday, December 6, 2019 + job type:Permanent + Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.