Archivo para 2009

ScreenCrop v0.1

ScreenCrop es una pequeña utilidad que he creado en Delphi basándome en una similar que trae Windows 7 y que sirve para hacer capturas de pantalla parciales o totales.

Basta con iniciar la aplicación y, mediante la técnica de arrastrar y soltar con el ratón, dibujar un cuadrado en la pantalla. El contenido de dicho cuadro será copiado al portapapeles en forma de imagen, que luego se podrá pegar en (casi) cualquier sitio.

Si, durante la realización del cuadrado, nos ha quedado mal, se puede cancelar la creación manteniendo pulsada la tecla Control y soltando el botón del ratón. También se puede salir directamente de la aplicación mediante la tecla Escape, o hacer una captura completa mediante la tecla Enter.

Si se hace clic con el botón derecho una vez iniciada la aplicación, aparecerá un menú contextual con las opciones más comunes así como con una pequeña configuración.

Y aquí, como no, una pequeña captura de pantalla (que no, no está hecha con la aplicación :) ):

Captura de pantalla de la aplicación 'ScreenCrop'

Por supuesto, podéis descargaros el ejecutable y, si queréis el código fuente, sólo tenéis que pedirlo.

Descargar ScreenCrop v0.1 – ZIP – 294 KB

Comparaciones

Se compare como se compare, España es de lejos uno de los países más caros de Europa [respecto al precio de Internet].

Viviane Reding, política europea y comisaria de información en la Comisión Europea para el periodo 2004-2009, en una entrevista en Público.

Revolución

En una época de engaño universal, decir la verdad es un acto revolucionario.

George Orwell, escritor y periodista británico.

Einstein y las religiones

La palabra Dios no es más que la expresión y el fruto de la debilidad humana, y la Biblia, una colección de honorables leyendas primitivas, las cuales, no obstante, son bastante pueriles.

Albert Einstein, físico alemán considerado el científico más importante del siglo XX.

De la noticia de El País donde se muestra una carta de Einstein mostrando su postura sobre las religiones.

Y, a su vez, visto en una noticia de Menéame sobre la utilización de una anécdota de Einstein para fomentar la religión.

Otra página basura con (mucho) dinero público

Viendo la nueva página de Promusicae, El Portal de la Música, voy a dejar de lado el hecho de que de lo único que viven estas asociaciones es de las subvenciones del estado. Pero no puedo sino expresar mi ira cuando veo que esta basura de página ha costado 737.000 €.

Captura de pantalla de la página Web 'El Portal de la Música'

Cualquier adolescente con acné que haya salido del instituto con dos dedos de frente y que, al menos, use uno, podrá hacer esto, por llamarle de alguna forma, en menos de una semana.

El diseño gráfico es hilarante. No se han gastado ni un duro euro en carga gráfica. Dos colores y encima planos, sin degradados, sombras y texturas. Sin ese puntillo 2.0 que tanto se lleva ahora, pero no por moda, sino porque vende porque es más usable. Porque, en definitiva, es mejor.

Además, ¡está hecha en Flash! Por dios, ¿a qué persona diseñadora/desarrolladora de páginas Web se le ocurre por un momento, en estos tiempos que corren, hacer una página en Flash? Y, encima, para 61 líneas de código (lo justo para insertar el Flash y un Javascript intrusivo) y tienen ¡24 errores y 6 warnings! en la validación. Aunque esto podría tener dos lecturas, o no tienen ni puta idea, o no quieren que Google y compañía los indexen por eso de no violar los derechos de autor.

Y ya la última gracieta: ¡¡la música arranca según cargas la página!! Viendo esto me decanto por la primera opción. No tienen ni puta idea de hacer páginas Web. Y no es la primera vez que en algo oficial sucede algo así.

Esa página, aún sin cumplir los requisitos mínimos de calidad en el desarrollo Web de hoy, no hubiera costado más de 30.000 € (si alguien dice que eso es barato por esa basura, yo la haría sin dudar —y sin sudar— por ese dinero). Así que esos señores se han embolsado más de 700.000 € de dinero público que es de TODOS.

