<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>isync &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/isync/</link>
	<description>Feed of posts on WordPress.com tagged "isync"</description>
	<pubDate>Tue, 01 Dec 2009 15:16:54 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[An attempt to illustrate differences between memory ordering and atomic access.]]></title>
<link>http://peeterjoot.wordpress.com/2009/11/29/an-attempt-to-illustrate-differences-between-memory-ordering-and-atomic-access/</link>
<pubDate>Mon, 30 Nov 2009 03:07:56 +0000</pubDate>
<dc:creator>peeterjoot</dc:creator>
<guid>http://peeterjoot.wordpress.com/2009/11/29/an-attempt-to-illustrate-differences-between-memory-ordering-and-atomic-access/</guid>
<description><![CDATA[[Click here for a PDF alternative to this post] Abstract. Discussion of problems and solutions assoc]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://sites.google.com/site/peeterjoot/math2009/atomic.pdf">[Click here for a PDF alternative to this post]</a></p>
<h1>Abstract.</h1>
<p>Discussion of problems and solutions associated with correct atomic and memory barrier usage has been a recurrent theme of many cubicle chats within DB2 development, and I will attempt to describe here part of what I&#8217;ve learned in some of those chats.  As a software developer, not a hardware implementer, I cannot pretend to understand more than a fragment of this topic, but it is enough to be dangerous and perhaps help others be dangerous too.</p>
<h1>Introduction</h1>
<p>Use of atomic instructions for manipulating &#8220;word&#8221; (or smaller) size quantities, avoiding the use of mutual exclusion library functions is becoming increasingly easy for developers.  This hasn&#8217;t made the using atomic instructions or library methods correctly any less difficult or error prone.</p>
<p>Information on how to use these written for an average Joe developer is hard to come by.  What can be easily found is good detailed low level information targeted at or written by operating system kernel extension writers or compiler developers [1], or language implementers and designers [2] [3] [4] [5] [6] [7] [8].  </p>
<p>The driving reason for most atomic usage is lock avoidance, and a desire for performance drives most use of atomic methods.  When atomic operations are used to replace lock protected updates, this can change the semantics of the program in subtle ways that are difficult to understand or get right.  In particular, additional use of memory barrier instructions or library methods may be required to correctly replace lock protected updates.</p>
<p>It is assumed here that most use of atomics is done for performance based lock (mutex) avoidance.  An attempt to cheat, writing atomic based code that avoids a lock, unfortunately requires some understanding of what that lock provided in the first place.  Here the meaning of, requirements for, and implementation of, a lock are discussed.  The implementation of an atomic operation is then discussed, and we then move on to an enumeration of the types of memory barrier instructions and their effects.  Finally, unless the assembly samples provided have not scared aways the reader, we cover a simple non-mutex example of barrier usage.  This example uses an atomic to signal completion of a previous update and requires memory barriers for correctness on weakly ordered systems.</p>
<h1>Why do I need locking or atomics?</h1>
<p>Why would you want to use an atomic?  If you are reading because you want to know a bit about memory barrier usage, you probably already know.  However, for illustrative purposes, consider the very simplest example of non-thread-safe updates of an integer in shared memory.</p>
<pre>
   pShared-&#62;x++ ;
</pre>
<p>Any such operation requires three steps.  Read the value, change the value, update the value in memory.  On some platforms this is explicit and obvious since the value will have to be read into a register before making the update.  Here&#8217;s a PowerPC example that illustrates this</p>
<pre>
    lwz      r4=(sharedMem)(r3,0)    ; r3 == pShared ; (r3,0) == *pShared
    addi     r0=r4,1
    stw      (sharedMem)(r3,0)=r0
</pre>
<p>The value in the memory address contained in the register r3 (offset by zero bytes) is loaded into a register (r4).  One is added to this (into r0), and the value is stored back into the original memory location.  Running on a CISC system this may all appear as one instruction, but it still requires the same number of steps internally.</p>
<p>Suppose you had a threaded application where this counter variable is updated routinely by many threads as they complete some routine and commonplace action.  What can now happen, interleaved (with time downwards) across threads may now look like this</p>
<pre>
T0: pShared-&#62;x = 0

T1: R1 = pShared-&#62;x (R1 = 0)
    R1 = R1 + 1
T1: 

T2: R2 = pShared-&#62;x
    R2 = R2 + 1
    pShared-&#62;x = R2

T3: R3 = pShared-&#62;x (assume T3 "sees" T2's update, a value of 1)
    R3 = R3 + 1
    pShared-&#62;x = R3

T4: R4 = pShared-&#62;x (assume T4 "sees" T3's update, a value of 2)
    R4 = R4 + 1
    pShared-&#62;x = R4

T1:
    pShared-&#62;x = R1 (T2 and T3's updates are now clobbered)
</pre>
<p>We had four updates to the counter after the initialization, but the counter value only goes up by one.  Uncontrolled updates like this can oscillate in peculiar fashions, and something that may be expected to be monotonically increase perhaps only trends upwards on average.  If the counter is not heavily contended you may even fluke out, running for a long time before getting unlucky with an inconsistent update of some sort.</p>
<p>This example leads us nicely to requirements for locking or atomic methods to protect such updates.</p>
<h2>Use of locking to make the read, change update cycle safe.</h2>
<p>Mutual exclusion mechanisms go by many names, locks, mutexes, critical sections, and latches to name a few.  System libraries usually provide implementations, a common example of which are the Unix pthread_mutex methods.  The unsafe increment above can be made thread safe, protecting it with such a guard.  With error handling omitted for clarity, a modified example could be as follows</p>
<pre>
   pthread_mutex_lock( &#38;m ) ;

   pShared-&#62;x++ ;

   pthread_mutex_unlock( &#38;m ) ;
</pre>
<p>If all threads only ever updates this value we can use a similar bit of code to read and do something with the read value</p>
<pre>
   pthread_mutex_lock( &#38;m ) ;

   v = pShared-&#62;x ;

   pthread_mutex_unlock( &#38;m ) ;

   doSomethingWithIt( v ) ;
</pre>
<p>No two sequential samplings of the shared variable x would see the value go down was possible in the uncontrolled update case.  </p>
<p>Now, you may ask why a mutex is required for the read.  If that is just a single operation, why would it matter?  That&#8217;s a good question, but not easy to answer portably.  If your variable is appropriately aligned and of an appropriate size (practically speaking this means less than or equal to the native register size) and you aren&#8217;t compiling with funky compiler options that turn your accesses into byte accesses (such options do exist), then you may be able to do just that.  However, if that variable, for example, is a 64-bit integer and you are running on a 32-bit platform, then this read may take two instructions and you have a risk of reading the two halves at different points in time.  Similarly, suppose you were doing a 32-bit integer read, but that 32-bit integer was aligned improperly on a 16-bit boundary (on a platform that allows unaligned access), then your apparent single read may internally require multiple memory accesses (perhaps on different cache lines).  This could cause the same sort of split read scenario.</p>
<p>You probably also need to declare your variable volatile and also have to be prepared to deal with a few other subtleties if lock avoidance on read is going to be attempted.  By the end of these notes some of those subtleties will have been touched on.</p>
<p>To make the story short, it should be assumed that if you want portable correct results you need to take and release the mutex for both read and write.</p>
<h2>What does correctness cost me?</h2>
<p>Now, having corrected the increment code, what does that cost us.  Timing the following very simple single threaded program with an without the mutex code</p>
<pre>
#include 

int x = 0 ;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER ;

int inc() ;

int main()
{
   for ( int i = 0 ; i &#60; 1000000000 ; i++ )
   {
      inc() ;
   }
}

int inc()
{
#if defined USE_THE_MUTEX
   pthread_mutex_lock( &#38;m ) ;
#endif

   x++ ;

   int v = x ;

#if defined USE_THE_MUTEX
   pthread_mutex_unlock( &#38;m ) ;
#endif

   return x ;
}
</pre>
<p>I find that this billion sets of call a function, increment a variable and return it without the mutex takes about 2.5 seconds.  With the mutex calls enabled, the total elapsed time required goes up to 8.5 seconds.  It costs over three times the time to do it with a mutex, and that&#8217;s without any contention on the mutex whatsoever!  With threads all fighting over the mutex and blocking on kernel resources when they cannot get it, this is as good as it gets.  Correctness doesn&#8217;t come cheaply.</p>
<h2>How does the lock work?</h2>
<p>Any mutex implementation requires at least one platform specific method of performing a read, update, change cycle as if it is done without interruption.  Your hardware will likely provide a <a href="http://en.wikipedia.org/wiki/Compare-and-swap">Compare and swap</a> or <a href="http://en.wikipedia.org/wiki/Load-Link/Store-Conditional">Load Link/Store Conditional</a> (which can be used to construct higher level atomics like compare and swap).  Implementing a mutex is intrinsically unportable territory.  Older <a href="http://download.intel.com/design/intarch/manuals/24319101.pdf">intel</a> cpus did not provide a compare and swap, but one did have a bus locked exchange available (LOCK XCHG).</p>
<p><a href="http://ftp.parisc-linux.org/docs/arch/pa11_acd.pdf">HP&#8217;s PARSIC</a>, also easily argued to not be a modern architecture, only provides an atomic load and clear word instruction, also requiring 16 BYTE a aligned word.  What can be assumed is that any multiple cpu machine provides some sort of low level atomic instruction suitable for building a mutual exclusion interface.  If one were to imagine what a pthread_mutex_lock protected increment expands to, it would likely have the following form</p>
<pre>
   T valueRead ;

   while ( ATOMIC_OP_WAS_SUCCESSFUL != SOME_INSTRUCTIONS_FOR_LOCK_ACQUISION( &#38;m ) )
   {
      // instructions (like PAUSE()) for hyper threaded cpus.

      // code for wasting a bit of time hoping to get the lock
      //   (when not running on a uniprocessor).

      // sleep or block using an OS primitive
   }

   valueRead = pShared-&#62;myLockProtectedData ;
   pShared-&#62;myLockProtectedData = valueRead + 1 ;

   SOME_INSTRUCTIONS_FOR_LOCK_RELEASE( &#38;m ) ;
</pre>
<p>Even before talking about the hardware, one has to assume that there are mechanisms available to the library writer that prevent the generated code from being reordered.  Any instructions containing accesses of myLockProtectedData must NOT occur BEFORE the ACQUISION instructions, and must NOT occur AFTER the RELEASE instructions.  If the compiler were to generate code that had the following effect</p>
<pre>
   T valueRead = pShared-&#62;myLockProtectedData ;
   pShared-&#62;myLockProtectedData++ ;

   pthread_mutex_lock( &#38;m ) ;
   pthread_mutex_unlock( &#38;m ) ;
</pre>
<p>Things would obviously be busted.  In the case of the pthread functions we have non-inline method with unknown side effects requiring a call to an external shared library.  This appears to be enough that the lock protected data does not have to be declared volatile and can be used while the mutex is held as if in a serial programming context.  Understanding the murky language rules that give us the desired thread safe behavior is difficult (for an average Joe programmer like me).  I came to the conclusion this is not a completely well defined area, motivating a lot of the recent C++ standards work into memory consistency and threaded behavior.</p>
<p>Presuming one assumes that the compiler is laying down the instructions for this code in program order (or something sufficiently close), or that there are mechanism available to ensure this, is this enough to guarantee that we have correct program behavior?</p>
<p>It may come as a rude surprise that, depending on the instructions used to acquire and release the mutex, having the all the instructions scheduled in program order is NOT actually sufficient.  Not all hardware executes instructions in the order the compiler specifies.  We also need mechanisms to prevent the hardware from starting a memory access too early or letting a memory access complete too late.</p>
<p>This requirement for memory ordering instructions is really the whole point of this discussion.  We must have additional mechanism on top of the raw atomic instructions that only ensure read,change,update accesses on an isolated piece of memory (the lock word) can be made as if uninterpretable.</p>
<p>For illustrative purposes, suppose that one was using the <a href="http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html">gcc Atomic Builtins</a> to attempt to implement a mutex.  One (generally) wrong way to use these would be</p>
<pre>
   // the mutex data
   volatile int m = 0 ;
   #define HELD_BIT 1
   #define WAITER_BIT 2

   // Get the mutex.
   while ( true )
   {
      int prev = __sync_fetch_and_or( &#38;m, HELD_BIT ) ;

      if ( 0 == ( prev &#38; HELD_BIT ) )
      {
         break ;
      }
      // sleep and other stuff, possibly blocking and setting WAITER_BIT.
   }

   // Got the mutex, access the protected data.
   pShared-&#62;myLockProtectedData++ ;

   // Release the mutex.
   int preLockState = __sync_fetch_and_and( &#38;m, ~HELD_BIT ) ;
   assert( preLockState &#38; HELD_BIT ) ;
   if ( preLockState &#38; WAITER_BIT )
   {
      WakeUpAnyWaiters() ;
   }
</pre>
<p>Reading the GCC docs one sees that this has desired compiler behaviour for instruction scheduling.  Namely, &#8220;these builtins are considered a full barrier. That is, no memory operand will be moved across the operation, either forward or backward&#8221;.  The compiler will not move instructions that access memory and move them into or out of the critical section bounded by the pair of atomic instructions.</p>
<p>Will the hardware retain that ordering?  NO, not necessarily.</p>
<p>These compiler builtins are partially patterned after ones provided by intel, and intel designed them to match functionality provided by their <a href="http://www.intel.com/design/itanium/manuals/245319.htm">ia64 architecture</a>, a weakly ordered instruction set.  While ia64 was effectively killed by AMD64 and Windows (now living on only in the guise of HP&#8217;s IPF systems), there are other weakly ordered instruction sets predating ia64.  Some PowerPC chips that you will find on big AIX systems, or in older macs, or in your childrens ps3 will be weakly ordered.  The <a href="http://developers.sun.com/solaris/articles/sparcv9.pdf">Sparc architecture</a> allows for weak ordering, but the chips you find in sun machines implement their TSO (total store order) model which is mostly ordered.</p>
<p>This allowance for unordered memory is why, way down at the end of the GCC page, one finds a couple special _lock methods.  The point of these is to ensure that the hardware does not reorder the relative order of memory accesses of the lock word and the lock data, even when the compiler lays down the code in &#8220;program order&#8221;.</p>
<p>We can do a mutex implementation less wrongly using a memory barrier for release as in the following fragment.</p>
<pre>
   // the mutex data
   volatile int m = 0 ;
   #define HELD_BIT 1

   // Get the mutex.
   while ( true )
   {
      int prev = __sync_fetch_and_or( &#38;m, HELD_BIT ) ;

      if ( 0 == ( prev &#38; HELD_BIT ) )
      {
         break ;
      }
      // sleep and other stuff if you didn't get it
   }

   // Got the mutex, access the protected data.
   pShared-&#62;myLockProtectedData++ ;

   __sync_syncronize() ; 

   m = 0 ;
</pre>
<p>Observe that the use of the word barrier is overloaded on the GCC page, with some usage associated with compiler instruction scheduling, and other usage referring to memory ordering.  Their syncronize function appears to be both.  Looking at the generated assembly for a weakly ordered system would verify this interpretation, and one would likely find an lwsync or sync instruction on PowerPC for example.  This modification of the locking code ensures the compiler lays down the code with the clearing of the lock word after the protected data access, and the hardware memory barrier instruction should ensure that reads or writes to the protected data are complete before the store to the lock word is allowed to occur.  Depending on the type of instruction that is emitted for the synchronize builtin, this may not actually prevent loads and stores that occur after the lock release from being started before the lock is released.  Generally if that must be prevented a full barrier is required, and it would not surprise me if most implementations of library methods like pthread_mutex_unlock do not prevent memory accesses that occur after the lock release from being initiated before the lock release occurs.  This sort of subtlety is not likely to be found in documentation for the mutex library functions.</p>
<p>With the sample code above we are still left with the possibility that the hardware will execute the memory access instructions for the lock protected data before the lock is acquired, making the lock useless.  We can fix this with the _lock test and set and release builtins, and also remove the likely overzealous full memory barrier that synchronize provides (allowing post lock release memory access into the critical section).  Sample code for this would may look like</p>
<pre>
   // the mutex data
   volatile int m = 0 ;
   #define HELD_VALUE 1

   // Get the mutex.
   while ( true )
   {
      int wasHeld = __sync_lock_test_and_set( &#38;m, HELD_VALUE ) ;

      if ( !wasHeld )
      {
         break ;
      }
      // sleep and other stuff if you didn't get it
   }

   // Got the mutex, access the protected data.
   pShared-&#62;myLockProtectedData++ ;

   __sync_lock_release( &#38;m ) ;
</pre>
<p>This now implements functional mutual exclusion code, even on weakly ordered systems.  The compiler has provided methods that ensure it does not move the lock protected data accesses out of the critical section, we are using atomic instructions that guarantee other threads cannot also be modifying the data (presuming they all use the same mutex), and also have instructions that ensure the hardware does not inappropriately reorder the memory accesses.  Inappropriate reordering means that accesses to the lock protected data remain after the lock acquisition and before the lock release.  It may not mean that memory accesses from before the lock acquisition are done by the time the lock is acquired nor that memory accesses that occur after the lock is released occur after the lock is released (the compiler says it does that, but the hardware may be a sneaky bastard behind your back).</p>
<p>So, that&#8217;s a mutex.  We can use something like this to avoid some of the excessive cost observed when using the pthread library mutex functions, and would expect that the uncontended cost of the back to back increment code could be lessened.</p>
<p>Presuming you do not mind the unportability of such code, and manage to get it right, and want to live with maintaining your own mutex implementation, if you do a poor job dealing with contention, you may very well get worse performance than the system provided methods in the contended codepath.</p>
<p>You really really have to want the performance to go down the path of implementing your own mutual exclusion code.  DB2 is such a product.  DB2 is also a product where first born sacrifices in the name of performance are not considered abhorrent.  In our defense our mutex implementation predates the availability of widely available library methods.  We had SMP exploitation before pthreads existed using mutiple processes and shared memory.  Our own implementation also has the advantage of providing framework to build problem determination functionality that cannot be found in generic library implementations.  Performance driven coding is not the only reason we do it ourself even in this more modern age where library methods do exist.</p>
<h1>What is an atomic, and how does an atomic method work?</h1>
<p>At the core of every atomic library method or compiler intrinsic is one or more special purpose instructions.  In many cases these are the same types of instructions that can be used to implement mutual exclusion code (when properly augmented by memory barrier instructions).</p>
<p>If you don&#8217;t have an instruction for exactly what you want, it can often be built from some other lower level operation.  Suppose for example you want to safely do the contended increment without using a lock, but only have a compare and swap.  Something like the following can be used</p>
<pre>
int fetch_and_add( volatile int *ptr, int value )
{
   int v = *ptr ;
   while ( true )
   {
      int prev = __sync_val_compare_and_swap( ptr, v, v + value ) ;
      if ( prev == v )
      {
         break ;
      }

      v = prev ;
   }

   return prev ;
}
</pre>
<p>Generally, one can assume at least a compare and swap operation, but this may also be simulated, built up out of more direct and primitive operations.  On PowerPC for example, this is done with the very flexible load-linked/store-condition instructions (load with reservation and store conditional in PowerPC lingo).  A fetch and add can be built with a small loop</p>
<pre>
fadd32_spin:
   lwarx     r0,0,r3       ; load word and acquire a registration
   add       r0,r0,r4      ; add in the desired amount to the possibly current value
   stwcx.    r0,0,r3       ; try to store it
   bne-      fadd32_spin   ; if loaded value old or somebody beat us repeat.
   sub       r3,r0,r4      ; fake a return using normal function return register r3
</pre>
<p>Building a portable dependence on a load-linked/store-condition primitive can be tricky, but possible.  In DB2&#8217;s reader-writer mutex implementation, a data structure employing some nifty lock free algorithms ([9] [10] [11] [12] [13] [14]) we use this load-linked/store-conditional code to implement a slick compare-against-bitmask-and-increment-or-set-bit atomic operation.  We can do the same thing with compare and swap, but the generated assembly code is particular pretty on AIX, where PowerPC gives us this more powerful primitive. </p>
<h2>A historical reflection aside.</h2>
<p>Even only a couple of years ago, it was much harder to exploit atomic instructions.  Part of the reason is that we have tossed or stopped caring about older systems.  Nobody cares anymore about older ia32 systems that did not have cmpxchg.  Pre-PowerPC AIX implementations that did not have lwarx and stwcx. instructions are now dead and buried in landfill somewhere.  PARISC systems that did not provide any sort of reasonable atomic instructions are now being replaced by HP IPF systems.  We can now generally assume that some basic atomic building blocks are available and no longer have to tiptoe around avoiding breaking the old guys.</p>
<p>Another reason that makes atomic usage easier these days is the wide availability of compiler builtins and library infrastructure, rendering this previous area of horrendous unportability accessible.  Use of the GCC builtins was illustrated above, showing some incorrect and correct lock implementations.  On the same page can be found instructions for compare and swap, atomic read and increment, and others.  Similar builtins are available from many other compilers.  The boost library implementation of atomic types are a good example.  The next revision of the C++ standard will likely include boost-like methods.  It appears that C\# implements Interchange methods very much like the msdev intrinsics, so this is even becoming a cross language portability area in a limited fashion.</p>
<p>It is fun to illustrate just how murky the portability waters were before the prevalance of compiler intrinsics.  Atomic exploitation generally required writing assembly code, and that is never particularly fun.  Here is a sample code showing how one would code an &#8220;inline assembly&#8221; language implementation of fetch and add using the IBM compiler targeting PowerPC</p>
<pre>
int PowerPcFetchAndAdd32Internal ( volatile int * pAtomic, int value ) ;

#pragma mc_func PowerPcFetchAndAdd32Internal { "7c001828" "7c002214" \
   "7c00192d" "40a2fff4" "7c640050" }

#pragma reg_killed_by PowerPcFetchAndAdd32Internal cr0, gr0, gr3
</pre>
<p>What we have here is literally a mechanism to instruct the compiler to shove the raw instructions, specified by hexadecimal opcodes, directly into the instruction stream, with the writer of the inline assembly routine providing information about all the registers clobbered and side effects of the code.  This inline assembly code is actually generated from the listing in PowerPC assembly fragment above, which was carefully constructed to have the same structure as a real function call on AIX (input params in r3,r4, and output in r3)</p>
<p>Before the GCC intrinsics were available, one could use the powerful GCC inline assembly syntax to instruct the compiler what to shove into the code.  Here&#8217;s an example for fetch and add</p>
<pre>
#define IA32_XADD32(pAtomic, addValue, oldValue)                    \
__asm__ __volatile__( "lock; xaddl
 /* outputs */     : "=r"(oldValue), /*
                     "+m" (*pAtomic) /*
 /* inputs */      : "0" (addValue)  /*
 /* clobbers */    : "cc"            /* condition registers (ZF) */ \
                       )
</pre>
<p>Looks kind of like ASCII barf, but does the job nicely enough if you can get it right.  </p>
<p>On platforms that provided no good inline assembly methods was not available (which includes those platforms and compilers for which inline assembly makes the code worse than using out of line assembly) one had the option of coding standalone assembler files to create the function call methods desired.  That can be just as difficult since one is then forced to learn the assembler syntax in more detail and understand the idiosyncrasies of all the platform calling conventions.</p>
<h1>Types of barriers.</h1>
<p>There are in general a few different types of barriers (or fences).  Not all architectures that allow for unordered instructions necessarily implement all of these.  Some of these may also only be available as variations of specific instructions, so when standalone use is required a more expensive instruction may be required.</p>
<p>To describe the barrier types I will borrow ia64 nomenclature and assembly fragments, which is nicely descriptive despite death of this platform.  The ia64 architecture provides acquire, release and full barriers.  Some of these are built into the load and store operations on these platforms.</p>
<h2>Acquire barrier</h2>
<p>If one sees assembly code containing</p>
<pre>
ld4      r3   = [r30]   ; "BEFORE"
st1      [r4] = r40     ; "BEFORE"

ld4.acq  r5   = [r42]   ; LOAD with ACQUIRE barrier

ld4      r6   = [r43]   ; AFTER
st1      [r7] = r44     ; AFTER
</pre>
<p>One has no guarantee about the relative ordering of the BEFORE-labeled memory accesses.  Similarly one has no guarantee about the ordering of the pair of AFTER-labeled memory accesses, but because of the acquire barrier the load and acquire barrier must be complete before the AFTER accesses.</p>
<p>Note that the acquire barrier is one directional.  It does not prevent the pair of BEFORE memory accesses from occurring after the barrier.  Illustrating by example, the instructions could be executed as if the compiler had generated the following sequence of instructions</p>
<pre>
ld4.acq  r5   = [r42]

st1      [r7] = r44
ld4      r3   = [r30]
ld4      r6   = [r43]
st1      [r4] = r40
</pre>
<p>There may be additional architecture rules about dependent loads and stores effecting the types of code motion that is allowed by the compiler, or the way that the CPU implements the architecture, but I will ignore those here.</p>
<p>This sort of effective instruction reordering is often described saying that one instruction has passed another.</p>
<p>This acquire barrier, perhaps unsurprising, is exactly the type of barrier required when implementing code for mutex acquisition.  In addition to ia64, the PowerPC platform requires such barriers, and provides the isync instruction to the programmer.  An example in a higher level language that may not have the desired effect without an such an acquire barrier is</p>
<pre>
if ( pSharedMem-&#62;atomic.bitTest() ) // use a bit to flag that somethingElse is "ready"
{
   foo( pSharedMem-&#62;somethingElse ) ;
}
</pre>
<p>If correct function of your program depends on somethingElse only being read after the atomic update flagging a condition is complete, then this code is not correct without an isync or other similar platform specific acquire barrier.</p>
<p>Your code should really look something like this</p>
<pre>
if ( pSharedMem-&#62;atomic.bitTestAcquire() )
{
   foo( pSharedMem-&#62;somethingElse ) ;
}
</pre>
<p>Here it is assumed the atomic library provides acquire and release variations of all atomic operations.  For PowerPC this could be as simple as adding an isync to the unordered atomic operation, but on a platform like ia64 one would probably use a different instruction completely (ie. cmpxchg.acq for example).  With such an acquire barrier the somethingElse access or another other memory operation that follows the load associated with the bitTest necessarily follows the load itself.  For example, this can mean that a non-dependent load that has been executed ahead of the acquire barrier will have to be thrown out and reexecuted.</p>
<h2>Release barrier</h2>
<p>A release barrier is perhaps a bit easier to understand.  Illustrating again by example, suppose that we have the following set of load and store instructions, separated by a release barrier.</p>
<pre>
ld4      r3    = [r30]   ; BEFORE
st1      [r4]  = r40     ; BEFORE

st4.rel  [r42] = r5      ; STORE with release barrier.

ld4      r6    = [r43]   ; "AFTER"
st1      [r7]  = r44     ; "AFTER"
</pre>
<p>The release barrier ensures that the pair of BEFORE-labeled reads and write memory accesses are complete before the barrier instruction.  There is nothing that prevents the BEFORE instructions from executing in an alternate order, but all of the effects of these instructions visible by any other CPU must be complete before the effects of the store barrier instruction is observable by that other CPU.  Like the acquire barrier, the release barrier is a one way fence.  Neither of the instructions labeled &#8220;AFTER&#8221; necessarily have to be executed after the release barrier.</p>
<p>On PowerPC this release barrier is implemented with a light weight sync (different than the isync that implements the acquire barrier).  As a general rule of thumb, code that requires a release barrier will require an acquire barrier and vice-versa.  These instructions are almost always required to be used in complementary pairs.</p>
<p>Similar but opposite to the acquire barrier, a release barrier has the semantics required for implementing the release portion of a mutex.</p>
<h2>Full barrier.</h2>
<p>We have seen how use of release and acquire barriers can ensure that that memory access before or after the barrier can be forced to maintain that order relative to the barrier.  There are however, some types of memory ordering that neither of these can ensure.</p>
<p>Using ia64 code to illustrate, suppose one has memory accesses before a release barrier, and memory accesses after an acquire barrier.</p>
<pre>
ld4      r3    = [r30]   ; BEFORE
st1      [r4]  = r40     ; BEFORE

st4.rel  [r42] = r5      ; STORE with release barrier.
ld4.acq  r8    = [r45]   ; LOAD with acquire barrier.

ld4      r6    = [r43]   ; AFTER
st1      [r7]  = r44     ; AFTER
</pre>
<p>The barriers here ensure that the BEFORE-labeled instructions all complete before the release barrier effects become visible to other cpus, and also ensure that none of the AFTER-labeled instructions may start before the acquire barrier instruction is complete.  This barrier cannot prevent the acquire barrier LOAD instruction from completing before the STORE barrier.  Illustrating by example, the CPU could execute things like so</p>
<pre>
ld4.acq  r8    = [r45]   ; LOAD with acquire barrier.

ld4      r3    = [r30]   ; BEFORE
st1      [r4]  = r40     ; BEFORE

ld4      r6    = [r43]   ; AFTER
st1      [r7]  = r44     ; AFTER

st4.rel  [r42] = r5      ; STORE with release barrier.
</pre>
<p>This alternate ordering also meets the requirements of the original code.  All of the BEFORE-labeled instructions are still before the release barrier and all the AFTER-labeled instructions occur after the acquire barrier.  In order to enforce this type of ordering we require a special standalone ordering construct.  On ia64 this is the mf (memory fence) instruction, and on that platform it acts as both a standalone acquire and release barrier, but also prevents store load reordering.  Of the weakly ordered platforms that are widely available (PowerPC, Sparc, ia64), all of these architectures require a special standalone instruction to enforce this special ordering.</p>
<p>The Sparc architecture has a number of possible ordering models, but the one implemented in all the CPUs that you would find in a Solaris Sparc based system is designated total store order (TSO).  For all practical purposes this means that all instruction pairs are ordered except a store load sequence, and in order to enforce such an ordering one must interject a &#8216;membar \#storeload&#8217; instruction.</p>
<p>On PowerPC, in order to guarantee store load instructions maintain their order, one must interject a heavy-weight sync instruction between the two (sync).</p>
<p>One gets the impression that whatever hardware black magic is required to implement store load ordering, it has the appearance of being harder to enforce this particular type of instruction ordering than any other.</p>
<p>One of the interesting things about these store load barrier instructions, is not that they do enforce this ordering, but that the release and acquire barrier instructions do not.  In particular a mutex implemented with acquire and release barriers and not with a full barrier instruction can let exterior memory accesses into the critical section.</p>
<p>Suppose for example we have the following code</p>
<pre>
pSharedMem-&#62;x = 3 ;  // BEFORE
v = pSharedMem-&#62;y ;  // BEFORE

mutex.acquire() ; // assumed to contain an acquire barrier.

pSharedMem-&#62;z = 4 ;
foo( pSharedMem-&#62;w ) ;

mutex.release() ; // assumed to contain a release barrier.

pSharedMem-&#62;a = 2 ;  // AFTER
q = pSharedMem-&#62;b ;  // AFTER
</pre>
<p>Unless the mutex uses very heavy handed memory barrier instructions one has the possibility that either the AFTER or BEFORE labeled memory accesses may sneak into the critical section that the mutex provides.</p>
<p>This subtlety may not be documented by the mutex implementation, but one should not assume that a mutex does any more than keep stuff within the critical section from getting out.</p>
<h1>The flag pattern illustrated.</h1>
<p>The mutex is by far the most important example of barrier use that is required for correctness in a weakly ordered system.  It is however, perhaps not the easiest to understand.  A slightly simpler pattern is the use of an atomic to flag that another memory update is complete.</p>
<p>As mentioned it is common for correct memory barrier usage to require paired conugate acquire and release barriers.  This is very much like what is in the implementation of the critical section that you are probably trying to avoid by using an atomic and the associated barriers.  It will however, be split, with the release and acquire barrier usage divided into portions for the producer and consumer.  As an example your critical section implementation would typically be of the form:</p>
<pre>
while (!pShared-&#62;lock.testAndSet_Acquire()) ;
// (this loop should include all the normal critical section stuff like
// spin, waste,
// pause() instructions, and last-resort-give-up-and-blocking on a resource
// until the lock is made available.)

// Access to shared memory.

pShared-&#62;foo = 1
v = pShared-&#62; goo

pShared-&#62;lock.clear_Release()
</pre>
<p>Acquire memory barrier above makes sure that any loads (pShared-&#62;goo) that may have been started before the successful lock modification are tossed, to be restarted if necessary.</p>
<p>The release memory barrier ensures that the load from goo into the (local say) variable v is complete before the lock word protecting the shared memory is cleared.</p>
<p>You have a similar pattern in the typical producer and consumer atomic flag scenario (it is difficult to tell by your sample if that is what you are doing but should illustrate the idea).</p>
<p>Suppose your producer used an atomic variable to indicate that some other state is ready to use. You&#8217;ll want something like this:</p>
<pre>
pShared-&#62;goo = 14

pShared-&#62;atomic.setBit_Release()
</pre>
<p>Without a release (&#8220;write&#8221;) barrier here in the producer you have no guarantee that the hardware isn&#8217;t going to get to the atomic store before the goo store has made it through the CPU store queues, and up through the memory hierarchy where it is visible (even if you have a mechanism that ensures the compiler orders things the way you want).</p>
<p>In the consumer</p>
<pre>
if ( pShared-&#62;atomic.compareAndSwap_Acquire(1,1) )
{
   v = pShared-&#62;goo
}
</pre>
<p>Without a &#8220;read&#8221; barrier here you won&#8217;t know that the hardware hasn&#8217;t gone and fetched goo for you before the atomic access is complete. The atomic (ie: memory manipulated with the Interlocked functions doing stuff like lock cmpxchg), is only &#8220;atomic&#8221; with respect to itself, not other memory.</p>
<p>That&#8217;s really all there is to this example, so it is perhaps anticlimatic, as well as including a redundant discussion of a mutex implementation.  However, it is a good first step and these notes are already too long.  A more and better example will perhaps follow on a different day.</p>
<h1>Conclusion.</h1>
<p>Some of the issues associated with using atomics and barriers to replace the simpler lock mechanism have been discussed.  It is unfortunate to have to provide examples that utilize assembly code to illustrate these ideas, but it is harder to discuss these topics without doing so.  Hopefully the inclusion of some of the low level details and assembly listings has not rendered this on paper discussion too incomprehensible.  </p>
<p>The fact that some low level systems details must be understood for correct use of atomics to avoid locking should perhaps be a warning to the programmer.  It can be very hard to implement lock avoidance algorithms correctly, harder still to test them.  There is also a significant maintenance impact to going down this road, so be good and sure that you really need the performance provided before taking this path.  Premature optimization in this area can be particularly dangerous and costly.</p>
<p>Do you really have a good reason for going down the atomic path instead of just using a lock?  Doing all this correctly can be very difficult. Be prepared for a lot of self doubt and insecurity in code reviews and make sure you have a lot of high concurrency testing with all sorts of random timing scenarios.  Use a critical section unless you have a very very good reason to avoid it, and don&#8217;t write that critical section yourself.</p>
<p>The correctness aspects of memory barrier utilization makes your code intrinsically unportable.  Because many correct uses of atomics also require barrier instructions, this can in turn imply that the &#8220;innocent and simple&#8221; atomic class library implementation you have access to can be correspondingly unportable.  This may be surprising to the developer, but then again, many aspects of weakly ordered system behavior can be surprising.</p>
<p>On a weakly ordered system, your compiler probably provides _acquire and _release variations for most of the atomic manipulation methods.  On a strongly ordered platform like ia32 or amd64, _acquire() or _release() suffixed atomic intrinsics will not be any different than the vanilla operations.  With ia64 effectively dead (except on HP where its still twitching slightly) PowerPC is probably the most pervasive surviving weakly ordered architecture around, and even it has toyed with non-weak ordering (power5 was weakly ordered, power6 was not, and power7 is again weakly ordered).  It will be interesting to what path the hardware folks take, and whether these details are of any importance in 10 or 15 years.</p>
<h1>References</h1>
<p>[1] M. Lyons, E. Silha, and B. Hay. PowerPC storage model and AIX programming, 2002.  <a href="http://www.ibm.com/developerworks/eserver/articles/powerpc.html">http://www.ibm.com/developerworks/eserver/articles/powerpc.html</a>.</p>
<p>[2] D. Lea. The JSR-133 cookbook for compiler writers, 2005.</p>
<p>[3] L.C.H.J. Boehm. Threads and memory model for C++ [online].  <a href="http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/">http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/</a>.</p>
<p>[4] J. Manson and B. Goetz. Jsr 133 (java memory model) faq [online]. 2004.  <a href="http://www.cs.umd.edu/ pugh/java/memoryModel/jsr-133-faq.html">http://www.cs.umd.edu/ pugh/java/memoryModel/jsr-133-faq.html</a>.</p>
<p>[5] L.C.H.J. Boehm. C++ atomic types and operations. mailings N2427. <em>C++ standards committee</em>, 2007.  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html</a>.</p>
<p>[6] H. Sutter. {Prism-A Principle-Based Sequential Memory Model for Microsoft Native  Code Platforms Draft Version 0.9. 1}, 2006.  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2197.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2197.pdf</a>.</p>
<p>[7] R. Silvera, M. Wong, P. McKenney, and B. Blainey. {A simple and efficient memory model for weakly-ordered  architectures}, 2007.  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2153.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2153.pdf</a>.</p>
<p>[8] S.V. Adve and K. Gharachorloo. Shared memory consistency models: A tutorial. <em>Computer</em>, 29(12):66&#8211;76, 1996.  <a href="http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf">http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf</a>.</p>
<p>[9] J.D. Valois. Lock-free linked lists using compare-and-swap.</p>
<p>[10] T.L. Harris, K. Fraser, and I.A. Pratt. A practical multi-word compare-and-swap operation. <em>Lecture Notes in Computer Science</em>, 2508:265&#8211;279, 2002.  <a href="http://www.cl.cam.ac.uk/research/srg/netos/papers/2002-casn.pdf">http://www.cl.cam.ac.uk/research/srg/netos/papers/2002-casn.pdf</a>.</p>
<p>[11] T.L. Harris. A pragmatic implementation of non-blocking linked-lists. <em>Lecture Notes in Computer Science</em>, 2180:300&#8211;314, 2001.  <a href="http://www.cl.cam.ac.uk/research/srg/netos/papers/2001-caslists.pdf">http://www.cl.cam.ac.uk/research/srg/netos/papers/2001-caslists.pdf</a>.</p>
<p>[12] T.L. Harris. Harris Papers [online].  <a href="http://www.cl.cam.ac.uk/research/srg/netos/lock-free/">http://www.cl.cam.ac.uk/research/srg/netos/lock-free/</a>.</p>
<p>[13] R. Bencina. lock free papers and notes. [online]. 2006.  <a href="http://www.audiomulch.com/ rossb/code/lockfree/">http://www.audiomulch.com/ rossb/code/lockfree/</a>.</p>
<p>[14] M.M. Michael. {Safe memory reclamation for dynamic lock-free objects using atomic  reads and writes}. In {\em Proceedings of the twenty-first annual symposium on  Principles of distributed computing}, pages 21&#8211;30. ACM New York, NY, USA,  2002.  <a href="http://www.research.ibm.com/people/m/michael/podc-2002.pdf">http://www.research.ibm.com/people/m/michael/podc-2002.pdf</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[iSync, Bluetooth &amp; SE T715 ]]></title>
<link>http://chimac.net/2009/11/29/isync-bluetooth-se-t715/</link>
<pubDate>Sun, 29 Nov 2009 19:32:16 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/11/29/isync-bluetooth-se-t715/</guid>
<description><![CDATA[Just say yes to everything the phone wants to do and it works great!]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Just say yes to everything the phone wants to do and it works great!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Using iSync to Connect to a Nokia 3120 Classic]]></title>
<link>http://mfluch.wordpress.com/2009/11/12/using-isync-to-connect-to-a-nokia-3120-classic/</link>
<pubDate>Thu, 12 Nov 2009 16:31:47 +0000</pubDate>
<dc:creator>mfluch</dc:creator>
<guid>http://mfluch.wordpress.com/2009/11/12/using-isync-to-connect-to-a-nokia-3120-classic/</guid>
<description><![CDATA[If you have like me a Nokia 3120 Classic and want to sync with your Mac using iSync, then Paul McCar]]></description>
<content:encoded><![CDATA[If you have like me a Nokia 3120 Classic and want to sync with your Mac using iSync, then Paul McCar]]></content:encoded>
</item>
<item>
<title><![CDATA[Transfer your contacts from a Sony Ericsson to your iPhone.]]></title>
<link>http://medietech.wordpress.com/2009/11/08/transfer-your-contacts-from-a-sony-ericsson-to-your-iphone/</link>
<pubDate>Sun, 08 Nov 2009 17:13:48 +0000</pubDate>
<dc:creator>jensborje</dc:creator>
<guid>http://medietech.wordpress.com/2009/11/08/transfer-your-contacts-from-a-sony-ericsson-to-your-iphone/</guid>
<description><![CDATA[(På svenska längre ner) After have been trying for hours to transfer my contacts from my old phone t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>(På svenska längre ner)</p>
<p>After have been trying for hours to transfer my contacts from my old phone to my new iPhone, I’ve now decided to share how I solved it. Maybe it will help so someone else doesn’t have to sit as long as I did with it.</p>
<p>I went from a Sony Ericsson W660i to an iPhone 3Gs, quite a big jump in the technology. As you probably know, iPhone Contacts syncs with the Address book in your mac when they are connected. However, originally there is no way to in its turn sync it with another kind of phone, like a Sony Ericsson, in the same way with the computer. This, however, you can do by install a plug-in to iSync, a standard software in OSX.</p>
<p>I found the plug-in I needed <a href="http://www.sonyericsson.com/cws/support/softwaredownloads/detailed/sonyericssonisync/w660i?lc=sv&#38;cc=se" target="_blank">here</a>, and there are probably similar ones for other kinds as well.</p>
<p>Once this is installed, iSync can now connect your Sony Ericsson with the computer and the Address Book syncs with the contacts from the phone. After that, it’s only to connect your iPhone to your computer and let it automatically sync with iTunes.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p><strong>Föra över dina kontakter från en Sony Ericsson-mobil till din iPhone</strong></p>
<p>Efter att ha i timmar försökt få över mina kontakter från min gamla mobil till min nya iPhone, har jag nu bestämt mig för att dela med mig av hur jag löste det. Kanske slipper någon annan sitta lika länge som jag med det.</p>
<p>Mitt byte gick från en Sony Ericsson W660i till iPhone 3Gs, ett ganska stort hopp i tekniken. Som ni förmodligen vet synkas iPhones Kontakter med Adressboken i din mac när de ansluts. Ursprungligen finns det emellertid inte något sätt att i sin tur synka en annan sorts telefon, som en Sony Ericsson, på samma sätt med datorn. Detta går däremot att göra genom att installera en plug-in till iSync, ett standardprogram i OSX.</p>
<p>Jag hittade den plug-in jag behövde <a href="http://www.sonyericsson.com/cws/support/softwaredownloads/detailed/sonyericssonisync/w660i?lc=sv&#38;cc=se" target="_blank">här</a>, och det finns förmodligen liknande för andra sorter.</p>
<p>När denna är installerad, kan nu iSync koppla ihop din Sony Ericsson med datorn och Adressboken synkas med kontakterna från telefonen. Därefter är det bara att koppla in din iPhone i datorn och låta den automatiskt synkas med iTunes.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Nokia E71 no longer able to iSync ]]></title>
<link>http://chimac.net/2009/10/29/nokia-e71-no-longer-able-to-isync/</link>
<pubDate>Thu, 29 Oct 2009 19:04:43 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/10/29/nokia-e71-no-longer-able-to-isync/</guid>
<description><![CDATA[Basically you need to talk to Nokia.  It used to work but after a firmware update stopped working.  ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Basically you need to talk to Nokia.  It used to work but after a firmware update stopped working.  Click <a href="http://discussions.apple.com/thread.jspa?threadID=2108359&#38;tstart=0" target="_self">here </a>to read.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Omnia HD Dicas e Truques: Sincronizar I8910 Omnia HD com MacOSX]]></title>
<link>http://dennytorres.wordpress.com/2009/10/20/sincronizar-i8910-omnia-hd-com-macosx/</link>
<pubDate>Wed, 21 Oct 2009 00:21:30 +0000</pubDate>
<dc:creator>dennyctorres</dc:creator>
<guid>http://dennytorres.wordpress.com/2009/10/20/sincronizar-i8910-omnia-hd-com-macosx/</guid>
<description><![CDATA[Estava tendo certa dificuldade para sincronizar meus contatos e minha agenda com o meu mais novo sma]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Estava tendo certa dificuldade para sincronizar meus contatos e minha agenda com o meu mais novo smartfone, o completo Omnia HD. A Samsung, não sei porque, ainda desenvolveu um software ou mesmo um plugin para o Isync do Mac, como a maioria dos aparelhos da Nokia.</p>
<p>Após vários testes, descobri uma forma bem fácil de atualizar os contatos. Primeiro você tem que ter uma conta no google. Depois você sincroniza seus contatos do Mac com o Google.</p>
<p>Feito isso, vá no smartfone em: Menu -&#62; settings -&#62; Connectivity -&#62; Data transfer -&#62; Sync -&#62; New sync profile</p>
<p>Na 1° página coloque um nome para o &#8220;profile&#8221;</p>
<p>Na 2° página, selecione &#8220;1.2&#8243;</p>
<p>Na 3° página selecione somente contatos &#8211; ainda não descobri porque as outras opções não funcionam</p>
<p>Na 4 ° página digite &#8220;Contacts&#8221; &#8211; sem as aspas, é claro.</p>
<p>Na 5° página, selecione &#8220;Internet&#8221;</p>
<p>Na 6° página digite &#8220;https://m.google.com/syncml&#8221; (repare que tem um &#8220;s&#8221;, ficando &#8220;https&#8221;)</p>
<p>Na 7° página digite &#8220;Google&#8221; (Muito importante que o ‘G’ seja em maiúsculo)</p>
<p>Na 8° página digite seu login do Gmail</p>
<p>e na 9° página coloque sua senha.</p>
<p>Fito isso, selecione &#8220;sync&#8221;</p>
<p>Depois vá em: options -&#62; Change active profile -&#62; e selecione o seu &#8220;profile&#8221;</p>
<p>Vá em seus contatos e selecione: Options -&#62; Synchronization -&#62; Start</p>
<p>Pronto!</p>
<p>________________________________________</p>
<p>Agora para sincronizar sua agenda do Google eu utilizo um software chamado <a href="http://www.googasync.com/" target="_blank">GoogaSync</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Snow Leopard N73 and iSync problem]]></title>
<link>http://chimac.net/2009/10/09/snow-leopard-n73-and-isync-problem/</link>
<pubDate>Fri, 09 Oct 2009 18:42:38 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/10/09/snow-leopard-n73-and-isync-problem/</guid>
<description><![CDATA[Snow Leopard N73 and iSync problem Mysteriously leaving it alone seems to fix the issue.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=2136237&#38;tstart=0" target="_self">Snow Leopard N73 and iSync problem</a> Mysteriously leaving it alone seems to fix the issue.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Samsung Soul and ISync -&gt;&gt;&gt;&gt; SUCCESS (after a bit of tinkering]]></title>
<link>http://chimac.net/2009/10/05/samsung-soul-and-isync-success-after-a-bit-of-tinkering/</link>
<pubDate>Mon, 05 Oct 2009 01:38:30 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/10/05/samsung-soul-and-isync-success-after-a-bit-of-tinkering/</guid>
<description><![CDATA[Samsung Soul and ISync -&gt;&gt;&gt;&gt; SUCCESS (after a bit of tinkering Nice details.  Look for t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=1806373&#38;tstart=0" target="_self">Samsung Soul and ISync -&#62;&#62;&#62;&#62; SUCCESS (after a bit of tinkering</a> Nice details.  Look for the post by Paul</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Nem só com o iPhone se comunica o Mac OS X]]></title>
<link>http://archtec.wordpress.com/2009/09/29/nem-so-com-o-iphone-se-comunica-o-mac-os-x/</link>
<pubDate>Tue, 29 Sep 2009 02:58:32 +0000</pubDate>
<dc:creator>matheusfernal</dc:creator>
<guid>http://archtec.wordpress.com/2009/09/29/nem-so-com-o-iphone-se-comunica-o-mac-os-x/</guid>
<description><![CDATA[Já pensou em manter seu celular sincronizado com com a agenda e o calendário do Mac OS X? Pois saiba]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img src="http://archtec.wordpress.com/files/2009/09/isyncdevices.png" alt="iSyncDevices" title="iSyncDevices" width="450" height="148" class="aligncenter size-full wp-image-145" /></p>
<p style="text-align:justify;">Já pensou em manter seu celular sincronizado com com a agenda e o calendário do Mac OS X? Pois saiba que isso é possível mesmo para quem não é proprietário de um iPhone. Para fazer a sincronização, tudo que será preciso é o <i>iSync</i>, um software que já vem instalado em todas as versões mais recentes do Mac OS X e dependendo do telefone, um plugin que normalmente é fornecido pela fabricante do mesmo.</p>
<p style="text-align:justify;">A vantagem de utilizar o <i>iSync</i> ao invés de softwares específicos (como normalmente acontece no Windows) é que você utilizará os programas nativos do Mac, nesse caso, a <i>Agenda</i> e o <i>iCal</i> que facilitarão muito a sua vida em tarefas que seriam bem chatas se de fazer pelo próprio telefone como adicionar fotos aos contatos. Outra vantagem é que trocando de marca de celular, tudo que precisará ser feito é sincronizar novamente (desde que o novo seja compatível, é claro). Por último, mas não menos importante, tanto a <i>Agenda</i> quanto o <i>iCal</i> podem ser sincronizados com serviços online como os do Google ou o MobileMe, sendo assim, dá pra manter tudo sincronizado no telefone, no Mac e nas nuvens e o melhor, sem gastar nem um kylobyte com conexão via celular.</p>
<p style="text-align:justify;">No seu <a href="http://support.apple.com/kb/HT2824" target="_blank">site</a> (em inglês), a Apple mantém uma lista dos dispositivos compatíveis com o <i>iSync</i> além de um rápido <a href="http://support.apple.com/kb/HT2484?viewlocale=pt_BR" target="_blank">tutorial</a> (em portugês) mostrando como fazer a sincronização. Para aparelhos que não constam na lista, vale a pena conferir no site da fabricante se existe plugin disponível, como no caso do <a href="http://www.sonyericsson.com/cws/support/softwaredownloads/detailed/sonyericssonisync/k660i?lc=pt&#38;cc=br" target="_blank">Sony Ericsson K660i</a>.</p>
<div style="background-color:#C8D1FC;text-align:center;border-color:#0066FF;border-style:solid;border-width:1px;padding:3px;">Esse post foi escrito para o <a href="http://www.pontomac.com/" target="_blank">Ponto Mac</a>, um blog dedicado a assuntos relacionados ao universo Apple.</div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Compatibility with HTC Magic (Android Powered Phone)]]></title>
<link>http://chimac.net/2009/09/22/compatibility-with-htc-magic-android-powered-phone/</link>
<pubDate>Tue, 22 Sep 2009 15:21:17 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/09/22/compatibility-with-htc-magic-android-powered-phone/</guid>
<description><![CDATA[Compatibility with HTC Magic (Android Powered Phone)]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=2085549&#38;tstart=150" target="_self">Compatibility with HTC Magic (Android Powered Phone)</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Samsung S8300]]></title>
<link>http://chimac.net/2009/09/21/samsung-s8300/</link>
<pubDate>Mon, 21 Sep 2009 18:57:57 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/09/21/samsung-s8300/</guid>
<description><![CDATA[Samsung S8300]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=1993332&#38;tstart=195" target="_self">Samsung S8300</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[iSync Conduit not visible in HotSync Conduit Manager]]></title>
<link>http://chimac.net/2009/09/17/isync-conduit-not-visible-in-hotsync-conduit-manager/</link>
<pubDate>Thu, 17 Sep 2009 16:54:57 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/09/17/isync-conduit-not-visible-in-hotsync-conduit-manager/</guid>
<description><![CDATA[iSync Conduit not visible in HotSync Conduit Manager]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=1162624&#38;tstart=30" target="_self">iSync Conduit not visible in HotSync Conduit Manager</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Nokia N97 + iSync]]></title>
<link>http://chimac.net/2009/09/16/nokia-n97-isync/</link>
<pubDate>Wed, 16 Sep 2009 00:52:37 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/09/16/nokia-n97-isync/</guid>
<description><![CDATA[Nokia N97 + iSync]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=2062019&#38;tstart=0" target="_self">Nokia N97 + iSync</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[LG Env Touch VX11000 and iSync...no support?]]></title>
<link>http://chimac.net/2009/09/14/lg-env-touch-vx11000-and-isync-no-support/</link>
<pubDate>Mon, 14 Sep 2009 16:56:24 +0000</pubDate>
<dc:creator>chimac</dc:creator>
<guid>http://chimac.net/2009/09/14/lg-env-touch-vx11000-and-isync-no-support/</guid>
<description><![CDATA[LG Env Touch VX11000 and iSync&#8230;no support?]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://discussions.apple.com/thread.jspa?threadID=2060631&#38;tstart=0" target="_self">LG Env Touch VX11000 and iSync&#8230;no support?</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[iCal-GoogleCalendar-Nokia]]></title>
<link>http://vanucho.wordpress.com/2009/09/08/ical-googlecalendar-nokia/</link>
<pubDate>Tue, 08 Sep 2009 08:22:37 +0000</pubDate>
<dc:creator>vanucho</dc:creator>
<guid>http://vanucho.wordpress.com/2009/09/08/ical-googlecalendar-nokia/</guid>
<description><![CDATA[Bueno, supongamos que no eres un mortal y tienes una Mac. Como yo. Pero que tienes un celular que no]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:center;"><img class="aligncenter" src="http://i619.photobucket.com/albums/tt274/vanovan/ical_google_calendar.png" alt="" width="450" height="296" /></p>
<p>Bueno, supongamos que no eres un mortal y tienes una Mac. Como yo.</p>
<p>Pero que tienes un celular que no es iPhone (como yo) y en ocasiones tienes que despegarte de tu Mac y trabajar en un PC. Como yo. Ahora supongamos que te gustaría ordenar un poco tu vida y desearías tener sincronizado tu calendario sin comprar un PDA/Smartphone que te dé el software para ello pues para ello está pensado.  Mi punto es, cómo tener sincronizado tus eventos de iCal y que te aparezcan en tu cuenta de GoogleCalendar para consultarlo en cualquier computadora en tu navegador favorito y los tengas a mano para cuando no estás frente a un monitor (celular chafa). Para eso este post.<!--more--></p>
<p>Primero, vamos a ver cómo sincronizar entre iCal y GoogleCalendar. Vi que iCal soporta de manera oficial y gratis, agregar un calendario de nuestra cuenta de Gmail pero le encontré un fallo. Sólo es de un lado. No es sincronización como tal. O sea, sólo copia los eventos que tu agregues al GoogleCalendar a tu iCal y por ende, solo a tu Mac. Pero si tu agregas un evento de iCal éste no aparecerá en GoogleCalendar. Entiendes? El soporte oficial de iCal para este servicio sólo lo veo útil si agregas calendarios externos en el que no puedes meter mano. Si eso te interesa puedes <a href="http://thinkwasabi.com/2008/07/sincroniza-ical-y-google-calendar-gratis/" target="_blank">seguir este enlace.</a></p>
<p>Pero si quieres sincronización de ambos lados entonces necesitas un programa externo. Como todo en la vida.</p>
<p>Y éstos son de pago. Cabe decir más. Esta el SpanningSync y BusySync, siendo el que yo uso el último, y que les ofrezco a full en <a href="http://www.mediafire.com/download.php?mqlmwzanh4f" target="_blank">este enlace.</a></p>
<p>Descargas, descomprimes, le das clic al .prefpane que es la extensión para los complementos que se instalan dentro del menú de preferencias del sistema de MacOSX y registras con el serial incluido. Fácil.</p>
<p>Ahora, teniendo el BusySync a full sólo le debes indicar tu cuenta de gmail en la pestaña de &#8220;Google&#8221; en &#8220;Settings&#8221; Metes tu email y contraseña y marcas los calendarios (Personal, Trabajo y otros que tengas) que quieras sincronizar y todo estará listo. Lo demás es cosa que tu le juguetees y te diviertas. Yujú, this is so funny. Aquí una captura para que confirmes si vas por el lado correcto:</p>
<p><img class="aligncenter" src="http://i619.photobucket.com/albums/tt274/vanovan/settings.jpg" alt="" width="398" height="283" /></p>
<p>Cuando tengas listo eso, tienes la mitad hecha. Ahora supón que quieres tener los mismos eventos en tu celular de mortal y agregarlos sin teclear nada en tu cel. Entonces tu debes instalar un plugin para iSync. <a href="http://www.mediafire.com/download.php?qbg00ujqn1t" target="_blank">Te los bajas de este enlace.</a> Tiene un montón de plugins para que puedas sincronizar con iSync (si es que no está soportado oficialmente, puedes checar <a href="http://support.apple.com/kb/HT2824" target="_blank">esta lista</a>). Lo instalé y cuando antes iSync buscaba por bluetooth y decía &#8220;Teléfono Móvil no soportado&#8221;, me lo agarró a la primera y pude sincronizar mis eventos y mi agenda del celular a la Agenda de Mac. Me sentí tan pro debido al hecho que no es un Smartphone. Take that!</p>
<p><img class="aligncenter" src="http://i619.photobucket.com/albums/tt274/vanovan/amo.jpg" alt="" width="425" height="536" /></p>
<p>Lo mejor de todo y que he comprobado, es que si originalmente le pusiste alarma al evento en iCal, éste se copia al celular y te avisa de la misma manera para que no se te olvide. Con eso no hay peros.</p>
<p>Sincronización completa laptop-web-celular. ¿Qué mas quieres? Ah sí, un iPhone 3GS y evitarse todo esto xD.</p>
<p>PD: El dmg de plugins anterior es de unos programadores ajenos, sí lo encuentras (<strong>yo no lo encontré y no todos están</strong>) de la lista de plugins oficiales de la página de Nokia pues más que mejor y tienes la seguridad de la famosa compañía finlandesa sin hacer cosas raras. <a href="http://europe.nokia.com/get-support-and-software/download-software/isync" target="_blank">http://europe.nokia.com/get-support-and-software/download-software/isync</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Nokia 6790 (Surge) iSync plugin]]></title>
<link>http://tnkgrl.wordpress.com/2009/08/05/nokia-6790-surge-isync-plugin/</link>
<pubDate>Thu, 06 Aug 2009 05:08:49 +0000</pubDate>
<dc:creator>tnkgrl</dc:creator>
<guid>http://tnkgrl.wordpress.com/2009/08/05/nokia-6790-surge-isync-plugin/</guid>
<description><![CDATA[There&#8217;s apparently no iSync plugin yet from Nokia for the 6790 (Surge), so I used my developer]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>There&#8217;s apparently no iSync plugin yet from Nokia for the <a href="http://tnkgrl.wordpress.com/2009/08/04/unboxing-the-nokia-6790-surge/">6790 (Surge)</a>, so I used my developer skills and whipped one together. Simply <a href="http://dl.getdropbox.com/u/23528/Software/Nokia-6790.phoneplugin.zip">download</a>, unzip and copy to the /Library/PhonePlugins folder! After pairing your 6790, run iSync, and select Devices&#124;Add Device&#8230;</p>
<p>Enjoy <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Mac-Blackberry]]></title>
<link>http://esotericliberica.wordpress.com/2009/07/28/mac-blackberry/</link>
<pubDate>Tue, 28 Jul 2009 04:40:14 +0000</pubDate>
<dc:creator>M</dc:creator>
<guid>http://esotericliberica.wordpress.com/2009/07/28/mac-blackberry/</guid>
<description><![CDATA[A new version of Blackberry&#8217;s Desktop software will be released in September that offers Mac s]]></description>
<content:encoded><![CDATA[A new version of Blackberry&#8217;s Desktop software will be released in September that offers Mac s]]></content:encoded>
</item>
<item>
<title><![CDATA[Plug-in iSync pour Nokia 2680 Slide]]></title>
<link>http://capheda.wordpress.com/2009/06/19/plug-in-isync-pour-nokia-2680-slide/</link>
<pubDate>Fri, 19 Jun 2009 14:49:19 +0000</pubDate>
<dc:creator>Cà Phê Ðá</dc:creator>
<guid>http://capheda.wordpress.com/2009/06/19/plug-in-isync-pour-nokia-2680-slide/</guid>
<description><![CDATA[Je viens de voir que le Nokia 2680 était disponible en France maintenant, du coup je me suis dit que]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Je viens de voir que le Nokia 2680 était disponible en France maintenant, du coup je me suis dit que ça pouvait intéresser du monde si je mettais en ligne le <a title="Téléchargement du plugin" href="http://yannick.devos.free.fr/download/Plugin2680.dmg">plug-in que j&#8217;ai fait pour iSync</a>.</p>
<p>En effet ce téléphone n&#8217;est pas gérer d&#8217;origine par iSync sous Léopard bien qu&#8217;il se connecte parfaitement en Bluetooth. Heureusement pour nous, Apple livre avec les Developper Tools (XCode) un outil fantastique qui s&#8217;appelle<em> iSync Plug-in Maker</em> et qui fait tout tout seul ou presque.</p>
<p>Ce plug-in n&#8217;est pas testé complètement et présente peut-être des bogues. Toutefois, je l&#8217;utilise depuis un petit moment et je n&#8217;ai rien remarqué d&#8217;anormal en synchronisant mon agenda.</p>
<p>Sinon le 2680 est un excellent téléphone à mon goût, et l&#8217;argument du dos &#8220;anti-rayures&#8221; avancé par la charmante vendeuse s&#8217;avère vrai. Par contre elle ne m&#8217;avait pas dit que la face avant (l&#8217;écran) se rayait en un rien de temps. Je suis plutôt soigneux, le téléphone ne traîne pas souvent avec mes clefs, mais on dirait que je l&#8217;ai nettoyé au tampon jex&#8230;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[[iSync] Plugin Sony Ericsson W995 pour iSync Mac OSX]]></title>
<link>http://thinksmartshop.wordpress.com/2009/06/12/isync-plugin-sony-ericsson-w995-pour-isync-mac-osx/</link>
<pubDate>Fri, 12 Jun 2009 11:02:10 +0000</pubDate>
<dc:creator>Smart</dc:creator>
<guid>http://thinksmartshop.wordpress.com/2009/06/12/isync-plugin-sony-ericsson-w995-pour-isync-mac-osx/</guid>
<description><![CDATA[iSync OSX Sony Ericsson W995 iSync plugin pour Sony Ericsson W995]]></description>
<content:encoded><![CDATA[iSync OSX Sony Ericsson W995 iSync plugin pour Sony Ericsson W995]]></content:encoded>
</item>
<item>
<title><![CDATA[E71 &amp; Mac iSync]]></title>
<link>http://4ting.wordpress.com/2009/05/27/e71-mac-isync/</link>
<pubDate>Wed, 27 May 2009 09:45:01 +0000</pubDate>
<dc:creator>Sandra</dc:creator>
<guid>http://4ting.wordpress.com/2009/05/27/e71-mac-isync/</guid>
<description><![CDATA[Considering how much I&#8217;m utilizing my new shiny e71 to organize things, I decided to find out ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Considering how much I&#8217;m utilizing my new shiny e71 to organize things, I decided to find out if I could sync the e71 calendar to my iCal.</p>
<p>First, you have to go to <a href="http://europe.nokia.com/A4299040">Nokia Europe&#8217;s iSync download</a> page. Click the green &#8220;download&#8221; button and select your device. In this case, the e71. The site uses a scroller-style menu to display the phones.</p>
<p><img src="http://img23.imageshack.us/img23/1974/pic1lrz.jpg"></p>
<p>After downloading the plugin, run iSync. (if it&#8217;s running while you installed the plugin, close and run again.)</p>
<p>Make sure your e71&#8217;s bluetooth is turned on, then add a new device (CMD+N) in iSync. Wait a few seconds for your e71 to get a prompt to allow your Mac to connect to it (and, obviously, allow it).</p>
<p><img src="http://img41.imageshack.us/img41/8708/picture1nwv.png"></p>
<p><img src="http://img39.imageshack.us/img39/676/picture2xop.png"></p>
<p>Once the synchronization has been done, the device icon and name will appear next to the default .mac connection. </p>
<p><img src="http://img43.imageshack.us/img43/5128/sync.jpg"></p>
<p>You can choose to either &#8220;Merge data on computer and device&#8221; or to &#8220;Erase data on phone and sync&#8221;. </p>
<p>As for Contacts, I suppose you could choose to sync certain &#8220;groups&#8221; of people rather than everyone. As I don&#8217;t have anyone in groups yet, it only shows &#8220;All Contacts&#8221; for me. In &#8220;More Options&#8221;, you can sync only contacts with phone numbers &#8211; very useful if you have people with only addresses!</p>
<p>For Calendars, you can choose to synchronize all calendars in your iCal, or just a few. I&#8217;ve created a calendar just for the e71 so that events created on my phone will go there before I edit them into their appropriate categories. You don&#8217;t want to mess up your existing calendars! <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  You can choose not to synchronize events created before, and after certain periods of time.</p>
<p>Now, every time you hit the Sync button, your e71 will receive a prompt to allow access to it. I suppose it is to prevent unwanted synchronizations.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Iphoto 5, Isync, Itunes]]></title>
<link>http://20minuteswithmymac.wordpress.com/2009/04/30/iphoto-5-isync-itunes/</link>
<pubDate>Thu, 30 Apr 2009 04:06:26 +0000</pubDate>
<dc:creator>auntmyrna1</dc:creator>
<guid>http://20minuteswithmymac.wordpress.com/2009/04/30/iphoto-5-isync-itunes/</guid>
<description><![CDATA[Moving on now. I have finished the iphoto tutorials, I must say the text ones are not as entertainin]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Moving on now.  I have finished the iphoto tutorials, I must say the text ones are not as entertaining as the videos.  Now I am working on getting artwork for my missing album art.  I have downloaded <a href="http://www.gimmesometune.com/">, and will see if that works automatically. I am afraid, though, that I will have to use the more labor intensive processes I have found through Yahoo.</p>
<p>I just gave it a shot, and it found Styx Paradise Theater album art right away.  I am happy so far.</p>
<p>Ok, once more.  The Arista 15 years of Hits stumped it, but that is to be expected.  What I don&#8217;t understand is that it found the Beatles Abbey Road, but not the White Album.  It looks like I still have some work to do to complete my album art.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Sync in Plain English]]></title>
<link>http://raystrauss.com/2009/03/15/sync-in-plain-english/</link>
<pubDate>Sun, 15 Mar 2009 12:45:08 +0000</pubDate>
<dc:creator>raystrauss</dc:creator>
<guid>http://raystrauss.com/2009/03/15/sync-in-plain-english/</guid>
<description><![CDATA[Still think Sync is half a band from the 90&#8217;s? Well, you&#8217;re partly correct. Take a look ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Still think Sync is half a band from the 90&#8217;s?  Well, you&#8217;re partly correct.  Take a look at this video from the guys at commoncraft and discover the other half you&#8217;ve been missing.</p>
<p><code><span style='text-align:center; display: block;'><object width='425' height='350'><param name='movie' value='http://www.youtube.com/v/kjQVn5cmqlg&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' /><param name='allowfullscreen' value='true' /><param name='wmode' value='transparent' /><embed src='http://www.youtube.com/v/kjQVn5cmqlg&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' type='application/x-shockwave-flash' allowfullscreen='true' width='425' height='350' wmode='transparent'></embed></object></span></code></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Teléfonos de sustitución y la sociedad de consumo]]></title>
<link>http://escuelasviejas.wordpress.com/2009/02/23/telefonos-de-sustitucion-y-la-sociedad-de-consumo/</link>
<pubDate>Mon, 23 Feb 2009 18:42:16 +0000</pubDate>
<dc:creator>Daniel</dc:creator>
<guid>http://escuelasviejas.wordpress.com/2009/02/23/telefonos-de-sustitucion-y-la-sociedad-de-consumo/</guid>
<description><![CDATA[Quien diga que a mi no me gusta la electrónica, o bien miente, o bien no me conoce. Y claro, dejar e]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Quien diga que a mi no me gusta la electrónica, o bien miente, o bien no me conoce. Y claro, dejar en mis manos un nuevo juguetito lleno de microchips, es algo digno de ver. Se me iluminan los ojos, e intento descubrir como funciona. El problema, es que se trata de un teléfono de sustitución. Y teniendo en cuenta, que la agenda hace años que no se guarda en la tarjeta SIM, nos enfrentamos a un drama digno de mención.</p>
<p>Tener un teléfono sin agenda, es como tener un ordenador sin internet hoy en día. Y yo, que soy precavido, normalmente hago copias de seguridad cada cierto tiempo. Así que ahí estaba yo, intentando sincronizar el mac con el teléfono, para tratarlo como se merece. USB fuera, conectando, y yo feliz.</p>
<p><img class="aligncenter size-medium wp-image-473" title="foto-72" src="http://escuelasviejas.wordpress.com/files/2009/02/foto-72.jpg?w=300" alt="foto-72" width="300" height="225" /></p>
<p>A todo esto hay que añadir, que antes hubo 15 intentos de sincronización bluetooth previos a la conexión por USB. El tema es sencillo, conectar y presionar el botón de sincronizar, y por arte de magia, tendría una agenda completa y ordenada.</p>
<p>Pero no todo era tan sencillo. Presioné sincronizar en el ordenador, metí el código en el teléfono y llegó el momento de pulsar el botón de OK.</p>
<p><img class="aligncenter size-medium wp-image-474" title="foto-73" src="http://escuelasviejas.wordpress.com/files/2009/02/foto-73.jpg?w=300" alt="foto-73" width="300" height="225" /></p>
<p>Y como siempre, con un aparato que no sea Apple, al sincronizarlo con el mac y la aplicación agenda, fallo. Como siempre, fallo. Cansado estoy de la maldita incompatibilidad de los mac, el OsX Leopard y demás castañas añadidas. Resultado: &#8220;Forzar Salida&#8221; y una agenda en blanco.</p>
<p>Tendremos que ir por el camino largo, habrá que hacer una sincronización con la Palm, que también tiene su agenda. Busco el cable en el cajón de los cables, guantes y cosas deslizantes. Conecto, y ahora con algo más de miedo, inicio la sincronización.</p>
<p><img class="aligncenter size-medium wp-image-475" title="foto-74" src="http://escuelasviejas.wordpress.com/files/2009/02/foto-74.jpg?w=300" alt="foto-74" width="300" height="225" /></p>
<p>Error, catástrofe. De nuevo, lo de siempre, fallo de sincronización. Agenda vacía, y un teléfono por usar. Llantos lágrimas y desquiciamientos de frustración. Pero tan difícil es sincronizar dos aparatitos&#8230; Pues parece ser que es la misión imposible del día, si no quieres añadir a mano los ciento-y-pico contactos que están en el teléfono.</p>
<p>Opto por solución drástica. Una fusión a lo bestia, conforme pulso el botón de sincronización acerco los dos dispositivos en un intento de que se hablen entre ellos, pero no hay forma, no hay forma.</p>
<p><img class="aligncenter size-medium wp-image-476" title="foto-75" src="http://escuelasviejas.wordpress.com/files/2009/02/foto-75.jpg?w=300" alt="foto-75" width="300" height="225" /></p>
<p>¿Funciona? Parece que sí, parece que funcionan por inducción. Momento de alegría, se está iniciando la sincronización, por fin voy a tener agenda, por fin voy a tener un teléfono funcional.</p>
<p>No, eso era imposible. Por supuesto que no. Cuando la electrónica se pone en mi contra, SE PONE EN MI CONTRA.</p>
<p>Solución, iniciar una fusión integra con el teléfono y la PDA, es decir, comerme la maldita PDA y asumir que tengo que cargar con ella hasta que me den mi teléfono normal.</p>
<p><img class="aligncenter size-medium wp-image-477" title="foto-71" src="http://escuelasviejas.wordpress.com/files/2009/02/foto-71.jpg?w=300" alt="foto-71" width="300" height="225" /></p>
<p>Además, comérmela en el sentido LITERAL de la palabra, más útil, y más práctico.</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
