TweetFollow Us on Twitter

Demystifying The GS/OS Cache

Demystifying The GS/OS Cache

MATT DEATHERAGE

GS/OS has given Apple IIgs users an important capability: caching. To the newly initiated, the mysteries of the GS/OS cache may still seem profound. This article clarifies the basics of the caching algorithm and offers useful pointers for working safely and efficiently.


In the past couple of years, the Apple IIgs system software has grown by leaps and bounds. With the introduction of thousands of new features and capabilities, one very important one often goes unnoticed. GS/OS is the first Apple II operating system of any kind to provide a comprehensive caching implementation.

Although the cache is an important part of GS/OS, its purpose and nature are sometimes misunderstood. Some people create huge caches in the hope that peripherals will start behaving like RAM disks. Others set the cache size to zero because they think it's wasting time and memory. Some developers mistakenly believe their program has absolute control over caching, which is only true if they're writing device drivers. This article reaches into the murky depths of your IIgs's memory and allows you to examine the cache in the light you would normally use, say, to read develop by.

CACHE FUNDAMENTALS

Let's start at the beginning, with the basics. What's a cache? How is it managed? How big is it? How does the GS/OS cache differ from that of the Macintosh? Read on.

WHAT'S A CACHE?
A cache is a part of memory in which the operating system can keep a spare copy of information read from and written to a device, in an attempt to decrease disk access time.

Many people use RAM disks to decrease disk access time. Because the operating system doesn't actually have to physically manipulate any media to access information on a RAM disk, the information is saved and retrieved at a very nice clip, exceeded only by the speed at which the operating system can read information already in main memory. In a caching algorithm, that is exactly what happens.

When information is read from a device, the operating system reads from the physical media and returns the information to the caller who asked for it. Additionally, the operating system keeps a spare copy of the information in the cache. The next time a caller requests information, the operating system first looks in the cache to see if it already has it from a previous media access. If it's there, the operating system simply moves the data into the caller's buffer, completing the call without having to actually read anything from disk.

Information to be written can also be cached. The operating system writes the information to the disk and also writes it to the cache. This method, called a write-through cache, ensures that the information in the cache is never more recent than the information on the disk. GS/OS uses a write- through cache except in one special situation--during a write-deferral session.

THE CACHE MANAGER AND WHAT IT CACHES
In GS/OS, several distinct managers handle different parts of the operating system or environment. Many of these managers (the Loader and the Device Manager, for example) are familiar to application and driver authors. Another, more obscure manager takes care of the cache; plainly enough, it's called the Cache Manager. The Cache Manager handles the storage of the cache and all requests involving it.

The GS/OS Cache Manager only caches one thing: blocks. Blocks are what both generated and loaded drivers read from block devices. They can be traditional ProDOS-sized 512-byte blocks from traditional ProDOS devices; they can be 512-byte blocks from nontraditional ProDOS devices, such as network volumes or nondisk devices; or they can be odd-sized blocks from odd peripherals. If you had a GS/OS loaded driver to read 981-byte blocks from a 20-gigahertz, 35-terabyte RAM disk hooked to your Apple IIgs through a slot-based card, GS/OS could cache those blocks. (Whether or not any file system translators in the system could use the device is another story.) The Cache Manager does not cache anything having to do with printers, modems, or other character devices.

THE SIZE OF THE CACHE
The size of the cache is determined by a battery RAM (BRAM) parameter. When the Cache Manager is initialized as part of the GS/OS boot process, it retrieves this value from the battery backed-up RAM and adjusts so that the given value is taken as the maximum size to which the cache can grow. The BRAM parameter is currently number $81 and represents the cache size in 32K increments (a value of 2 would indicate 64K). You should know that the location and interpretation of the cache size parameter are not guaranteed at this point, and relying on the location or interpretation of the parameter might get you into trouble. When they are guaranteed, Apple II Developer Technical Support will release a Technical Note detailing this point, or the GS/OS Reference will be revised to document it.

The size of the cache is not an exact number but an exact maximum, and it is that only when nonzero. If the user has set the cache size to nonzero, that value (which will always be an increment of 32K) is the maximum cache size. If the user has set the cache size to zero, GS/OS allocates a 16K cache for system purposes--so that system components such as file system translators (FSTs) and drivers (both generated and loaded) can take advantage of the speed increase the cache provides. There is no way to completely turn off caching under GS/OS.