Quiero que me devuelvan mi parte, que ya la invertiré yo en cosas más útiles y necesarias (por ejemplo).

P.D.: Y, además de todo esto, la reputación de los informáticos queda a la altura del betún al ver la mierda que sale de algunas manos que se hacen pasar por ingenieros. Para que luego no regulen nuestra profesión…

Juegos retro: SimCity 2000

El SimCity 2000 era un juego de simulación de construcción de ciudades. Este lo tenía mi primo y la instalación ya ocupaba 2 disquetes.

La odisea de la copia es parecida a la que tuve con el Prehistorik 2: como ya estaba instalado y ocupaba unos 2 MB, copié todos los archivos a un disquete menos uno que ocupaba casi los 2 MB, por lo que no se me ocurrió otra cosa que abrirlo con el editor de texto, seleccionar hasta la mitad, más o menos, y guardar lo seleccionado en otro archivo quitándolo del primero. Cuando llegué a casa los uní y… no funcionó. Lógico.

Luego no recuerdo como llegué a conseguirlo, pero las horas que pasé delante del ordenador construyendo mi cuidad no fueron pocas. Y la verdad es que se podían construir ciudades bastante chulas.

Ejemplo de ciudad en SimCity 2000

Ejemplo de ciudad en SimCity 2000

Y también lo tengo en una máquina virtual, por si algún día quiero rememorar viejos tiempos.

Juegos retro: Prehistorik 2

El Prehistorik 2 fue uno de los primeros juegos que tuve en mi 486 a 66 MHz. Lo conseguí del instituto, donde alguien lo había puesto. Para copiarlo me pillé un disquete (sí, esas cosas cuadradas y negras que hacían ruidos extraños al leerse) y copié el archivo prehisto.exe. El resto, ¿para qué, si este es el archivo que ejecuto? Lógicamente no funcionó. En aquella época sabía algo menos de lo que se hoy (menos mal ;) ).

Pantalla de presentación del juego 'Prehistorik 2'

Después de conseguir traerlo para casa al día siguiente de informática empecé a cocerme enriquecerme algún tiempo diario. Hasta que, llegada la fase final y después de unos cuantos intentos infructuosos, decidí dejarlo, no por imposible —que también— sino por que ya me aburría un poco. Es lo que me pasa con los juegos :( .

El juego era un juego de plataformas arcade donde tenías a un cavernícola recorriendo el mundo y acabando a mazazos con los demonios de Tasmania y otros bichos, consiguiendo frutas y puntos hasta llegar a la fase final. Gran juego para la época.

Pantalla del juego 'Prehistorik 2'

Y aunque no juego, todavía hoy lo tengo instalado en una máquina virtual sólo para rememorar aquellos tiempos ;) .

Blasfemia

La fe no es una razón.

La mejor blasfemia del concurso de blasfemias (en inglés). Y hay unas cuantas más (en español), y también hay algunas perlas en los comentarios de Menéame, que es donde lo vi.

Frases de “Pazos”

El conceto… esa es la cuestión.

Vamos a llevarnos bien porque sino van a ver hondonadas de hostias ¿eh?

El señor Villambrosa, que es un gen-tel-man, me dijo que viniera a solucionar esto con pacifismo, así que A: lo mismo que le digo una cosa le digo la otra; y B:… y cuidado que igual te viene la C.

En tanto en cuanto nos dean lo que es nuestro, discutiremos ese conceto con el fin de discutirlo.

Mira nena, aquí hay una cuestión: el “conceto” es el “conceto”. Esa es la cuestión. Por ejemplo, tu eres una mujer con estudios, yo no objeto nada al respective porque soy liberal… y no soy de esos que van diciendo que son todas más putas que las gallinas… aunque lo piense. Pero, ¿y el concepto, eh? ¿eh? ¡Amiga! A los hechos me repito.

