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

Microsoft Remote Desktop 8.0.19 - Connec...
With Microsoft Remote Desktop, you can connect to a remote PC and your work resources from almost anywhere. Experience the power of Windows with RemoteFX in a Remote Desktop client designed to help... Read more
OmniGraffle 6.3 - Create diagrams, flow...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
PDFKey Pro 4.3.2 - Edit and print passwo...
PDFKey Pro can unlock PDF documents protected for printing and copying when you've forgotten your password. It can now also protect your PDF files with a password to prevent unauthorized access and/... Read more
Ableton Live 9.2.2 - Record music using...
Ableton Live lets you create and record music on your Mac. Use digital instruments, pre-recorded sounds, and sampled loops to arrange, produce, and perform your music like never before. Ableton Live... Read more
Macs Fan Control 1.3.1.0 - 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
NetShade 6.3.1 - Browse privately using...
NetShade is an anonymous proxy and VPN app+service for Mac. Unblock your Internet through NetShade's high-speed proxy and VPN servers spanning seven countries. NetShade masks your IP address as you... Read more
Dragon Dictate 4.0.7 - Premium voice-rec...
With Dragon Dictate speech recognition software, you can use your voice to create and edit text or interact with your favorite Mac applications. Far more than just speech-to-text, Dragon Dictate lets... Read more
Persecond 1.0.2 - Timelapse video made e...
Persecond is the easy, fun way to create a beautiful timelapse video. Import an image sequence from any camera, trim the length of your video, adjust the speed and playback direction, and you’re done... Read more
GIMP 2.8.14p2 - Powerful, free image edi...
GIMP is a multi-platform photo manipulation tool. GIMP is an acronym for GNU Image Manipulation Program. The GIMP is suitable for a variety of image manipulation tasks, including photo retouching,... Read more
Sandvox 2.10.2 - Easily build eye-catchi...
Sandvox is for Mac users who want to create a professional looking website quickly and easily. With Sandvox, you don't need to be a Web genius to build a stylish, feature-rich, standards-compliant... Read more

ReBoard: Revolutionary Keyboard (Utilit...
ReBoard: Revolutionary Keyboard 1.0 Device: iOS Universal Category: Utilities Price: $1.99, Version: 1.0 (iTunes) Description: Do everything within the keyboard without switching apps! If you are in WhatsApp, how do you schedule a... | Read more »
Tiny Empire (Games)
Tiny Empire 1.1.3 Device: iOS Universal Category: Games Price: $2.99, Version: 1.1.3 (iTunes) Description: Launch cannonballs and blow tiny orcs into thousands of pieces in this intuitive fantasy-themed puzzle shooter! Embark on an... | Read more »
Astropad Mini (Productivity)
Astropad Mini 1.0 Device: iOS iPhone Category: Productivity Price: $4.99, Version: 1.0 (iTunes) Description: *** 50% off introductory price! ​*** Get the high-end experience of a Wacom tablet at a fraction of the price with Astropad... | Read more »
Emo Chorus (Music)
Emo Chorus 1.0.0 Device: iOS Universal Category: Music Price: $1.99, Version: 1.0.0 (iTunes) Description: Realistic Choir simulator ranging from simple Chorus emulation to full ensemble Choir with 128 members. ### introductory offer... | Read more »
Forest Spirit (Games)
Forest Spirit 1.0.5 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.5 (iTunes) Description: | Read more »
Ski Safari 2 (Games)
Ski Safari 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The world's most fantastical, fun, family-friendly skiing game is back and better than ever! Play as Sven's sister Evana, share... | Read more »
Lara Croft GO (Games)
Lara Croft GO 1.0.47768 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.47768 (iTunes) Description: Lara Croft GO is a turn based puzzle-adventure set in a long-forgotten world. Explore the ruins of an ancient... | Read more »
Whispering Willows (Games)
Whispering Willows 1.23 Device: iOS Universal Category: Games Price: $4.99, Version: 1.23 (iTunes) Description: **LAUNCH SALE 50% OFF** - Whispering Willows is on sale for 50% off ($4.99) until September 9th. | Read more »
Calvino Noir (Games)
Calvino Noir 1.1 Device: iOS iPhone Category: Games Price: $3.99, Version: 1.1 (iTunes) Description: The film noir stealth game. Calvino Noir is the exploratory, sneaking adventure through the 1930s European criminal underworld.... | Read more »
Angel Sword (Games)
Angel Sword 1.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.0 (iTunes) Description: Prepare to adventure in the most epic full scale multiplayer 3D RPG for mobile! Experience amazing detailed graphics in full HD.... | Read more »

Price Scanner via MacPrices.net

Apple and Cisco Partner to Deliver Fast-Lane...
Apple and Cisco have announced a partnership to create a “fast lane” for iOS business users by optimizing Cisco networks for iOS devices and apps. The alliance integrates iPhone with Cisco enterprise... Read more
Apple offering refurbished 2015 13-inch Retin...
The Apple Store is offering Apple Certified Refurbished 2015 13″ Retina MacBook Pros for up to $270 (15%) off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
Apple refurbished 2015 MacBook Airs available...
The Apple Store has Apple Certified Refurbished 2015 11″ and 13″ MacBook Airs (the latest models), available for up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $999.99 $100 off - 21″ 2.7GHz iMac: $1199.99 $100 off - 21″ 2.9GHz iMac... Read more
5K iMacs on sale for up to $150 off MSRP, fre...
B&H Photo has the 27″ 3.3GHz 5K iMac on sale for $1899.99 including free shipping plus NY tax only. Their price is $100 off MSRP. They have the 27″ 3.5GHz 5K iMac on sale for $2149.99 $2199.99, $... Read more
1.4GHz Mac mini, refurbished, available for $...
The Apple Store has Apple Certified Refurbished 1.4GHz Mac minis available for $419. Apple’s one-year warranty is included, and shipping is free. Their price is $80 off MSRP, and it’s the lowest... Read more
iPad Air 2 on sale for up to $100 off MSRP
Best Buy has iPad Air 2s on sale for up to $100 off MSRP on their online store for a limited time. Choose free shipping or free local store pickup (if available). Sale prices available for online... Read more
MacBook Airs on sale for $100 off MSRP
Best Buy has MacBook Airs on sale for $100 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Sale prices for online orders only, in-store prices may vary... Read more
Big Grips Lift Handle For iPad Air and iPad A...
KEM Ventures, Inc. which pioneered the extra-large, super-protective iPad case market with the introduction of Big Grips Frame and Stand in 2011, is launching Big Grips Lift featuring a new super-... Read more
Samsung Launches Galaxy Tab S2, Its Most Powe...
Samsung Electronics America, Inc. has announced the U.S. release of the Galaxy Tab S2, its thinnest, lightest, ultra-fast tablet. Blending form and function, elegant design and multitasking power,... Read more

Jobs Board

*Apple* Evangelist - JAMF Software (United S...
The Apple Evangelist is responsible for building and cultivating strategic relationships with Apple 's small and mid-market business development field teams. This Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Desktop Analyst - KDS Staffing (Unit...
…field and consistent professional recruiting achievement. Job Description: Title: Apple Desktop AnalystPosition Type: Full-time PermanentLocation: White Plains, NYHot Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
Title: Apple Systems Engineer (Mclean, VA and NYC) Location: United States-New York-New York-200 Park Ave (22005) Other Locations: United States-Virginia-Vienna-Towers Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
…Assist in providing strategic direction and technical leadership within the Apple portfolio, including desktops, laptops, and printing environment. This person will Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.