When the cache is initialized, it is empty and has zero size. As blocks are added to it, it grows as necessary to accommodate the increased use until the maximum size is reached. If no one ever asks for blocks to be cached, the cache remains empty and occupies no memory.

WHAT HAPPENS WHEN THE CACHE IS FULL
Having a maximum cache size implies that there can be a problem -- what happens when nothing else can be written to the cache because there is no room in cache memory for more information? How does GS/OS behave when there's no room in the Cache Inn?

The operating system, through the cache algorithm, has a few options for handling the possibility that the cache will be full. The most obvious option is for the algorithm to shrug its bit-encoded shoulders and say, "Well, the cache is full, so nothing else will be written to it." Information that comes knocking at the door thereafter is written to disk only and read from disk each time it's needed.

Most caching algorithms, including the one used by GS/OS, are a little bolder. They attempt to identify which blocks in the cache have actually been used and to keep those blocks in the cache, simultaneously removing from the cache the blocks that have not been used. The rationale for this is that if a block hasn't been read from the cache in a long time, it's probable that no one's going to want to read it again for a while, and the cache can be better used by a new block. For example, when GS/OS is booted, the file START.GS.OS is read from the disk. Suppose, for the sake of argument, that this file's information was placed in the cache. This file isn't likely to be read again by the operating system or by any application unless GS/OS has to be reloaded, which under version 5.0 and later never happens. This file could, therefore, be sitting in the cache, taking up valuable cache space that subsequently can't be used by directory blocks, bitmap blocks, or even program files that will be needed repeatedly, such as the Finder or APW commands. The strategy used by most caching algorithms tries to keep space in the cache free for use by directory blocks, bitmap blocks, and program files that will be needed repeatedly.

One popular caching algorithm keeps all the blocks in a chain with the most-recently used block at the beginning of the chain and the block not used for the longest time at the end. When there's no more room in the cache, the blocks at the end of the chain are removed, making room for new blocks. This algorithm, straightforwardly called a least-recently used (LRU) caching algorithm, is what GS/OS uses.

Some blocks, however, can't be kicked out of the cache by the LRU algorithm. These are the blocks placed in the cache by a write-deferral session. When such a session is in progress, some or all of the information written to files is write-deferred, which means GS/OS keeps the information around in the cache instead of taking the time to write it all to physical media. This is accomplished in different ways for different file systems; each file system translator behaves in the way it can achieve the best performance during a session. For example, the ProDOS FST writes actual data to the disk but not system-level information such as directories or bitmap blocks.

If any write-deferred blocks are in the cache, the Cache Manager will not purge them to make room for new blocks until they have been written to disk. If the cache fills up with nonpurgeable blocks and another nonpurgeable block must be added, a feature known as AutoFlush, which was new to System Software 5.0, takes over, stops the session, and flushes all write-deferred blocks to disk so that new ones can be added. This has the effect of breaking a session into lots of mini-sessions, each exactly long enough to get the best possible use from the cache.

Blocks in the cache can also be deleted from it by another method besides the LRU algorithm. If a driver detects a disk-switched condition, which normally means that an on-line volume has been taken off-line, it makes the SET_DISKSW.System Service call, which enables the file system translators to remove all blocks belonging to the switched disk from the cache so that no blocks are in the cache for volumes that aren't currently on-line. This ensures that no one accidentally reads from the device and gets an old block from the cache, or that no blocks are in the cache for volumes that aren't currently on-line.

DIFFERENCES FROM THE MACINTOSH
The GS/OS Cache Manager is different from the caching implementation on the Macintosh in two important ways. The first difference is in the way memory is allocated. On the Macintosh, if the user sets the disk cache size to 128K, a 128K block of memory stays allocated for the disk cache unless someone resizes the cache. Under GS/OS, memory for cached blocks is allocated as needed up to the maximum set by the user. The other difference between GS/OS and Macintosh is in the size of the blocks that can be cached. The GS/OS cache can handle a block of any size; if a device deals in 2048-byte blocks--as some CD-ROM discs do--GS/OS will cache a 2048-byte block. The Macintosh Cache Manager, on the other hand, can only cache 512-byte blocks.