La teoría en la práctica es otra…

¿Villambrosa? Villambrosa es un cabrón… tiene mucha plata, nada en la ambulancia.

Con los hijos estudiando en los mejores colegios de Kanfort.

Manuel Manquiña como «Pazos» en Airbag (1997).

Clonar un objeto en Javascript

En Javascript las variables que apuntan a objetos son referencias, por lo que la asignación entre las mismas se hace de esta forma con lo que la modificación de una de estas variables afecta al resto de referencias. Por ejemplo:

var myObject = {
text: ‘Clonning Objects’
};

var mySecondObject = myObject;
mySecondObject.text = ‘Clonando Objectos’;

// saldrá una alerta con el texto ‘Clonando Objetos’ ya
// que las variables se asignan por referencia
alert(mySecondObject.text);

En el alert(...) saldrá el texto ‘Clonando Objetos’ ya que ambas variables apuntan a la misma zona de memoria, de ahí las referencias. Es debido a esto, y que en algunas ocasiones necesitas clonar un objeto, por lo que es necesario implementar una función que lo haga. Para ello tenemos esta función, que la he visto en StackOverflow aunque la he retocado un poco, que funciona perfectamente:

function clone(from) {
if(from == null || typeof from != “object”)
return from;

if(from.constructor != Object &&
from.constructor != Array)
return from;

if(from.constructor == Date ||
from.constructor == RegExp ||
from.constructor == Function ||
from.constructor == String ||
from.constructor == Number ||
from.constructor == Boolean)
return new from.constructor(from);

var to = {};
to = to || new from.constructor();

for (var name in from) {
to[name] = typeof to[name] == “undefined” ?
this.clone(from[name]) :
to[name];
}

return to;
}

Con esta función, el ejemplo anterior se convierte:

var myObject = {
text: ‘Clonning Objects’
};

var mySecondObject = clone(myObject);
mySecondObject.text = ‘Clonando Objectos’;

// saldrá una alerta con el texto ‘Clonning Objects’ ya que,
// aunque las variables se asignan por referencia, nuestra
// función ha clonado nuestro objecto con lo que son dos
// objetos distintos
alert(mySecondObject.text);

Y aquí el mensaje del alert(...) ya será ‘Clonning Objects’. Con esto ya podemos duplicar objetos… Pero, como no había quedado muy conforme con la solución seguí buscando, más por encontrar otro tipo de solución (no veo lógico que Javascript no tenga una forma nativa de clonar objetos) que por mejorar rendimiento. Y, aunque no encontré la forma nativa (creo que no la hay), sí encontré otra mucho más corta y más elegante:

function clone(o) {
return eval(uneval(o));
}

La función eval(...) coge un texto y lo evalúa como su fuese Javascript, de forma dinámica. Y, lógicamente, la función uneval(...) hace lo contrario: dado un código en Javascript —una clase, un array, etc.— lo convierte en el texto correspondiente, por lo que esta función lo que hace es convertir el objeto en texto y el texto generado otra vez en objeto, clonando así el objeto que se pasa como parámetro.

De estas dos formas, la segunda solución me parece más elegante —pocas cosas se consiguen en una sola línea de código—. El problema que puede existir es el rendimiento, ya que no he visto nada por ahí y yo tampoco he hecho pruebas, así que la decisión queda para cada uno. Yo he probado las dos y ambas funcionan sin problemas. Si alguien hace sus pruebas, que comente sus resultados.

La comunicación entre procesos de Android

Viendo ayer la comunicación entre procesos se ve que en Android se usa OpenBinder. Pero he mirado la lista de procesos y he visto que existe un daemon llamado dbus-daemon que también se está ejecutando.

Y yo me pregunto ¿por qué si Android usa OpenBinder como sistema de comunicación entre procesos, también está el sistema D-Bus para hacer lo mismo? ¿Por qué este sistema es redundante?