HOW APPLICATIONS REQUEST TO USE THE CACHE
Applications--or desk accessories, inits, or anyone who makes GS/OS system calls--request to use the cache through cache-related parameters to the system calls. Specifically, applications can ask that data read from files be cached by using the cachePriority field of class one (and only class one)Read and Write calls.

CACHING CAN BE REQUESTED BY CLASS ONE CALLS
An application requests caching by setting the cachePriority field in the GS/OS parameter block of Read and Write calls. (These are the only two GS/OS system calls with this field in the parameter block. The system calls DRead and DWrite do not have a cachePriority field, as the Device Manager always disables caching of blocks read or written through these calls.)

A value of $0000 for the word-length parameter in the cachePriority field is the norm (and the default if this parameter is omitted) and indicates that blocks involved in this call should not be cached. A value of $0001 identifies the blocks involved as candidates for caching. Only a value of $0001 in this field will cause files read at the application level to be considered for caching.

The fact that a caching request has been made by an application doesn't mean that it will be fulfilled. Applications do not call the Cache Manager; other system components do. Those components (file system translators and drivers) may deny the request when it doesn't make sense or is dangerous for the file's blocks to be cached.

CACHING CANNOT BE REQUESTED BY CLASS ZERO CALLS
Applications written using class zero calls (including older ProDOS 16 applications) cannot request that their files be placed in the cache. To make such a request, the application must be changed to use class one calls. At first this seems a little harsh and arbitrary, but it's quite the opposite. GS/OS could treat class zero file calls one of two ways--it could automatically cache everything, or automatically cache nothing. If it cached everything, reading any file larger than the maximum cache size would flush all the cached blocks, no matter how frequently they were used. This would force them all to be reread from disk the next time they were needed. Such a method is normally a grand waste of time, since most files on the Apple IIgs are typically read once. Most programs still follow the old Apple II method of "read the file, modify it, and write it back," and writing such files to the cache only serves to slow things down while the flushed blocks are reread from disk. Better methods for file manipulation exist these days, but the system was designed for maximum performance using the methods of the time.

An application knows best which files it will be reading from disk often enough to benefit from caching. Such decisions are often reached after long performance studies of cached reads vs. purgeable handles in memory. For more pointers on application-level caching, see GS/OS Technical Note #3, Pointers on Caching.

WRITE-DEFERRAL SESSIONS AND THE CACHE
Applications can also speed up disk-intensive operations through the use of write-deferral sessions. An application begins such a session by giving the GS/OS system call BeginSession. This places all subsequent writes in a mode where some or all of the blocks written to disk are placed only in the cache and not on the media.

Deferred blocks are then written to the media when the EndSession call is made. If theEndSession call is not made or if it's made before the files being written to are closed, some of the blocks for the files written may be on the disk while others are in the cache only. This damages disks in most file systems as fast as fingerprints on the media. Be sure to always issue EndSession calls on every exit path after a BeginSession call to prevent blocks written from being only in the cache and not on the disk. And be sure to close all open files before calling EndSession, since the operating system can get caught with write-deferred blocks in open files if the session is ended and the disk is ejected before the files are closed.

HOW CACHE REQUESTS ARE FULFILLED

GS/OS attempts to make sure that although an application can cache blocks if it so chooses, by default the most intelligent use possible of the caching capabilities will be made. It does this by filtering out possibly bogus requests for caching at several levels. When an application makes a request to use the cache, the request is filtered through drivers and/or file system translators. These agents of the Cache Manager evaluate requests to make sure that the most intelligent possible use of the caching capability is made. If an application's request to use the cache is found to be valid, one of these system components calls a System Service routine to add blocks to the cache.

THE SYSTEM SERVICE CALLS
The ultimate caching authority is at the System Service call level. System Service calls are used by drivers and file system translators to access the routines that act on cache requests. These calls are available only to drivers and file system translators; they are not available to applications. System Service calls are accessed through vectors in the $01/FC00 page and are described in the GS/OS Reference , volume 2, chapter 12.

The following four System Service calls--to add blocks, find blocks in the cache, move blocks in and out of the cache, and remove all purgeable blocks in the cache belonging to a switched disk--are the only calls that can be made by drivers. Other cache-related System Service calls enable the system to delete blocks and volumes from the cache, but these are not documented in the GS/OS Reference and can only be used by file system translators and other Apple-supplied system components.

CACHE_ADD_BLK ($01/FC08) is the System Service call for a routine that adds blocks to the cache. This call takes several parameters on GS/OS direct page (which is available to drivers and file system translators but not to applications), including information to identify the block by volume, device number, size and block number, and whether or not a write-deferral session is in progress. The Cache Manager is called, and it adds the block to the cache with no filtering. If necessary, the entire purgeable cache (the cache size minus all nonpurgeable write-deferred blocks) will be purged to add the block. The call will return with an error if a block could not be added to the cache, most likely because the entire purgeable cache was smaller than the block to be cached.

CACHE_FIND_BLK ($01/FC04) is the System Service call for a routine that finds blocks in the cache. It will search the cache for a specified block, returning a pointer to it if it is found. The cache can be searched by device number, so a device driver can find all blocks it has cached, or by volume ID, so that a file system translator can find all blocks it has cached (when a write-deferral session is in progress).

MOVE_INFO is the System Service call for a memory-moving routine. This routine is called by drivers and file system translators to move data in and out of the cache.

SET_DISKSW is the System Service call for a routine that kicks out all purgeable blocks in the cache belonging to a switched disk. If SET_DISKSW is called while a write-deferral session is in progress involving closed files on that device, GS/OS puts up a dialog box warning that the disk was prematurely ejected and that the disk's structure may be damaged.

There are two main parts of GS/OS that can use these System Service calls -- drivers and file system translators.

THE ROLE PLAYED BY DRIVERS
Drivers filter cache requests passed on from the application and file system translator levels. With every Driver_Read and Driver_Write command a driver gets from an application, it is passed instructions to take one of three possible caching actions:

  • If the cachePriority word (on GS/OS direct page) is $0000, the block being read or written should not be cached.
  • If cachePriority is nonzero with the high bit clear ($0001--$7FFF), the block should be cached as a normal, purgeable block.
  • If cachePriority has the high bit set ($8000-$FFFF), the block should be cached as a deferred nonpurgeable block. This means a write-deferral session is in progress. In this case, which is only valid for Driver_Write calls (there are no read-deferral sessions in GS/OS), the driver should write the requested block only to the cache and not to the physical media. The end of the session will result in the driver being called again to write all the cached blocks to the physical media.

There are instances, such as identifying volumes, in which a file system translator might wish to force a read from physical media rather than from the cache (if the block is in it). In these cases, the FST ID number on GS/OS direct page has the high bit set, telling drivers not to read the block from the cache.

A driver is not obligated to cache blocks when requested to, but instead can decide to disable caching completely or selectively. In some cases, the driver should refuse to cache any blocks. For example, this would be appropriate if the driver is for a device that cannot identify a disk-switched condition with any degree of reliability, as with a 5.25" disk. Since the driver can't call SET_DISKSW until it notices the disk has been switched--which could be well after the fact--a block in the cache for such a device might not be deleted when it should be, and thus the driver should refuse to cache any blocks in the first place. Or for example, if a driver can actually read from the media faster than a block can be returned from the cache, it should refuse to cache blocks.

THE ROLE PLAYED BY FILE SYSTEM TRANSLATORS
File system translators can initiate cache requests themselves, and can filter cache requests passed on from the application level.

When a file is opened and read or written, not all of the requests to a driver for information from the physical media are requests for data blocks from the file in question. Many of the read and write requests are for directories, file-system-specific data structures--such as key blocks and index blocks in ProDOS--and bitmap blocks. File system translators need these data structures repeatedly during file operations, and may ask that the blocks involved be cached. The ProDOS FST does this, caching all blocks it reads and writes that aren't passed on to the application. If the caching can be done, the file system translator gets much faster response time the next time it needs those blocks. On ProDOS disks, the caching of the volume directory and volume bitmap give tremendous speed increases since every file opening causes a read of the volume directory, and every write operation causes a read and write of the volume bitmap.