Logo Bluetooth

Pues parece ser, según me ha informado mi amigo Héctor, que la pila Bluetooth de Android está basada en Bluez, la implementación oficial de la pila Bluetooth en Linux. Y resulta que esta implementación utiliza D-Bus para comunicarse con el resto de los procesos, como se puede observar en el diagrama donde se explica su funcionamiento.

Espero que pronto implementen su propia pila Bluetooth o, al menos, que reimplementen la comunicación de la actual adaptándola a OpenBinder, porque lo que pasa con esto es que existe un proceso adicional e innecesario que lo único que hace es comsumir memoria, tiempo y de procesador y, sobre todo, batería. Y la verdad es que Android es un sistema bastante bien hecho y que está calando profundo como para que estén con estas cosas.

Game & Watch Shuttle Voyage

Viendo el emulador de Parachute para Android, un juego de las antiguas maquinitas del estilo de Game & Watch (aunque creo que esta no era original) me acordé de que allá por 1988 (más o menos), yo también tuve el mío, Shuttle Voyage, que, si no recuerdo mal, vino de Canarias de la mano de una de mis tías:

Juego, del estilo de Game & Watch, Shuttle Voyage

El juego trataba de llevar la nave desde la parte izquierda hasta la parte derecha cada vez que presionabas el botón de la derecha tratando de evitar que te tocasen los satélites. Además tenías la posibilidad de cambiar la posición de la nave de arriba a abajo y viceversa para esquivar a los satélites. Cada vez que llegaras al final te daban puntos. Cuantos más puntos, mejor.

Además también tenía calculadora y un soporte por detrás para ponerlo igual que un marco de fotos porque también tenía reloj. Para aquella época era impresionante. De hecho pocos éramos los que teníamos algo parecido.

A parte de este también jugué, con mi hermano y mi primo (el dueño de la maquinita), al Game & Watch Green House que tenía doble pantalla. De lo que se trataba era de que los bichos del jardín no te comiesen las plantas mediante un spray. En la pantalla de abajo tenías arañas que tenías que hacer volver a su tela o, si estaban en la última posición antes de comerte la planta, las matabas.

En la pantalla de arriba había gusanos desde el centro hacia los lados que tenías que matar para que no te comieran las flores. Lógicamente, para pasar de una pantalla a otra había unas escaleras que tenías que subir y bajar.

Game & Watch Green House

Como en el otro juego, cuantos más puntos, mejor. Porque en realidad no había más que eso, conseguir puntos. Pero la verdad es que pasamos unos ratos muy buenos jugando, no sólo yo, porque en realidad uno jugaba y los otros animaban.

Comunicación entre procesos

A la hora de desarrollar un sistema operativo, después de haber planificado la gestión de memoria y la gestión de procesos e hilos, le toca el turno a la comunicación entre los distintos procesos, IPC en inglés, imprescindible para el funcionamiento del sistema.

Para la comunicación a bajo nivel (en el kernel) entre hilos existen varias técnicas que se pueden resumir en:

  • Memoria compartida: Varios procesos, aunque en espacios de memoria distintos, comparten una zona de la misma donde leen y escriben los datos a compartir. La ventaja es que se pueden compartir grandes cantidades de datos y es un sistema muy rápido y sin problemas para lecturas. En cambio, existe el problema de la sincronización del acceso cuando varios procesos tienen que escribir en la misma zona de memoria simultáneamente.
  • Paso de mensajes: Es un sistema donde, mediante canales compartidos entre los procesos, éstos leen y escriben para comunicarse. Se suele implementar mediante sockets, pipas y FIFO‘s aunque hay más tipos de implementación. La ventaja es que las lecturas y escrituras son síncronas por lo que no hay problemas de lectura y escritura simultáneas. El problema es que la cantidad de datos a comunicar puede estar limitada.