The file system translator may also cause caching of a different variety. When a write-deferral session is enabled, the file system translator changes the cachePriority field it passes to the drivers so that blocks are marked as write-deferred. This places them in the cache in a nonpurgeable state but not on the disk. The ProDOS FST asks that all of its ProDOS-specific directory, index, and bitmap blocks be placed in the cache write-deferred, but that all pure data blocks go straight out to disk without caching. This enables most devices to write data to contiguous areas of the disk, so that the head doesn't need to move back and forth writing directories and index blocks and updating bitmaps. All of that is done in one burst at the end of the session. Other file system translators may use the cache during sessions in ways that make sense for that particular file system. For example, the AppleShare FST handles caching in a completely different way, not involving the GS/OS cache at all, since the media could change on the server from another workstation. Most file system translators, however, use the GS/OS cache in ways similar to the way the ProDOS FST uses it.

A file system translator can deny an application's caching request if it interferes with optimal system performance. For example, caching a ProDOS file being copied to a ProDOS disk during a session would slow things down, since cached file blocks would be continually removed from a full cache to make room for more write-deferred system blocks from the ProDOS FST. Write-deferral sessions are usually used to copy large numbers of files or create them from memory. In either case, the files in question aren't likely to be read again, so the ProDOS FST eliminates possible overhead by denying requests to cache files during write-deferral sessions.

RESETTING THE CACHE FROM THE APPLICATION
Only one application-level call acts only on the cache--the ResetCache call (class one only, call number $2026). This call forces the cache to be reinitialized, purging all blocks that are in it and resizing if necessary. Do not issue this call while a write-deferral session is in progress; you can use SessionStatus to see if a write-deferral session is currently active.

If you're writing a utility program and suspect that an file system translator has cached something you don't really want around, calling ResetCache will ensure the cache is flushed. The cache is also resized from the battery RAM parameter. As discussed earlier, this parameter is currently $81 and represents the cache size in 32K increments, but this is not guaranteed. ResetCache is called by the RAM CDev to change the size of the cache.

To make the call, simply issue it with a parameter block pointer to a word of $0000. There are no parameters.

WHERE TO GO FROM HERE
This article has described the basics of the GS/OS cache, and has given you an idea of how an application requests caching and how such a request is fulfilled (or not fulfilled, if the request turns out not to be in the best interests of the system).

If you want to experiment with the effects of GS/OS calls that request caching, play around with these calls in the Exerciser that comes on the GSBug disk. That's why it's there. It's come a long way from the ProDOS 16 Exerciser. It makes all the calls (inline or stack-based, any class, with the exception of ResetCache), lists all devices, and catalogs directories to 255 levels. It also lets you choose any number of parameters for any class one call, except ResetCache, and allows you to modify memory through a built-in editor--you can visit the Monitor and return if you so choose. (Incidentally, the new calls for System Software 5.0 are coming in a revision soon.)

As always, help to Apple Partners on all matters, including GS/OS, is available on AppleLink and MCIMail from Apple II Developer Technical Support at the address AIIDTS. (Macintosh developers can contact Macintosh Developer Technical Support at AppleLink address MACDTS or MCIMail address MACTECH.) If you're not an Apple Partner, you can often get help from knowledgeable programmers on third-party online services, usually in the "Developers" or"Development" forum.

MATT DEATHERAGE says, "You always want what you can't get," and the thing he wants most is sleep. This desire probably started in his college days while studying industrial engineering at the University of Oklahoma. In his far too many waking hours he's an Apple II DTS engineer, a self-proclaimed nonhardware person. "Eat lots of toast" is his motto and the ideal to which he aspires (thanks to his friend Robert Thurman). When he's not gobbling toast or snoozing, he can be found writing music (on the Apple IIGS, naturally) or playing the piano, the clarinet, or the bass clarinet. He isn't married, as far as he can tell. *

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Adobe Acrobat Reader 20.012.20041 - View...
Adobe Acrobat Reader allows users to view PDF documents. You may not know what a PDF file is, but you've probably come across one at some point. PDF files are used by companies and even the IRS to... Read more
Adobe Acrobat DC 20.012.20041 - Powerful...
Acrobat DC is available only as a part of Adobe Creative Cloud, and can only be installed and/or updated through Adobe's Creative Cloud app. Adobe Acrobat DC with Adobe Document Cloud services is... Read more
Sketch 68 - Design app for UX/UI for iOS...
Sketch is an innovative and fresh look at vector drawing. Its intentionally minimalist design is based upon a drawing space of unlimited size and layers, free of palettes, panels, menus, windows, and... Read more
Bean 3.3.1 - Fast and uncluttered word p...
Bean is no longer being actively developed, but will be updated as necessary to patch bugs and maintain OS X compatibility Bean is lean, fast, and uncluttered. If you get depressed at the thought... Read more
RetroArch 1.9.0 - Game emulator.
RetroArch is most popularly known for being a program with which you can play many emulators and games, which have all been customized and tailor-ported to the libretro API. It is designed to be fast... Read more
NetNewsWire 5.0.4 - RSS and Atom news re...
NetNewsWire is the best way to keep up with the sites and authors you read most regularly. Let NetNewsWire pull down the latest articles, and read them in a distraction-free and Mac-like way. Native... Read more
EarthDesk 7.4.5 - $24.99
EarthDesk replaces your static desktop picture with a rendered image of Earth showing correct sun, moon, and city illumination. With an Internet connection, EarthDesk displays near-real-time global... Read more
BetterTouchTool 3.401 - Customize multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom)... Read more
Vienna 3.5.6 :e12c952d: - RSS and Atom n...
Vienna is a freeware and Open-Source RSS/Atom newsreader with article storage and management via a SQLite database, written in Objective-C and Cocoa, for the OS X operating system. It provides... Read more
WhatsApp 2.2031.5 - Desktop client for W...
WhatsApp is the desktop client for WhatsApp Messenger, a cross-platform mobile messaging app which allows you to exchange messages without having to pay for SMS. WhatsApp Messenger is available for... Read more

Latest Forum Discussions

See All

Scrappers receives a major update that a...
Q-Games' Scrappers has received a fairly sizeable new update that adds fresh gameplay features and a host of quality-of-life tweaks. [Read more] | Read more »
Motorball is a car football game from No...
A few years back Noodlecake Studios announced that they would be dipping in the multiplayer gaming realm with two different games. The first of those, Golf Blitz, released a while back and has proven to be very popular. Now, the second has arrived... | Read more »
SINoALICE's latest update introduce...
SINoALICE's latest update has now arrived, adding several fan-favourite characters from popular RPG series NieR. Young Nier, Kaine, and Young Emil are available in-game as part of a limited-time crossover event set to run until August 20th. [Read... | Read more »
Rocat Jumpurr is an intense roguelite pl...
Rocat Jumpurr is a roguelite platformer from developer Mousetrap Games. You might already be familiar with it if you follow the Big Indie Pitch, where it won first place during this year's Pocket Gamer Connects London competition. Following its... | Read more »
PUBG Mobile's Play As One campaign...
Back in mid-July, we reported that PUGB Mobile had teamed up with Direct Relief to help raise money for the charity's COVID-19 response project. It focused on an in-game running challenge for players, which lead to the PUBG Mobile donating $2... | Read more »
Marvel Contest of Champions' latest...
Marvel Contest of Champions' latest motion comic has arrived, and it shows off new fighters Air-Walker and Dragon Man. Both characters are set to arrive in-game this month. [Read more] | Read more »
Clash Royale: The Road to Legendary Aren...
Supercell recently celebrated its 10th anniversary and their best title, Clash Royale, is as good as it's ever been. Even for lapsed players, returning to the game is as easy as can be. If you want to join us in picking the game back up, we've put... | Read more »
Global Spy is an intriguing 2D spy sim f...
Developer Yuyosoft Innovations' Global Spy launched last month for iOS and Android, though if you missed it at the time, we're here to tell you why it's well worth a go. This one's all about international espionage, tracking down elusive spies,... | Read more »
Distract Yourself With These Great Mobil...
There’s a lot going on right now, and I don’t really feel like trying to write some kind of pithy intro for it. All I’ll say is lots of people have been coming together and helping each other in small ways, and I’m choosing to focus on that as I... | Read more »
Hyena Squad is sci-fi turn-based strateg...
Wave Light Games has just revealed its latest release, Hyena Squad, a turn-based RPG set in a space station infested by gross aliens and the living dead. The announcement was first reported on by Touch Arcade. [Read more] | Read more »