El sistema operativo BeOS y su sucesor, Haiku, han implementado una solución muy elegante: por un lado, como los sistemas compatibles con POSIX tiene la compartición de memoria; por otro lado, implementó dos técnicas adicionales:

  • El paso de mensajes entre hilos directamente mediante las funciones send_data(...) y receive_data(...) con el inconveniente de que las funciones son síncronas y después de enviar el primer mensaje, hasta que no se lee no se puede enviar otro.
  • El paso de mensajes mediante puertos. Los puertos son el homólogo a los sockets pero entre procesos y mucho más rápidos. Existe un elemento común entre dos hilos llamado “puerto” a través del cual los procesos se comunican mediante las funciones write_port(...) y read_port(...). La ventaja de esto es que el puerto puede tener un buffer por lo que, hasta que no se llene, las llamadas a estas funciones son asíncronas.

Con estas dos técnicas, se consigue tanto la comunicación entre procesos como la sincronización entre distintos hilos gracias a que las llamadas a las funciones de lectura y escritura son síncronas.

Debido a que este tipo de comunicación, aunque muy rápida, es bastante complicada de aplicar, sobre todo porque los datos pasados entre los distintos procesos no tienen tipo, son flujos de bytes, se han implementado otras técnicas de comunicación, pero estas a nivel de aplicación, es decir, no es el proceso el que responde, sino la aplicación completa mediante una API dedicada a ello.

Algunos ejemplos de estas implementaciones son RPC, MPI, COM, DCOM, DDE, OLE, CORBA, ICE, D-Bus, DCOP, MBUS, RMI, Sockets, Doors, OpenBinder, etc.

En esta lista hay que destacar OpenBinder. OpenBinder es una implementación de un nuevo tipo de comunicación entre procesos. Este proyecto nació con lo que iba a ser la siguiente versión de BeOS, la 6, aunque posteriormente maduró dentro de Palm al ser esta empresa la que compró los derechos sobre BeOS.

OpenBinder está un nivel por encima del resto de implementaciones de comunicación entre procesos. Y digo un nivel por encima porque esta API proporciona una comunicación, por decirlo de alguna forma, a nivel de componentes, es decir, los componentes del sistema operativo, incluyendo los componentes de la interfaz gráfica (ventas, botones, etc.) son clases que heredan de clases de OpenBinder, con lo que cualquier componente es susceptible de comunicarse con cualquier otro. Este sistema inicialmente implica bastante complejidad, pero está optimizado para ser muy rápido y, además, lo que se pretende con él es poder hacer aplicaciones, especialmente GUI‘s como las X, que sean distribuidas de forma transparente para el desarrollador.

OpenBinder no merecería más atención que la del resto de sistemas si no fuese porque esta tecnología está implementada dentro del sistema operativo Android, dejando de lado el resto de sistemas. Esto es cuanto menos curioso, ya que el resto de tecnologías están ampliamente probadas y esta, quizá, sea la más nueva. Pero aquí es donde se ve lo que gasta Google en I+D; no se conforma con lo que hay, quiere lo mejor (según ellos, claro).

Y ya puestos, se pueden empezar a hacer conjeturas: por ejemplo, los dispositivos Android completos podrían estar en la nube de Google, no sólo los datos que manejan, por lo que tu teléfono móvil o tu ordenador podrá ayudar a Google a procesar sus propios datos.

Ahora hay que esperar un poco más a que salga Chorme OS para ver qué sistemas de comunicación tiene y saber si esta teoría será real o una simple paranoia mía :) .

Coches

Cuanto más grande es el coche y más dinero cuesta, menos vale el tipo que lo conduce, a no ser que sea chófer, claro.

Sexto Sevilla d’Teodora, escritor novel.

Analizando GCD

Hace unos meses que Apple sacó a la venta la última versión de su sistema operativo, Mac OS X 10.6 Snow Leopard.

Esta versión es principalmente una versión de, como dicen ellos, afinamiento. No se han incorporado características nuevas sino que se han refinado las actuales dándole al sistema una mayor velocidad y estabilidad. Lo que sí han hecho es incorporar en el núcleo del sistema una tecnología que no se ve pero que sí se nota: Grand Central Dispatch.

Logotipo de Grand Central Dispatch

GCD es una nueva tecnología que lo que hace es distribuir las tareas que tienen que hacer las aplicaciones en tareas más pequeñas para así aprovechar toda la potencia de las máquinas que tienen varios procesadores o varios núcleos por procesador, como viene siendo habitual en los ordenadores de hoy en día, no sólo los Apple.

Esta tecnología viene a solucionar el problema de la escasez de paralelismo con la que contaba Mac OS X, pero, más que por su incapacidad, por la desidia de los desarrolladores a incorporarlo en sus aplicaciones. Aunque tienen sus razones, claro, es bastante complicado sincronizar hilos cuando no tienes un API que te ayude a hacerlo.

GCD añade dos cosas al nuevo sistema operativo de Apple. La primera es lo que se conoce como un pool de hilos, es decir, en lugar de que cada vez que queramos realizar una acción de forma paralela creando un hilo para así aprovechar los diferentes procesadores, lo que hacemos es indicar al sistema que queremos realizar tareas paralelas. Es el propio sistema el encargado de crear los hilos correspondientes y de ejecutarlos con una de las tareas a realizar.

La diferencia con los hilos tradicionales es que los hilos de GCD ni se crean ni se destruyen (esto me suena), simplemente existe una o varias listas de estos hilos (el pool) donde cada tarea se va a asociando a cada uno de estos hilos hasta que termine. Una vez terminada la tarea, el hilo no se destruye, sino que vuelve a la lista correspondiente. Además, estas listas de hilos tienen diferentes prioridades con lo que se puede tener más precisión a la hora de ejecutar tareas.

Lo bueno que tiene esto es que el programador no tiene que preocuparse de nada más que de indicar cuáles son las tareas a realizar de forma paralela. El sistema se encargará de distribuirlas entre las distintas listas de hilos disponibles.

Pero para lograr esto, Apple se ha tenido que sacar de la manga una extensión para el lenguaje C de su compilador Clang. Esta extensión es lo que se conoce en otros lenguajes, como Java o Javascript, como closures. Las closures son funciones anónimas o funciones lambda, algo así como los punteros a funciones de C pero con capacidades extras, como el acceso a variables locales, que se puedan devolver por otra función o que se puedan declarar en línea.

A esto, los desarrolladores de Apple le llamaron bloques. Entonces un bloque sería un trozo de código ejecutable que se parece a una función pero que no tiene nombre (función anónima) y que puede acceder a las variables locales del ámbito donde se ha declarado. Y la sintaxis que han hecho es al mejor estilo de C: austera. Veamos unos ejemplos, aunque la forma de trabajar es similar a Java y Javascript pero con distinta sintaxis:

// bloque asignado a una variable y accediendo
// a una variable local
int b = 3
multiplicar = ^ int (int a) { return a * b; };

// x valdría 6
int x = multiplicar(2);

// declaración de un tipo de bloque
typedef void ( ^ my_block_type)(int count);

// función que repite la ejecución de un bloque n veces
void repeat(int times,my_block_type block) {
for(int i = 0; i < times; i++) {
block(i);
}
}

// declaración en línea (pasando como parámetro
// un bloque completo sin declararlo previamente
// como se hace con los punteros a funciones)
repeat(10, ^ (int count) {
printf(“count = %d\n”,count);
});

Gracias a esta nueva extensión, con apenas trabajo por parte del desarrollador, se puede aprovechar toda la potencia de las máquinas multiprocesador. Y, realmente, cuando se dice con “pocas líneas” es cierto. Basta con identificar las tareas (ese es el trabajo difícil) y usar las funciones dispatch_* de la nueva API pasando como parámetro un bloque de código con la tarea a ejecutar. Es el sistema, de forma transparente, el que se encarga de distribuir las tareas en los distintos procesadores creando los hilos necesarios para ello o utilizando los que están en el pool.