Price Scanner via MacPrices.net

Apple drops prices on clearance 27″ 5K iMacs,...
Apple has dropped prices on Certified Refurbished 2019 27″ iMacs to a new low of $1439 and up to $520 off their original MSRP. Apple’s one-year warranty is standard and shipping is free. The... Read more
Price drop: Clearance 8-core iMac Pro for $38...
Apple has dropped their price on Certified Refurbished 27″ 3.2GHz 8-Core iMac Pros to $3819 including free shipping. Their price is $1180 off the original MSRP of new models. A standard Apple one-... Read more
Monday sale: New 13″ 2.0GHz MacBook Pros for...
Amazon has new 2020 13″ 2.0GHz/512GB MacBook Pros back in stock on sale today for $200 off Apple’s MSRP. Shipping is free. Be sure to purchase the MacBook Pro from Amazon, rather than a third-party... Read more
Sale! Apple’s 16″ MacBook Pros for up to $349...
Apple Authorized Reseller Adorama has new 2019 16″ MacBook Pros in stock on sale today for $100-$349 off Apple’s MSRP, each including free shipping. Their prices for 8-core models ($349 off) are the... Read more
Save hundreds of dollars on a custom-configur...
Save up to $920 on a custom-configured 16″ MacBook Pro with these Certified Refurbished models that Apple has restocked today. Each MacBook Pro features a new outer case, free shipping, and includes... Read more
New 2020 12.9″ iPad Pros on sale for up to $8...
Apple reseller Expercom has new 2020 Apple 12.9″ iPad Pros on sale today for $60-$85 off MSRP, with prices starting at $939. These are the same iPad Pros sold by Apple in their retail and online... Read more
Woot offers numerous 2018-2020 MacBook Pros a...
Amazon-owned Woot has many open-box return MacBook Airs and MacBook Pros available today at prices starting at $879. Shipping is free for Prime members. Here’s what they have as of this post, and... Read more
Apple restocks refurbished 2020 13″ MacBook A...
Apple has restocked Certified Refurbished 2020 13″ MacBook Airs starting at only $849 and up to $200 off the cost of new Airs. Each MacBook features a new outer case, comes with a standard Apple one-... Read more
Apple restocks clearance 2019 13″ 2.4GHz MacB...
Apple has restocked Certified Refurbished 2019 13″ 2.4GHz 4-Core Touch Bar MacBook Pros starting at $1359 and up to $560 off original MSRP. Apple’s one-year warranty is included, shipping is free,... Read more
Apple restocks refurbished iPhone XR models s...
Apple has restocked Certified Refurbished, unlocked, iPhone XR models in the refurbished section of their online store starting at $539. Each iPhone comes with Apple’s standard one-year warranty,... Read more

Jobs Board

Cub Foods - *Apple* Valley - Now Hiring Par...
Cub Foods - Apple Valley - Now Hiring Part Time! United States of America, Minnesota, Apple Valley New Retail Post Date 6 days ago Requisition # 122305 Sign Up Read more
Director of *Apple* Enterprise Operations -...
## Description JOB SUMMARY: The Director of Apple Enterprise Operations is responsible for developing and managing the overall strategy, operation and management of Read more
Cub Foods - *Apple* Valley - Now Hiring Par...
Cub Foods - Apple Valley - Now Hiring Part Time! United States of America, Minnesota, Apple Valley New Retail Post Date 5 days ago Requisition # 122305 Sign Up Read more
Blue *Apple* Cafe Student Worker - Fall - P...
…to enhance your work experience. Student positions are available at the Blue Apple Cafe. Employee meal discount during working hours is provided. Duties include food Read more
Cub Foods - *Apple* Valley - Now Hiring Par...
Cub Foods - Apple Valley - Now Hiring Part Time! United States of America, Minnesota, Apple Valley New Retail Post Date 4 days ago Requisition # 122305 Sign Up Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.