La verdad es que hay que agradecer a Apple que por fin se pusiese las pilas en cuanto al rendimiento de sus sistema, que ya iba bien de por sí, pero siempre puede ir mejor, sobre todo por facilitar el paralelismo de tareas a los programadores. Y aunque esto está muy bien, todavía no he visto por ningún sitio cómo han solucionado el problema de la sincronización/comunicación entre tareas (a parte de la memoria compartida y semáforos, claro), ya que esta extensión es sólo para aprovechar las máquinas multinúcleo.

Y es que, a mi entender, creo que esta solución que tan bien les está yendo, es un parche para un problema que viene de lejos. Venga, va, aquí los abucheos por criticar el Mac OS X. Pero expongo mis razones:

Esta solución crea un pool de threads con los que, a partir de un momento dado, se empiezan a realizar tareas sin la necesidad de estar creando y destruyendo hilos continuamente sino reaprovechándolos. Existe más de un pool con diferentes prioridades para así gestionar mejor las tareas. Esta solución es así porque la forma en Apple que implementó los hilos en Mac OS X no es la de lightweight threads (hilos ligeros) sino la de hilos más parecidos a procesos que a hilos en sí.

Esta solución implica que la creación de cada hilo sea bastante costosa, aproximadamente unos 512 KB por cada uno, mientras que la solución de hilos ligeros, la que implementan BeOS y Haiku (sí, ha salido BeOS, ¿raro en este blog? :) ) es la de verdaderos hilos ligeros, con lo que la creación de los mismos apenas lleva 50 KB (32 KB de memoria de pila y el resto de estructuras internas del kernel).

512 KB por hilo creado es mucha memoria utilizada. Y más teniendo en cuenta la cantidad de aplicaciones y servicios que se están ejecutando en un sistema operativo actual según se inicia. Por pocos hilos que crees estás consumiendo mucha memoria y hay que tener en cuenta que cuantos más hilos (ojo, con un límite), más paralelismo y mayor aprovechamiento del hardware. Y vale que ahora la memoria es barata, pero ¿los nuevos sistemas funcionarán en hardware antiguo? Quizás esto no sea una prioridad para Apple, pero siempre hay que pensar en todo.

Como comenté antes, tampoco sé exactamente como se sincronizan las tareas en Mac OS X, mientras que en BeOS/Haiku tenemos tres mecanismos muy ligeros para ello: semáforos, comunicación entre hilos y puertos. El problema es la complejidad a la que se enfrenta el programador para hacer esta sincronización, aparentemente solucionada en Mac OS X, pero que no debería ser un problema si existe una buena API dentro del sistema que lo facilite.

En conclusión (y ya para terminar este ladrillo de entrada) creo que Apple ha mejorado mucho su sistema con esta característica, tanto para los usuarios, aprovechando el hardware al máximo, como para los programadores, haciendo que con escasas líneas de código aprovechen mejor dicho hardware, pero sigo pensando que la solución inicial de hilos pesados no es tan buena como la solución de hilos ligeros.

27 horas

19 horas de llamada a Vodafone

Esto es lo que ha estado esperando al teléfono un usuario de las redes Vodafone cuando intentó hacer una consulta en el 122 para que le solucionasen un problema. Lo peor, al final le colgaron la llamada.

Aparte de la desfachatez y desvergüenza que tienen algunos servicios de atención al cliente de algunas empresas, no únicamente los de Vodafone, hay que destacar lo bien que funciona el HTC Magic con Android estando 27 horas con la radio GSM en comunicación :) .

Cacharros tecnológicos a parte, habrá que ver como va evolucionando el asunto y qué es lo que hará Vodafone después de este pequeño incidente. Y para eso hasta tenemos un grupo en Facebook con casi 2000 fans desde el que se puede seguir a “El chico que esperó mucho rato a que le antendieran en atención al cliente”.