martes, 22 de noviembre de 2011

~~Tiempo, concedeme tan solo un segundo~~

Siempre quise ser cantante

Siempre quise, escritor

Solo quise darle un motivo

de vivir a mi quebrada voz

Se escapaba de mi interior

mi roto corazón, maltrecho y desolado

como un puente olvidado, que nadie más cruzó.

De beberlas en tu ausencia

destilo lagrimas en quebrado frasco

con ellas me embriago

para así ahogar las penas...

me sobran los motivos para no volver a mirar el reloj.

Ya no hay espera, solo condena

triste y desolado, se morirá el amor.

marchitándose como pétalos,

Atado con tu cadena.

Como un ramo inspirador,

que colgado boca abajo espera escuchar

la llave que le permita volver a caminar.

No son gente, son dementes

que arrebatan a la muerte,

lo que un día yo quise robarte

para mi y para ti, no es egoísmo, si no resurgir...

quiero escribir estas líneas para ti

Y escribir al fin un final feliz.

Para decirte que adiós, para suplicarte un perdón

para dejarte marchar un olvido y se acabo..

quiero no sufrir por melancolía ni un día mas

Me hice viejo y te vi crecer, aprendiste y te utilice

acabo todo en un papel, y ahora que no tengo nada que enseñar, ni esconder...

De beberlas en tu ausencia

destilo lagrimas en quebrado frasco

con ellas me embriago

para así ahogar las penas...

me sobran motivos para no llorar al mirar el reloj.

Se acabo el tiempo y las penas, es hora de a andar aprender.

este es el principio, el final y el descanso.

donde están los suspiros, donde están mis canciones,

siempre quise ser escritor, cantante, darle a mi voz un sentido.

Encontré lejos el camino, ahora dejo atrás esta ciudad derruida.

Dame solo el ultimo beso, y un segundo...

No mas castillos de arena, no mas conciertos en la cama.

Se acabo el suspirar por tus besos en la almohada.

Mejor despierto otro día, digo adiós amada mía,

el tiempo se detiene, no hay pasado ni presente.

Esta todo inerte.

Ya no hay motivos para tener un reloj...

~~Conejo blanco~~

Escapas, como el agua que fluye entre mis dedos.

Corres a tu madriguera, este es el conejo,

un camino espinoso en tierra de nadie,

donde mis sueños dejan paso a tu realidad.

Estate quieto, déjate coger, eres mío, lo fuiste, lo seré.

olvídate ya de correr, no me gustan tus mundos,

no me gusta en lo que te conviertes si no estoy en el.

Sal de tu madriguera no me hagas volver.

Donde están tus besos, donde están tus abrazos,

eres un maldito conejo blanco, espera, no corras tanto.

Despierta pequeña Alicia, el reloj se dejo de mover.

Asta marzo y otra vez, en tu ausencia solo se enfría el te,

el lirón le contagio a la liebre su apatía

y asta las flores se marchitaron.

ni cantar tiene sentido ni alegría.

No hay alarmas, no hay cantares, no hay dulces ni amistades.

Los animales se devoran, los soldados se consumen en los rosales.

Esto dejo de ser una aventura,

Solo queda lo que forjaste para mi, el País de las pesadillas...

Donde están tus andares, donde están tus pasiones

eres un maldito conejo blanco, espera, no corras tanto.

Ya no hay reinas ni princesas,

no hay caballeros ni condesas.

Como la sonrisa de un gato que nunca estuvo,

desapareces entre llantos, cual cordura entre agravios.

Y entre tanto solo un rato, me despisto cual muchacho.

ya no hay fabulas ni cuentos, solo rosas y sombreros.

Y el pobre sombrero persiguiendo a los conejos.

Donde están tu cordura donde esta mi locura

eres un maldito conejo blanco, espera, no corras tanto.

Si te atrapo te libero, ya no queda sentido alguno...

Quien lo quiere. YO NO!!!

~~Danza de Sangre~~

Lloraba en un esquina, sin saber que hacer.

Fingía ser feliz, y todo el mundo le aplaudía.

No me hacías falta, era feliz en las mentiras.

Mirada triste, mirada fría,

Melancolía.

envidia, dolor...

muñeca rota.

Y el llego, y trajo una cagita con el.

Seras feliz si danzas para mi,

En su interior, dos zapatitos de charol.

La niña volvió a andar.

Era feliz con sus danzares, era feliz con sus pesares.

Al principio a saltitos, después a saltos grandes.

Era el momento de reír, ya llegarían después las penas.

Comenzó con pequeños brincos, termino con un danzar.

Al principio todo eran sonrisas,

la voz de aquel que le animaba, no era mas que su alegria.

Dio de espalda a sus amigos, y a sus seres queridos.

Esos zapatitos le daban la felicidad.

Pero pronto llego la melancolía, los pies no podían parar.

cantaba, danzaba, lloraba sin cesar.

Danza pequeña, por no querer escuchar.

Ahora eres marioneta, y no una muñeca dulce como la que mas.

Danza y sueña, tus pies sangran, envejecerás...

en las danzas que un demonio preparo para ti.

sangraras, te romperás.

Adiós mi dulce muñeca.

Y entre lagrimas y sangre meneas la mano.

Adiós, sonríes, adiós...

Mirada triste, mirada fría,

Melancolía.

envidia, dolor.

muñeca rota...

~~Suben~~

Suben. Bajan. No se inmutan..

Cambia todo tan rápido que da miedo, las horas son solo minutos y los años suspiros. Las personas cambian, se marchitan y florecen de golpe. ¿Cuando me marchite yo?

Encuentras la luz. Esa luz, no cualquiera. Te llevaría conmigo, te metería en una bonita bola de cristal y te daría de comer por una pequeña rendija.

Lo cierto, es que me daría miedo saltar.

Ahora es roja y quiere rosa en su vida, antes pretendió que el negro fuese su bandera. Con dos tibias y una calavera, como el Maestro. Y le gusta soñar con esa vida que no puede alcanzar, calmando la ansiedad pensando que este año todo cambiará.

No me calientes que me hundo, me sobrecargo y la has liado, quemas mis fusibles de una manera increíble, acojonante. Fundeme hoy también, una y otra vez como sabes hacer.

Calor, calor, calor...

~~Mil petalos~~

Y quedaran en mi lecho, mil caricias y mil besos

quedaran mil abrazos y mil versos

y queda en mi cama, mil recuerdos...y la soledad de tu ausencia...

Abro el bote de dulces, hoy es un día triste,Ante mi depara un nuevo día,

y el amanecer me recuerda que no estas aquí.

Miro con desprecio el vehículo que te aleja de aquí,

miro con esperanza en el móvil, a ver si te acuerdas de mi.

Y esperare una llamada o un mensaje, una carta o un suspiro...

Puedo contarte mil cuentos,

llenarte los sueños de abrazos que traigan solo buenos.

pero mirar mi cama vacía y pensar... no estas.

Beber de tu ausencia, llorar por lo bello. Quédate con lo bonito,no te rindas vida mía

deja caer esa lagrima y dedícame una ultima sonrisa,

Mírame con esos ojos de gata.

Y quedaran en mi lecho, mil caricias y mil besos

quedaran mil abrazos y mil versos

y queda en mi cama, mil recuerdos...

y florecen los recuerdos de días que marcaste con tu mirada...

domingo, 25 de septiembre de 2011

El monstruo sin nombre

Dedico esta entrada a la gente de Tqdie! que estuvo en un momento dificil de mi vida, cuando estaba cojo perdido... En especial a Oscar y Cris mi pistachia!

Este es el cuento que sale en Monster! es un buen manga, espero que lo leais:

Érase una vez, en un país muy lejano, habitaba un monstruo sin nombre. Este deseaba un nombre con todas sus fuerzas, tanto lo deseaba, que apenas podía pensar en nada más, es por esto que un día, decidió hacer un viaje para conseguir lo que tanto anhelaba.

Pero el mundo es grande, así que se dividió en dos para continuar el camino. Uno de ellos fue al Este y el otro al Oeste.

El monstruo que fue al Este encontró una aldea, allí encontró un herrero a la entrada.

- Oh señor herrero dame tu nombre -solicitó.

- Pero ¿qué tonterías dices? - sugirió incrédulo - No pienso darte mi nombre - exclamó.

- Si me das tu nombre, a cambio me introduciré dentro de tí y te daré toda la fuerza que te falta - Dijo el monstruo.

- ¿En serio?-preguntó - Si vas a hacerme más fuerte entonces, te daré mi nombre- aceptó gustoso el herrero. El monstruo se introdujo en el hombre y desde entonces se convirtió en Otto el herrero. Otto era el hombre más fuerte de la aldea. Sin embargo un día…

“¡Mírame! ¡Mírame! ¡Mira que grande se ha hecho el monstruo en mi interior!”.

"Grush Grush, Ñam Ñam, Grumpf Grumpf, Glup”

El monstruo, que tenía mucha hambre, se comió a Otto desde dentro, y volvió a ser un monstruo sin nombre.

Aunque también se introdujo en el zapatero Hans… “Grush Grush, Ñam Ñam, Grumpf Grumpf, Glup”. Volvió a ser un monstruo sin nombre.

Y al poco tiempo también lo intentó con el cazador Thomas, pero... “Grush Grush, Ñam Ñam, Grumpf Grumpf, Glup”. Una vez mas volvió a ser un monstruo sin nombre.

Entonces el monstruo, ingresó en el castillo, donde encontró a un principe que se encontraba muy enfermo.

- Si me das tu nombre te haré más fuerte - le ofreció entonces al niño.

-Si logras que me recupere y me haga más fuerte, te daré mi nombre - dijo el jovencito.

Entonces el monstruo se introdujo en el niño y éste se recuperó totalmente, haciendo felices a todos en el castillo.

-¡El Príncipe se ha curado! ¡el Príncipe se ha curado!- gritaba con regocijo el Rey y los súbditos también celebraban la recuperación del chico.

Al monstruo le gustó aquel nombre y la vida en el castillo, por eso aunque se moría de hambre, se contenía. Y un día tras otro hacía grandes esfuerzos para soportar el hambre...hasta que un día...

“¡Mírame! ¡Mírame!" "¡Mira que grande se ha hecho el monstruo en mi interior!”

... El niño se comió a sus sirvientes, a su padre y a todos los que habitaban la aldea.

“Grush Grush, Ñam Ñam, Grumpf Grumpf, Glup”

Al ver que no quedaba nadie, el niño se fue de viaje. Caminó por varios días hasta que finalmente un día se encontró con el monstruo que había ido al Oeste.

- Yo tengo nombre, es un nombre muy bonito - comentó gustoso el muchacho.

El monstruo que fue al Oeste dijo - No necesitas un n

ombre, puedes ser feliz sin uno. Somos monstruos sin nombre al fin y al cabo -

El niño en ese momento, se comió al monstruo que había ido al Oeste y... Aunque por fin había conseguido un nombre, no quedaba nadie que pudiese llamarlo...

...aun siendo Johan un nombre tan bonito.

domingo, 24 de abril de 2011

Origen en C (la pelicula)

Para la gente que le gusto la pelicula de Origen, traigo una original tributo en clave de programacion C... esta se la dedico a los colegas programadores de KoeRo xDDD

/* INCEPTION: My tribute to Christopher Nolan
; The code below tries to explain and follow the sequence of events that took place in Inception
; as seen from the eyes of the programmer. It performs the inception through a clever trick
; using x86 code morphing technique in inception.h. This is done so as to make it appear that the thought
; about copying the inception string was done by Fischer himself even though he expected to return to
; a different state in real life.
;
; Copyright (C) 2010-2011 A.R.Karthick
;
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
;
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include

#ifdef __linux__
#include
#define GET_TID syscall(SYS_gettid)
#else
#define GET_TID ({0;})
#endif

#include "list.h"
#include "inception_arch.h"

#define DREAM_INCEPTION_TARGET 0x1
#define DREAM_INCEPTION_PERFORMER 0x2
#define DREAM_WORLD_ARCHITECT 0x4
#define DREAM_ORGANIZER 0x8
#define DREAM_SHAPES_FAKER 0x10
#define DREAM_SEDATIVE_CREATOR 0x20
#define DREAM_OVERLOOKER 0x40
#define DREAM_ROLE_MASK 0x7f
#define DREAMERS (0x7)

/*
* fprintf output buffer is thread-safe anyway. So don't care much
*/
#define output(fmt, arg...) do { fprintf(stdout, fmt, ##arg);} while(0)

#define DREAM_LEVELS (0x3 + 1 ) /* + 1 as an illustrative considering the 4th is really a limbo from 3rd */

struct dreamer_request
{
#define DREAMER_HIJACKED 0x1
#define DREAMER_DEFENSE_PROJECTIONS (0x2)
#define DREAMER_FREE_FALL (0x4)
#define DREAMER_FAKE_SHAPE (0x8)
#define DREAMER_SHOT (0x10)
#define DREAMER_KILLED (0x20)
#define DREAMER_NEXT_LEVEL (0x40)
#define DREAMER_IN_LIMBO (0x80)
#define DREAMER_IN_MY_DREAM (0x100) /*shared dream*/
#define DREAMER_KICK_BACK (0x200)
#define DREAMER_FIGHT (0x400)
#define DREAMER_SELF (0x800)
#define DREAMER_FALL (0x1000)
#define DREAMER_SYNCHRONIZE_KICK (0x2000)
#define DREAMER_RECOVER (0x4000)

struct dreamer_attr *dattr; /*dreamer attribute*/
int cmd; /* request cmd */
void *arg; /* request cmd arg*/
struct list list; /* list head marker*/
};

struct dreamer_attr
{
const char *name;
int role;
int shared_state; /* shared request command state*/
int level; /*dreamer level*/
struct list_head request_queue; /* per dreamer request queue*/
struct list list; /* list head marker*/
pthread_mutex_t mutex;
pthread_cond_t *cond[DREAM_LEVELS]; /* per dreamer wake up levels */
};

static pthread_mutex_t inception_reality_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t inception_reality_wakeup_for_all = PTHREAD_COND_INITIALIZER;
static struct list_head dreamer_queue[DREAM_LEVELS];
static pthread_mutex_t dreamer_mutex[DREAM_LEVELS];
static pthread_mutex_t limbo_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t limbo_cond = PTHREAD_COND_INITIALIZER;

#define _INCEPTION_C_
#include "inception.h"

static char *fischers_mind_state;
static struct dreamer_attr *fischer_level1;
static pid_t fischer_level1_taskid; /*fischers level1 taskid*/
static int dream_delay_map[DREAM_LEVELS] = { 1, 2, 4, 8};
static int dreamers_in_reality;

static void fischer_dream_level1(void) __attribute__((unused));
/*
* Queue the command to the dreamers request queue
*/
static void __dream_enqueue_cmd(struct dreamer_attr *dattr, int cmd, void *arg, int level, int locked)
{
struct dreamer_request *req = calloc(1, sizeof(*req));
assert(req != NULL);
assert(level > 0 && level <= DREAM_LEVELS);
req->dattr = dattr;
req->cmd = cmd;
req->arg = arg;
if(!locked)
pthread_mutex_lock(&dattr->mutex);
list_add_tail(&req->list, &dattr->request_queue);
pthread_cond_signal(dattr->cond[level-1]);
if(!locked)
pthread_mutex_unlock(&dattr->mutex);
}

static __inline__ void dream_enqueue_cmd(struct dreamer_attr *dattr, int cmd, void *arg, int level)
{
return __dream_enqueue_cmd(dattr, cmd, arg, level, 0);
}

static __inline__ void dream_enqueue_cmd_safe(struct dreamer_attr *dattr, int cmd,
void *arg, int level, pthread_mutex_t *dreamer_lock)
{
/*
* Drop the current level dreamer lock before reacquiring.
*/
pthread_mutex_unlock(dreamer_lock);
__dream_enqueue_cmd(dattr, cmd, arg, level, 0);
pthread_mutex_lock(dreamer_lock);
}

static __inline__ void dream_enqueue_cmd_locked(struct dreamer_attr *dattr, int cmd, void *arg, int level)
{
return __dream_enqueue_cmd(dattr, cmd, arg, level, 1);
}

/*
* Clone the request command to all the dreamers: Called with lock held.
*/
static void dream_clone_cmd(struct list_head *dreamer_queue, int cmd, void *arg, struct dreamer_attr *dattr, int level)
{
register struct list *iter;
for(iter = dreamer_queue->head; iter; iter = iter->next)
{
struct dreamer_attr *dreamer = LIST_ENTRY(iter, struct dreamer_attr, list);
if(dattr && dreamer == dattr)
continue; /*skip cloning it on this dreamer*/
dream_enqueue_cmd(dreamer, cmd, arg, level);
}
}

static struct dreamer_request *dream_dequeue_cmd_locked(struct dreamer_attr *dattr)
{
struct dreamer_request *req = NULL;
struct list *head = NULL;
if(!dattr->request_queue.nodes)
return NULL;
head = dattr->request_queue.head;
assert(head != NULL);
req = LIST_ENTRY(head, struct dreamer_request, list);
list_del(head, &dattr->request_queue);
return req;
}

static __inline__ struct dreamer_request *dream_dequeue_cmd(struct dreamer_attr *dattr)
{
struct dreamer_request *req;
pthread_mutex_lock(&dattr->mutex);
req = dream_dequeue_cmd_locked(dattr);
pthread_mutex_unlock(&dattr->mutex);
return req;
}

static struct dreamer_attr *dreamer_find(struct list_head *dreamer_queue, const char *name, int role)
{
register struct list *iter;
for(iter = dreamer_queue->head; iter ; iter = iter->next)
{
struct dreamer_attr *dattr = LIST_ENTRY(iter, struct dreamer_attr, list);
if(role && (dattr->role & role))
return dattr;
if(name &&
!strcasecmp(dattr->name, name))
return dattr;
}
return NULL;
}

static struct dreamer_attr *dreamer_find_sync_locked(struct dreamer_attr *dreamer, int level, const char *name, int role)
{
struct dreamer_attr *dattr = NULL;
if(!level) return NULL;
rescan:
dattr = dreamer_find(&dreamer_queue[level-1], name, role);
if(!dattr)
{
static int c;
pthread_mutex_unlock(&dreamer_mutex[level-1]);
if(++c >= 10)
{
output("[%s] waiting for [%s] to join at level [%d]\n", dreamer->name,
name ?:"Unknown", level);
}
usleep(100000);
pthread_mutex_lock(&dreamer_mutex[level-1]);
goto rescan;
}
return dattr;
}

static struct dreamer_attr *dreamer_find_sync(struct dreamer_attr *dreamer, int level, const char *name, int role)
{
struct dreamer_attr *dattr;
if(!level) return NULL;
pthread_mutex_lock(&dreamer_mutex[level-1]);
dattr = dreamer_find_sync_locked(dreamer, level, name, role);
pthread_mutex_unlock(&dreamer_mutex[level-1]);
return dattr;
}

/*
* In a dream, you run 12 times slower : 5 mins of realtime = 60 mins
* Fake the slowness by reduction in threads priority or the
* scheduling priority of the dreamer
*/

static void set_thread_priority(struct dreamer_attr *dattr, int level)
{
struct sched_param dream_param = {0};
int policy = 0;

assert(pthread_getschedparam(pthread_self(), &policy, &dream_param) == 0);
if(dream_param.sched_priority > 12)
dream_param.sched_priority -= 12;

output("Dreamer [%s], level [%d], priority [%d], policy [%s]\n",
dattr->name, level, dream_param.sched_priority,
policy == SCHED_FIFO ? "FIFO" :
(policy == SCHED_RR ? "RR" : "OTHER"));

assert(pthread_setschedparam(pthread_self(), policy, &dream_param) == 0);
}

/*
* Wake up an individual dreamer in one level and let him propagate the kick down to levels below.
*/
static void wake_up_dreamer(struct dreamer_attr *dattr, int level)
{
register struct list *iter;
if(!level || (dattr->shared_state & DREAMER_IN_LIMBO)) return;
pthread_mutex_lock(&dreamer_mutex[level-1]);
for(iter = dreamer_queue[level-1].head; iter; iter = iter->next)
{
struct dreamer_attr *dreamer = LIST_ENTRY(iter, struct dreamer_attr, list);
if( !(dreamer->role ^ dattr->role) )
{
dream_enqueue_cmd(dreamer, DREAMER_KICK_BACK, NULL, dreamer->level);
break;
}
}
pthread_mutex_unlock(&dreamer_mutex[level-1]);
}

/*
* Level 0 is wake up dreamers on all levels.
* Skip guys in a limbo from that level to all the way down.
*/
static void wake_up_dreamers(int level)
{
int start = DREAM_LEVELS-1,end = 0;
register int i;
if(level > 0)
{
start = level - 1;
end = level - 1;
}
for(i = start; i >= end; --i)
{
struct list *iter;
pthread_mutex_lock(&dreamer_mutex[i]);
for(iter = dreamer_queue[i].head; iter; iter = iter->next)
{
struct dreamer_attr *dattr = LIST_ENTRY(iter, struct dreamer_attr, list);
if( (dattr->shared_state & DREAMER_IN_LIMBO) )
continue;
dream_enqueue_cmd(dattr, DREAMER_KICK_BACK, NULL, dattr->level);
}
pthread_mutex_unlock(&dreamer_mutex[i]);
}
}

/*
* Update states on all the levels and down.
*/
static void set_state(struct dreamer_attr *dattr, int state)
{
register int i;
for(i = DREAM_LEVELS - 1; i >= 0; --i)
{
register struct list *iter;
pthread_mutex_lock(&dreamer_mutex[i]);
for(iter = dreamer_queue[i].head; iter; iter = iter->next)
{
struct dreamer_attr *dreamer = LIST_ENTRY(iter, struct dreamer_attr, list);
if(!(dreamer->role ^ dattr->role))
{
dreamer->shared_state |= state;
break;
}
}
pthread_mutex_unlock(&dreamer_mutex[i]);
}
}

/*
* Set the limbo state on all levels of this dreamer so he cannot get a kick back
* Called with the lock on that level.
*/
static void set_limbo_state(struct dreamer_attr *dattr)
{
set_state(dattr, DREAMER_IN_LIMBO);
}

/*
* Called with the dreamer attr mutex held for the appropriate level.
*/
static void wait_for_kick(struct dreamer_attr *dattr)
{
struct dreamer_request *req = NULL;
for(;;)
{
struct timespec ts = {0};
while ( (req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
if(dattr->level > 1)
{
output("[%s] got Kick at level [%d]. Exiting back to level [%d]\n",
dattr->name, dattr->level, dattr->level - 1);
}
else
{
output("[%s] got Kick at level [%d]. Exiting back to reality\n",
dattr->name, dattr->level);
}
goto out;
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[dattr->level-1], &dattr->mutex, &ts);
}
out:
return;
}

static struct dreamer_attr *dream_attr_clone(int level, struct dreamer_attr *dattr)
{
struct dreamer_attr *dattr_clone = calloc(1, sizeof(*dattr_clone));
assert(dattr_clone != NULL);
memcpy(dattr_clone, dattr, sizeof(*dattr_clone));
dattr_clone->level = level;
memset(&dattr_clone->mutex, 0, sizeof(dattr_clone->mutex));
assert(pthread_mutex_init(&dattr_clone->mutex, NULL) == 0);
list_init(&dattr_clone->request_queue);
return dattr_clone;
}

static __inline__ void dream_level_create(int level, void * (*dream_function) (void *), struct dreamer_attr *dattr)
{
pthread_attr_t attr;
pthread_t dream;
struct dreamer_attr *dattr_clone = dream_attr_clone(level, dattr);
assert(dattr_clone != NULL);
assert(pthread_attr_init(&attr)==0);
assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED)==0);
assert(pthread_create(&dream, &attr, dream_function, dattr_clone) == 0);
}

/*
* Now this is the state where Cobb. meets Saito.
* The beauty of the Films ending is: Did Cobb take a kick back to reality on seeing Saito remind him
* that he has been in a limbo with his wife and has to come back to become Young.
* And does Saito take the kick back when Cobb. pulls the trigger on him implicitly in limbo to give him the kick back.
* Either way based on whether Cobb. got the kick back from limbo or not, the end is a reality or limbo.
* Thats the ingenuity of Inception. So I think its better if we don't mess this up for ourselves and
* just sleep here till infinity!
*/

static void infinite_subconsciousness(struct dreamer_attr *dattr)
{
struct timespec ts = {0};
static int dreamers;

pthread_mutex_lock(&limbo_mutex);
++dreamers;
while(dreamers != 2)
{
arch_gettime(2, &ts);
pthread_cond_timedwait(&limbo_cond, &limbo_mutex, &ts);
}
/*
* Wait for the signal from Fischer
*/
while(!dreamers_in_reality)
{
arch_gettime(1, &ts);
pthread_cond_timedwait(&limbo_cond, &limbo_mutex, &ts);
}

if((dattr->role & DREAM_INCEPTION_PERFORMER))
{
output("\n\nCobbs' search for Saito ends in Limbo. Now either both take the kick back to reality "
"or the ending is still a state of limbo from Cobbs' perspective, which is what Nolan wants us to think\n");
output("This is in spite of witnessing his children turn towards him for the first time which we're never shown in his projections.\n");
output("So, let me end the limbo state abruptly like the Movie with the totem spinning and leave it to the reviewers to decide the infinite sleep:-)\n\n");
}
pthread_cond_signal(&limbo_cond);
pthread_mutex_unlock(&limbo_mutex);
sleep(1<<31);
}

/*
* Limbo is a state of infinite subconciousness
*/
static void enter_limbo(struct dreamer_attr *dattr)
{
struct dreamer_attr *clone = NULL;
struct dreamer_request *req = NULL;

pthread_mutex_lock(&dattr->mutex);
dattr->shared_state |= DREAMER_IN_LIMBO;
clone = dream_attr_clone(dattr->level+1, dattr);
pthread_mutex_unlock(&dattr->mutex);

assert(clone != NULL);
pthread_mutex_lock(&dreamer_mutex[3]);
list_add_tail(&clone->list, &dreamer_queue[3]);
while( (dreamer_queue[3].nodes + 3) != DREAMERS)
{
pthread_mutex_unlock(&dreamer_mutex[3]);
usleep(100000);
pthread_mutex_lock(&dreamer_mutex[3]);
}
pthread_mutex_unlock(&dreamer_mutex[3]);

switch( (clone->role & DREAM_ROLE_MASK) )
{
case DREAM_INCEPTION_PERFORMER: /* Cobb */
{
struct timespec ts;
struct dreamer_attr *ariadne = NULL;
int inception_done = 0;
int search_for_saito = 0;
ariadne = dreamer_find(&dreamer_queue[3], "ariadne", DREAM_WORLD_ARCHITECT);
/*
* Self enqueue Mal and her thoughts into the dream
*/
dream_enqueue_cmd(clone, DREAMER_IN_MY_DREAM, (void*)"Cobb takes Elevator to meet Mal", clone->level);
dream_enqueue_cmd(clone, DREAMER_IN_MY_DREAM,
(void*)"[Cobb] tells [Mal] about his inception on her to think that the WORLD is unreal",
clone->level);
dream_enqueue_cmd(clone, DREAMER_IN_MY_DREAM,
(void*)"[Mal] wants [Cobb] to go back with him into the world they built in their dreams",
clone->level);
pthread_mutex_lock(&clone->mutex);
for(;;)
{
while( (req = dream_dequeue_cmd_locked(clone)) )
{
/*
* Meets Mal
*/
if(req->cmd == DREAMER_IN_MY_DREAM)
{
output("%s in level [%d] while in limbo\n", (const char*)req->arg, clone->level);
}
/*
* Mal killed
*/
else if(req->cmd == DREAMER_KILLED)
{
output("[%s] finds %s in level [%d] while in limbo\n",
clone->name, (const char*)req->arg, clone->level);
}
/*
* Recover to search for Saito. Here mark the inception
*/
else if(req->cmd == DREAMER_RECOVER)
{
struct dreamer_attr *source = (struct dreamer_attr*)req->arg;
/*
* If the recovery trigger is from ariadne
*/
if( (source->role & DREAM_WORLD_ARCHITECT) )
{
if(!inception_done)
{
search_for_saito = 1;
}
else
{
pthread_mutex_unlock(&clone->mutex);
search_saito:
output("[%s] enters limbo to search for Saito in limbo at level [%d]\n",
clone->name, clone->level);
set_limbo_state(clone);
usleep(10000);
infinite_subconsciousness(clone);
pthread_mutex_lock(&clone->mutex);
output("[%s] returned after searching for Saito in limbo at level [%d]\n",
clone->name, clone->level);
assert(0); /* should not return back here*/
}
}
/*
* Indicator from Fischer for the final shot.
*/
else if( (source->role & DREAM_INCEPTION_TARGET) )
{
pthread_mutex_unlock(&clone->mutex);
inception_done = 1;
memcpy(fischers_mind_state, inception_thoughts, sizeof(inception_thoughts));
/*
* Send recovery indicator to Ariadne
*/
dream_enqueue_cmd(ariadne, DREAMER_RECOVER, clone, ariadne->level);
if(search_for_saito)
{
goto search_saito;
}
pthread_mutex_lock(&clone->mutex);
}
}
}
arch_gettime(dream_delay_map[clone->level-1], &ts);
pthread_cond_timedwait(clone->cond[3], &clone->mutex, &ts);
}
}
break;

case DREAM_WORLD_ARCHITECT: /* Ariadne */
{
struct dreamer_attr *cobb = NULL;
struct dreamer_attr *fischer = NULL;
struct timespec ts = {0};
cobb = dreamer_find(&dreamer_queue[3], "cobb", DREAM_INCEPTION_PERFORMER);
fischer = dreamer_find(&dreamer_queue[3], "fischer", DREAM_INCEPTION_TARGET);
/*
* Self enqueue to follow Cobb. in the Elevator to his wife.
*/
dream_enqueue_cmd(clone, DREAMER_IN_MY_DREAM, cobb, clone->level);
pthread_mutex_lock(&clone->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(clone) ) )
{
if(req->cmd == DREAMER_IN_MY_DREAM)
{
output("[%s] follows [%s] in Elevator to level [%d] in Limbo to meet his wife\n",
clone->name, cobb->name, clone->level);
pthread_mutex_unlock(&clone->mutex);
/*
* Take a breather while Cobb. interacts with his and tells her about his inception.
*/
sleep(dream_delay_map[clone->level-1]);
dream_enqueue_cmd(cobb, DREAMER_KILLED, (void*)"[Mal] killed", cobb->level);
/*
* Quick breather
*/
usleep(10000);
/*
* Now send Fischer a kick back from limbo down to reconcile.
*/
dream_enqueue_cmd(fischer, DREAMER_KICK_BACK, clone, fischer->level);
/*
* Now tell Cobb. to recover and go and search Saito as he is the only one who can
* search her in limbo.
*/
output("[%s] tells [%s] to search for Saito in limbo at level [%d]\n",
clone->name, cobb->name, clone->level);
dream_enqueue_cmd(cobb, DREAMER_RECOVER, clone, cobb->level);
pthread_mutex_lock(&clone->mutex);
}
else if(req->cmd == DREAMER_RECOVER)
{
/*
* Indication for us to take the kick back.
*/
dream_enqueue_cmd_safe(clone, DREAMER_KICK_BACK, clone, clone->level, &clone->mutex);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
struct dreamer_attr *self = NULL; /*ourself in lower level*/
/*
* Return back
*/
dattr->shared_state &= ~DREAMER_IN_LIMBO;
clone->shared_state &= ~DREAMER_IN_LIMBO;
pthread_mutex_unlock(&clone->mutex);
free(req);
usleep(10000);
self = dreamer_find_sync(clone, clone->level-1, "ariadne", DREAM_WORLD_ARCHITECT);
dream_enqueue_cmd(self, DREAMER_KICK_BACK, clone, self->level);
output("[%s] taking the kick back from limbo at level [%d] to level [%d]\n",
clone->name, clone->level, clone->level-1);
goto out;
}
free(req);
}
arch_gettime(dream_delay_map[clone->level-1], &ts);
pthread_cond_timedwait(clone->cond[3], &clone->mutex, &ts);
}
}
break;

case DREAM_OVERLOOKER: /* Saito */
{
set_limbo_state(clone);
usleep(1000);
infinite_subconsciousness(clone);
}
break;

case DREAM_INCEPTION_TARGET: /*Fischer*/
{
struct dreamer_attr *self = NULL;
struct timespec ts = {0};
/*
* Find ourselves in the lower level to take the kick back.
*/
self = dreamer_find_sync(clone, clone->level-1, "fischer", DREAM_INCEPTION_TARGET);
pthread_mutex_lock(&clone->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(clone)) )
{
if(req->cmd == DREAMER_KICK_BACK)
{
dattr->shared_state &= ~DREAMER_IN_LIMBO;
clone->shared_state &= ~DREAMER_IN_LIMBO;
pthread_mutex_unlock(&clone->mutex);
free(req);
dream_enqueue_cmd(self, DREAMER_KICK_BACK, clone, self->level);
output("[%s] kicking off from limbo at [%d] to level [%d]\n",
clone->name, clone->level, clone->level-1);
goto out;
}
free(req);
}
arch_gettime(dream_delay_map[clone->level-1], &ts);
pthread_cond_timedwait(clone->cond[3], &clone->mutex, &ts);
}
}
break;
}

out:
return ;
}


/*
* The last level of the dream beyond which we enter limbo.
*/
static void *dream_level_3(void *arg)
{
struct dreamer_attr *dattr = arg;
struct dreamer_request *req = NULL;
assert(dattr->level == 3);
set_thread_priority(dattr, 3);
pthread_mutex_lock(&dreamer_mutex[2]);
list_add_tail(&dattr->list, &dreamer_queue[2]);
while( (dreamer_queue[2].nodes + 2 != DREAMERS ) )
{
pthread_mutex_unlock(&dreamer_mutex[2]);
usleep(10000);
pthread_mutex_lock(&dreamer_mutex[2]);
}
pthread_mutex_unlock(&dreamer_mutex[2]);
/*
* All have joined in level 3
*/
switch( (dattr->role & DREAM_ROLE_MASK) )
{
case DREAM_INCEPTION_PERFORMER: /* Cobb */
{
struct dreamer_attr *fischer = NULL;
struct dreamer_attr *ariadne = NULL;
struct dreamer_attr *eames = NULL;
struct timespec ts = {0};
/*
* Self enqueue
*/
fischer = dreamer_find(&dreamer_queue[2], "fischer", DREAM_INCEPTION_TARGET);
ariadne = dreamer_find(&dreamer_queue[2], "ariadne", DREAM_WORLD_ARCHITECT);
eames = dreamer_find(&dreamer_queue[2], "eames", DREAM_SHAPES_FAKER);
dream_enqueue_cmd(dattr, DREAMER_FIGHT, (void*)"Fischer", dattr->level);
dream_enqueue_cmd(dattr, DREAMER_IN_MY_DREAM, (void*)"Mal", dattr->level);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(dattr)))
{
if(req->cmd == DREAMER_FIGHT)
{
output("[%s] fights [%s] defense projections in level [%d]\n",
dattr->name, (char*)req->arg, dattr->level);
}
else if(req->cmd == DREAMER_IN_MY_DREAM)
{
pthread_mutex_unlock(&dattr->mutex);
output("[%s] sees his wife [%s] in his dream. [%s] shoots Fischer\n",
dattr->name, (char*)req->arg, (char*)req->arg);
dream_enqueue_cmd(fischer, DREAMER_SHOT, (void*)"Mal", fischer->level);
/*
* Let Eames know so he could start recovery on Fischer
*/
dream_enqueue_cmd(eames, DREAMER_SHOT, fischer, dattr->level);
/*
* Hint to Ariadne about Fischers death from Mal's hands
* Take the dreamer mutex for a synchronized reply wait.
*/
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_mutex_lock(&dreamer_mutex[dattr->level-1]);
dream_enqueue_cmd(ariadne, DREAMER_SHOT, (void*)"Fischer shot by Mal", dattr->level);
pthread_cond_timedwait(dattr->cond[dattr->level-1],
&dreamer_mutex[dattr->level-1], &ts);
pthread_mutex_unlock(&dreamer_mutex[dattr->level-1]);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_NEXT_LEVEL)
{
pthread_mutex_unlock(&dattr->mutex);
output("[%s] follows [%s] and enters limbo with his Wifes projections in level [%d]\n",
dattr->name, ((struct dreamer_attr*)req->arg)->name, dattr->level);
enter_limbo(dattr);
pthread_mutex_lock(&dattr->mutex);
/*
* should not be reached
*/
output("[%s] returned from limbo. Exiting out at level [%d]\n", dattr->name,
dattr->level);
exit(0);
}
free(req);
}
pthread_mutex_unlock(&dattr->mutex);
sleep(2);
pthread_mutex_lock(&dattr->mutex);
}
}
break;

case DREAM_WORLD_ARCHITECT: /* Ariadne*/
{
/*
* Wait for Cobbs command to enter his dream in limbo with him.
*/
struct timespec ts = {0};
struct dreamer_attr *cobb = NULL;
int ret_from_limbo = 0;
cobb = dreamer_find(&dreamer_queue[2], "cobb", DREAM_INCEPTION_PERFORMER);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_SHOT)
{
pthread_mutex_unlock(&dattr->mutex);
output("[%s] sees %s in level [%d]\n", dattr->name,
(char*)req->arg, dattr->level);
output("[%s] tells [%s] to follow Fischer to level [%d] in Mal's world in limbo\n",
dattr->name, cobb->name, dattr->level+1);
pthread_mutex_lock(&dreamer_mutex[dattr->level-1]);
dream_enqueue_cmd(cobb, DREAMER_NEXT_LEVEL, dattr, cobb->level);
pthread_mutex_unlock(&dreamer_mutex[dattr->level-1]);
output("[%s] enters Limbo at level [%d]\n",
dattr->name, dattr->level+1);
enter_limbo(dattr);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
if(!ret_from_limbo)
{
struct dreamer_attr *yusuf = NULL;
ret_from_limbo = 1;
output("[%s] returned from Fischers limbo to level [%d] to take the synchronized kick\n",
dattr->name, dattr->level);
pthread_mutex_unlock(&dattr->mutex);
yusuf = dreamer_find_sync(dattr, 1, "yusuf", DREAM_SEDATIVE_CREATOR);
dream_enqueue_cmd(yusuf, DREAMER_SYNCHRONIZE_KICK, dattr, yusuf->level);
/*
* Take a breather while Yusuf does his work so we can rescan for a kick back
* Otherwise we miss and get it after our delayed sleep
*/
usleep(10000);
pthread_mutex_lock(&dattr->mutex);
}
else
{
free(req);
output("[%s] got Kick back from level [%d]. Exiting back to level [%d]\n",
dattr->name, dattr->level, dattr->level-1);
goto out_unlock;
}
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[2], &dattr->mutex, &ts);
}
}
break;

case DREAM_SHAPES_FAKER: /* Eames*/
{
struct timespec ts = {0};
struct dreamer_attr *fischer = NULL;
struct dreamer_attr *saito = NULL;
saito = dreamer_find(&dreamer_queue[2], "saito", DREAM_OVERLOOKER);
/*
* Self enqueue and he is the dreamer at this level
*/
dream_enqueue_cmd(dattr, DREAMER_FIGHT, dattr, dattr->level);
/*
* Ask Saito to fight first before he is killed!
*/
dream_enqueue_cmd(saito, DREAMER_FIGHT, dattr, dattr->level);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(dattr)))
{
if(req->cmd == DREAMER_FIGHT)
{
output("[%s] fights Fischers defense projections at level [%d]\n",
dattr->name, dattr->level);
}
else if(req->cmd == DREAMER_SHOT)
{
pthread_mutex_unlock(&dattr->mutex);
fischer = ( (struct dreamer_attr*)req->arg);
output("[%s] sees [%s] shot in level [%d]. Starts recovery\n",
dattr->name, fischer->name, dattr->level);
output("[%s] tells [%s] to keep fighting Fischers projections in level [%d]\n",
dattr->name, saito->name, dattr->level);
dream_enqueue_cmd(saito, DREAMER_FIGHT, dattr, saito->level);

dream_enqueue_cmd(dattr, DREAMER_RECOVER, fischer, dattr->level);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_RECOVER)
{
output("[%s] doing recovery on [%s] who is shot at level [%d]\n",
dattr->name, ( (struct dreamer_attr*)req->arg)->name, dattr->level);
pthread_mutex_unlock(&dattr->mutex);
/*
* Dream about Saito getting killed ultimately as I am the dreamer in this level.
*/
dream_enqueue_cmd(saito, DREAMER_KILLED, dattr, saito->level);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
struct dreamer_attr *src = (struct dreamer_attr*)req->arg;
if(src && (src->role & DREAM_INCEPTION_TARGET))
{
pthread_mutex_unlock(&dattr->mutex);
output("[%s] sees [%s] get a recovery kick at level [%d]. "
"Starts faking Fischers Father's projections for the final Inception\n",
dattr->name, src->name, src->level);
dream_enqueue_cmd(src, DREAMER_FAKE_SHAPE, "Maurice Fischer", src->level);
pthread_mutex_lock(&dattr->mutex);
}
else
{
free(req);
output("[%s] got Kick at level [%d]. Exiting back to level [%d]\n",
dattr->name, dattr->level, dattr->level - 1);
goto out_unlock;
}
}
free(req);
}
if(fischer)
{
/*
* Keep recovering fischer if he is shot in this level.
*/
dream_enqueue_cmd_safe(dattr, DREAMER_RECOVER, fischer, dattr->level, &dattr->mutex);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[2], &dattr->mutex, &ts);
}
}
break;

case DREAM_OVERLOOKER: /*Saito*/
{
struct timespec ts = {0};
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while( (req = dream_dequeue_cmd_locked(dattr)))
{
if(req->cmd == DREAMER_FIGHT)
{
output("[%s] fights Fischers projections in level [%d]\n",
dattr->name, dattr->level);
}
else if(req->cmd == DREAMER_KILLED) /* Killed. Enter limbo */
{
output("[%s] gets killed at level [%d]. Enters limbo\n", dattr->name, dattr->level);
pthread_mutex_unlock(&dattr->mutex);
/*
* Update killed status on all the levels. just for the sake of being
* consistent
*/
set_state(dattr, DREAMER_KILLED);
enter_limbo(dattr);
pthread_mutex_lock(&dattr->mutex);
/*
* Unreached.
*/
output("[%s] returned back from Limbo at level [%d]\n", dattr->name, dattr->level);
exit(0);
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[2], &dattr->mutex, &ts);
}
}
break;

case DREAM_INCEPTION_TARGET: /* Fischer */
{
int reconciled = 0;
struct timespec ts = {0};
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(dattr)))
{
if(req->cmd == DREAMER_SHOT)
{
output("[%s] shot by [%s] in level [%d]\n",
dattr->name, (char*)req->arg, dattr->level);
/*
* Freeze for sometime before joining Cobb and Ariadne in limbo.
*/
pthread_mutex_unlock(&dattr->mutex);
usleep(100000);
enter_limbo(dattr);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
if(!reconciled)
{
struct dreamer_attr *eames = NULL;
pthread_mutex_unlock(&dattr->mutex);
output("[%s] got a kick back from Limbo at level [%d]\n", dattr->name, dattr->level);
eames = dreamer_find(&dreamer_queue[2], "eames", DREAM_SHAPES_FAKER);
dream_enqueue_cmd(eames, DREAMER_KICK_BACK, dattr, eames->level);
pthread_mutex_lock(&dattr->mutex);
}
else
{
free(req);
output("[%s] got a kick at level [%d]. Falling back to level [%d]\n",
dattr->name, dattr->level, dattr->level - 1);
goto out_unlock;
}
}
/*
* Fischer meeting with his dying father (reconciliation phase at the lowest level)
*/
else if(req->cmd == DREAMER_FAKE_SHAPE)
{
struct dreamer_attr *cobb = NULL;
reconciled = 1;
pthread_mutex_unlock(&dattr->mutex);
usleep(10000); /*take a breather*/
output("[%s] going to meet his dying father [%s] after getting a kick back to level [%d]\n",
dattr->name, (const char*)req->arg, dattr->level);
/*
* Indicator to Cobb. for you know WHAT :-)
*/
pthread_mutex_lock(&dreamer_mutex[dattr->level]);
cobb = dreamer_find_sync_locked(dattr, dattr->level+1, "cobb", DREAM_INCEPTION_PERFORMER);
dream_enqueue_cmd(cobb, DREAMER_RECOVER, dattr, cobb->level);
pthread_mutex_unlock(&dreamer_mutex[dattr->level]);
pthread_mutex_lock(&dattr->mutex);
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[2], &dattr->mutex, &ts);
}
}
break;
default:
break;
}
out_unlock:
pthread_mutex_unlock(&dattr->mutex);
wake_up_dreamer(dattr, 2);
return NULL;
}

static void *dream_level_2(void *arg)
{
struct dreamer_attr *dattr = arg;
int dreamers = 0;
assert(dattr->level == 2);
set_thread_priority(dattr, 2);
/*
* take level 2 lock.
*/
pthread_mutex_lock(&dreamer_mutex[1]);
list_add_tail(&dattr->list, &dreamer_queue[1]);
/*
* Wait for the expected members to join at this level.
*/
while( (dreamers = dreamer_queue[1].nodes)+1 != DREAMERS)
{
pthread_mutex_unlock(&dreamer_mutex[1]);
usleep(10000);
pthread_mutex_lock(&dreamer_mutex[1]);
}

pthread_mutex_unlock(&dreamer_mutex[1]);
switch((dattr->role & DREAM_ROLE_MASK))
{
case DREAM_INCEPTION_PERFORMER: /* Cobb in level 2 */
{
/*
* Wait for Ariadne and Fischer to join me. at this level after meeting with Arthur
*/
struct dreamer_request *req;
struct dreamer_attr *eames;
struct timespec ts = {0};
int wait_for_dreamers = DREAM_WORLD_ARCHITECT | DREAM_INCEPTION_TARGET;
eames = dreamer_find(&dreamer_queue[1], "eames", DREAM_SHAPES_FAKER);
pthread_mutex_lock(&dattr->mutex);
while(wait_for_dreamers > 0)
{
while( (!(req = dream_dequeue_cmd_locked(dattr)) )
||
req->cmd != DREAMER_IN_MY_DREAM
||
!req->arg
||
!( ((struct dreamer_attr*)req->arg)->role & wait_for_dreamers)
)
{
if(req) free(req);
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[dattr->level-1], &dattr->mutex, &ts);
}
wait_for_dreamers &= ~((struct dreamer_attr*)req->arg)->role;
output("[%s] taking [%s] to level 3\n", dattr->name, ((struct dreamer_attr*)req->arg)->name);
dream_enqueue_cmd((struct dreamer_attr*)req->arg, DREAMER_NEXT_LEVEL, dattr, dattr->level);
free(req);
}
/*
* Ariadne + Fischer has joined. Go to level 3. myself. Take Eames into level 3
*/
pthread_mutex_unlock(&dattr->mutex);
dream_level_create(dattr->level + 1, dream_level_3, dattr);
dream_enqueue_cmd(eames, DREAMER_NEXT_LEVEL, dattr, eames->level);
pthread_mutex_lock(&dattr->mutex);
/*
* Just do nothing and wait for kick back to previous level.
*/
wait_for_kick(dattr);
}
break;

case DREAM_WORLD_ARCHITECT : /*Ariadne*/
{
struct dreamer_request *req;
struct dreamer_attr *arthur;
struct dreamer_attr *cobb;
arthur = dreamer_find_sync(dattr, dattr->level, "arthur", DREAM_ORGANIZER);
cobb = dreamer_find_sync(dattr,dattr->level,"cobb",DREAM_INCEPTION_PERFORMER);
assert(arthur != NULL);
assert(cobb != NULL);
/*
* Add ourselves/Ariadne in Arthurs dream. and wait for Arthur to signal
*/
output("[%s] joining [%s] in his dream at level 2 to fight Fischers defense projections\n",
dattr->name, arthur->name);
pthread_mutex_lock(&dreamer_mutex[1]);
dream_enqueue_cmd(arthur, DREAMER_IN_MY_DREAM, dattr, arthur->level);
pthread_cond_wait(dattr->cond[1], &dreamer_mutex[1]);
pthread_mutex_unlock(&dreamer_mutex[1]);
/*
* Now join Cobb. before taking Fischer to level 3.
*/
output("[%s] joining [%s] in his dream at level 2 to help Fischer\n",
dattr->name, cobb->name);
dream_enqueue_cmd(cobb, DREAMER_IN_MY_DREAM, dattr, dattr->level);
/*
* Wait for the request to enter the next level or a kick back.
*/
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
struct timespec ts = {0};
while( (req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
output("[%s] got KICK while at level [%d]. Exiting back to level [%d]\n",
dattr->name, dattr->level, dattr->level - 1);
goto out_unlock;
}
if(req->cmd == DREAMER_NEXT_LEVEL)
{
pthread_mutex_unlock(&dattr->mutex);
output("[%s] following [%s] to level [%d]\n",
dattr->name, ( (struct dreamer_attr*)req->arg)->name, dattr->level + 1);
dream_level_create(dattr->level + 1, dream_level_3, dattr);
pthread_mutex_lock(&dattr->mutex);
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[1], &dattr->mutex, &ts);
}
}
break;
case DREAM_ORGANIZER: /*Arthur*/
{
struct dreamer_attr *ariadne = NULL;
struct dreamer_request *req = NULL;
struct dreamer_attr *self = NULL;
struct timespec ts = {0};
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while ( (req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_IN_MY_DREAM) /* check if Ariadne joined */
{
ariadne = (struct dreamer_attr*)req->arg;
assert(ariadne->role == DREAM_WORLD_ARCHITECT);
output("[%s] joined [%s] in level [%d]\n",
ariadne->name, dattr->name, dattr->level);
}
else assert(req->cmd != DREAMER_KICK_BACK); /* cannot receive kick back yet*/
free(req);
}
if(!ariadne) /* If ariadne hadn't arrived, wait for her to join*/
{
output("[%s] waiting for Ariadne to join in level [%d]\n",
dattr->name, dattr->level);
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[1], &dattr->mutex, &ts);
}
else break;
}
/*
* update the state to fight defense projections of Fischer
*/
dattr->shared_state = DREAMER_FIGHT;
pthread_mutex_unlock(&dattr->mutex);
pthread_mutex_lock(&dreamer_mutex[1]);
/*
* Signal Ariadne to join Cobb. to get into level 3 while I wait fighting projections
*/
dream_enqueue_cmd(ariadne, DREAMER_IN_MY_DREAM, (void*)dattr, dattr->level);
pthread_mutex_unlock(&dreamer_mutex[1]);
/*
* Signal self dreamer in the next level below.
*/
self = dreamer_find(&dreamer_queue[dattr->level-2], NULL, DREAM_ORGANIZER);
assert(self != NULL);
dream_enqueue_cmd(self, DREAMER_SELF, dattr, self->level);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while ( ( req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_FREE_FALL)
{
struct dreamer_attr *dreamer_falling = (struct dreamer_attr*)req->arg;
output("[%s] experiencing Free fall in level [%d] coz of a fall triggered "
" of [%s] in level [%d]\n",
dattr->name, dattr->level, dreamer_falling->name, dreamer_falling->level);
}
else if(req->cmd == DREAMER_FIGHT) /* instruction to fight */
{
output("[%s] Fighting Fischers projections in level [%d]\n",
dattr->name, dattr->level);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
output("[%s] got Kick at level [%d]. Exiting to level [%d]\n",
dattr->name, dattr->level, dattr->level - 1);
goto out_unlock;
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[1], &dattr->mutex, &ts);
}
}
break;

case DREAM_INCEPTION_TARGET: /* Fischer */
{
struct dreamer_attr *cobb = NULL;
struct dreamer_request *req = NULL;
/*
* First hunt for Cobb in this level.
*/
cobb = dreamer_find(&dreamer_queue[1], "cobb", DREAM_INCEPTION_PERFORMER);
dream_enqueue_cmd(cobb, DREAMER_IN_MY_DREAM, dattr, dattr->level);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
struct timespec ts = {0};
while ( (req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_NEXT_LEVEL)
{
output("[%s] following [%s] to level [%d]\n",
dattr->name, ( (struct dreamer_attr*)req->arg)->name, dattr->level + 1);
pthread_mutex_unlock(&dattr->mutex);
dream_level_create(dattr->level + 1, dream_level_3, dattr);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_FAKE_SHAPE)
{
output("[%s] met with Browning again in level [%d]. "
"Waits for Cobb before getting into level [%d] to meet his father\n",
dattr->name, dattr->level, dattr->level + 1);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
output("[%s] got Kick at level [%d]. Exiting back to level [%d]\n",
dattr->name, dattr->level, dattr->level-1);
goto out_unlock;
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[1], &dattr->mutex, &ts);
}
}
break;

case DREAM_SHAPES_FAKER: /*Eames*/
{
struct dreamer_attr *fischer = NULL;
struct dreamer_attr *saito = NULL;
/*
* Find fischer and fake Browning to manipulate him for the final inception.
* by creating a doubt in his mind.
*/
fischer = dreamer_find(&dreamer_queue[1], "fischer", DREAM_INCEPTION_TARGET);
saito = dreamer_find(&dreamer_queue[1], "saito", DREAM_OVERLOOKER);
output("[%s] Faking Browning's projection to Fischer at level [%d]\n",
dattr->name, dattr->level);
dream_enqueue_cmd(fischer, DREAMER_FAKE_SHAPE, dattr, dattr->level);

/* fall through*/
case DREAM_OVERLOOKER: /*Saito*/
{
struct dreamer_request *req = NULL;
struct timespec ts = {0};
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
while( (req = dream_dequeue_cmd_locked(dattr) ) )
{
if(req->cmd == DREAMER_NEXT_LEVEL)
{
struct dreamer_attr *src = (struct dreamer_attr*)req->arg;
output("[%s] following [%s] to level [%d]\n",
dattr->name, src->name, dattr->level+1);
pthread_mutex_unlock(&dattr->mutex);
if( ( src->role & DREAM_INCEPTION_PERFORMER) )
{
/*
* Eames takes Saito to the next level.
*/
dream_enqueue_cmd(saito, DREAMER_NEXT_LEVEL, dattr, saito->level);
}
dream_level_create(dattr->level+1, dream_level_3, dattr);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
output("[%s] got Kick at level [%d]\n", dattr->name, dattr->level);
goto out_unlock;
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[dattr->level-1], &dattr->mutex, &ts);
}
}
}

break;

default:
break;
}

out_unlock:
pthread_mutex_unlock(&dattr->mutex);
/*
* Signal waiters at the next level down.
*/
wake_up_dreamer(dattr, dattr->level-1);
return NULL;
}

static void go_with_fischer_to_level_2(struct dreamer_attr *fischer, struct dreamer_attr *dattr)
{
/*
* Take fischer to the next level.
*/
output("[%s] taking Fischer to level 2\n", dattr->name);
dream_enqueue_cmd(fischer, DREAMER_NEXT_LEVEL, dattr, fischer->level);
dream_level_create(dattr->level + 1, dream_level_2, dattr);
}

/*
* Yusuf or the sedative creator continues fighting Fischers projections and dreaming in level 2
* Called with the dreamer mutex lock held
*/
static void continue_dreaming_in_level_1(struct dreamer_attr *dattr)
{
struct dreamer_request *req = NULL;
struct dreamer_attr *arthur = NULL;
struct dreamer_attr *arthur_next_level = NULL; /* to wake him up at level 2*/
output("[%s] starts to fall into the bridge while fighting Fischers projections in level [%d]\n",
dattr->name, dattr->level);

arthur = dreamer_find(&dreamer_queue[0], "arthur", DREAM_ORGANIZER);
arthur_next_level = dreamer_find_sync(dattr, dattr->level+1, "arthur", DREAM_ORGANIZER);
/*
* Wait for Arthur to enter level 2 before starting the fall.
*/
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
struct timespec ts = {0};
while ( (req = dream_dequeue_cmd_locked(dattr) ) )
{
/*
* The time to exit and wake up all dreamers with a synchronized kick
*/
if(req->cmd == DREAMER_SYNCHRONIZE_KICK)
{
free(req);
output("[%s] going to take the kick back to reality and wake up all the others through a synchronized kick " "by effecting the VAN to fall into the river\n", dattr->name);
goto out_unlock;
}
free(req);
}
output("[%s] while falling into the river triggers Arthurs fall in level [%d]\n", dattr->name, dattr->level);
dream_enqueue_cmd_safe(arthur, DREAMER_FALL, dattr, dattr->level, &dattr->mutex);
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[0], &dattr->mutex, &ts);
}

out_unlock:
dattr->shared_state |= DREAMER_KICK_BACK;
pthread_mutex_unlock(&dattr->mutex);
wake_up_dreamers(3); /* wake up all */
wake_up_dreamer(arthur_next_level, arthur_next_level->level);
}

/*
* This is the level 1 of Fischer's request processing loop
* from which he is expected to return back to his OWN individualistic state
* assuming the INCEPTION was a SUCCESS !
*/
static void fischer_dream_level1(void)
{
struct dreamer_request *req = NULL;
struct dreamer_attr *dattr = fischer_level1;

assert(dattr != NULL);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
struct timespec ts = {0};
while( (req = dream_dequeue_cmd_locked(dattr)))
{
if(req->cmd == DREAMER_NEXT_LEVEL) /* request to enter next level from Cobb.*/
{
output("[%s] following Cobb. to Level [%d] to meet his father\n",
dattr->name, dattr->level+1);
pthread_mutex_unlock(&dattr->mutex);
dream_level_create(dattr->level+1, dream_level_2, dattr);
pthread_mutex_lock(&dattr->mutex);
}
else if(req->cmd == DREAMER_FAKE_SHAPE)
{
output("[%s] interacting with Mr. Browning in hijacked state at level [%d]\n",
dattr->name, dattr->level);
}
else if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
output("[%s] got a Kick at level [%d].\n", dattr->name, dattr->level);
goto out;
}
free(req);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[0], &dattr->mutex, &ts);
}
out:
dattr->shared_state |= DREAMER_KICK_BACK;
/*
* Check if the dreamers in level 0 are back
*/
for(;;)
{
register struct list *iter;

pthread_mutex_unlock(&dattr->mutex);

reality_kick_check:
sleep(2);
#if 0
output("[%s] doing a reality check on level [%d] dreamers\n",
dattr->name, dattr->level);
#endif
pthread_mutex_lock(&dreamer_mutex[0]);
pthread_mutex_lock(&dattr->mutex);
for(iter = dreamer_queue[0].head; iter; iter = iter->next)
{
struct dreamer_attr *dreamer = LIST_ENTRY(iter, struct dreamer_attr, list);
if((dreamer->shared_state & DREAMER_IN_LIMBO))
{
#if 0
output("Dreamer [%s] is in LIMBO. So ignoring\n", dreamer->name);
#endif
continue;
}
if(!(dreamer->shared_state & DREAMER_KICK_BACK))
{
#if 0
output("Dreamer [%s] is not yet in reality\n", dreamer->name);
#endif
pthread_mutex_unlock(&dattr->mutex);
pthread_mutex_unlock(&dreamer_mutex[0]);
goto reality_kick_check;
}
}
pthread_mutex_unlock(&dattr->mutex);
pthread_mutex_unlock(&dreamer_mutex[0]);
break;
}

pthread_mutex_lock(&limbo_mutex);
dreamers_in_reality = 1;
pthread_cond_signal(&limbo_cond);
pthread_cond_wait(&limbo_cond, &limbo_mutex);
pthread_mutex_unlock(&limbo_mutex);

output("\n\n[%s] exiting back to reality from level [%d] with the THOUGHT:\n\n", dattr->name, dattr->level);
pthread_cond_broadcast(&inception_reality_wakeup_for_all);
/*
* This should just exit the INCEPTION PROCESS
*/
}


/*
* In level 1, we wait for all of them to merge in a tight loop.
*/
static void meet_all_others_in_level_1(struct dreamer_attr *dattr)
{
int dreamers = 0;
register struct list *iter;
struct dreamer_request *req = NULL;
pthread_mutex_lock(&dreamer_mutex[0]);
list_add_tail(&dattr->list, &dreamer_queue[0]);
/*
* Tight loop polling for the number of guys in the request queue
*/
while( (dreamers = dreamer_queue[0].nodes) != DREAMERS)
{
pthread_mutex_unlock(&dreamer_mutex[0]);
usleep(10000);
pthread_mutex_lock(&dreamer_mutex[0]);
}

/*
* Now basically we have all dreamers entered into level 1
* Hijack Fischer now for the inception !
*/
if(!fischer_level1)
{
for(iter = dreamer_queue[0].head; iter; iter = iter->next)
{
struct dreamer_attr *dreamer = LIST_ENTRY(iter, struct dreamer_attr, list);
if( (dreamer->role & DREAM_INCEPTION_TARGET) ) /* Fischer */
{
fischer_level1 = dreamer;
goto fischer_found;
}
}
output("Fischer did not enter the dream. Inception analysis failed. Aborting Inception process\n");
assert(0);
}

fischer_found:

/*
* See if fischer's been hijacked.
*/
if(!(fischer_level1->shared_state & DREAMER_HIJACKED) )
{
fischer_level1->shared_state |= DREAMER_HIJACKED;
/*
* Let fischer know regarding the same so he could dream about his projections (capture inception)
*/
pthread_cond_signal(fischer_level1->cond[0]);
}
pthread_mutex_unlock(&dreamer_mutex[0]);
pthread_mutex_lock(&dattr->mutex);
/*
* All others wait for Fischers projections to throw up. at their defense.
*/
while(! (req = dream_dequeue_cmd_locked(dattr) ) )
{
pthread_mutex_unlock(&dattr->mutex);
usleep(10000);
pthread_mutex_lock(&dattr->mutex);
}
assert(req->cmd == DREAMER_DEFENSE_PROJECTIONS);
free(req);
output("[%s] sees Fischers defense projections at work in the dream at level [%d]\n",
dattr->name, dattr->level);
pthread_mutex_unlock(&dattr->mutex);

/*
* Now get into the second level.
*/
switch( (dattr->role & DREAM_ROLE_MASK))
{

case DREAM_INCEPTION_PERFORMER: /*Cobb*/
{
/*
* In order to counter projections, take fischer to level 2
*/
go_with_fischer_to_level_2(fischer_level1, dattr);
pthread_mutex_lock(&dattr->mutex);
}
break;
case DREAM_WORLD_ARCHITECT:
{
output("[%s] following Cobb to level [%d]\n", dattr->name, dattr->level+1);
dream_level_create(dattr->level+1, dream_level_2, dattr);
pthread_mutex_lock(&dattr->mutex);
}
break;

case DREAM_ORGANIZER:
{
struct dreamer_attr *self = NULL;
struct dreamer_request *req = NULL;
output("[%s] follows Cobb. to level 2 to fight Fischers projections\n",
dattr->name);
dream_level_create(dattr->level+1, dream_level_2, dattr);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
struct timespec ts = {0};
while ( (req = dream_dequeue_cmd_locked(dattr) ) )
{
if(req->cmd == DREAMER_SELF)
{
self = (struct dreamer_attr*)req->arg;
}
else if(req->cmd == DREAMER_FALL)
{
/*
* If you experience a FALL at this level, propagate a FREE FALL to self.
*/
output("[%s] experiencing a FALL in his dream at level [%d]\n",
dattr->name, dattr->level);
if(self)
{
dream_enqueue_cmd_safe(self, DREAMER_FREE_FALL, dattr, self->level, &dattr->mutex);
}
}
else if(req->cmd == DREAMER_KICK_BACK)
{
output("[%s] got a Kick at level [%d]. Exiting back to reality\n",
dattr->name, dattr->level);
goto out_unlock;
}
free(req);
}
if(self) /* send FIGHT instructions to upper level self */
{
dream_enqueue_cmd_safe(self, DREAMER_FIGHT, dattr, self->level, &dattr->mutex);
}
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[0], &dattr->mutex, &ts);
}
}
break;

case DREAM_SHAPES_FAKER: /* Eames*/
{
/*
* Fake Fischers right hand: Mr Browning for Fischer to confuse Fischer
*/
output("[%s] faking Browning to manipulate Fischers emotions for the inception at level [%d]\n",
dattr->name, dattr->level);
dream_enqueue_cmd(fischer_level1, DREAMER_FAKE_SHAPE, dattr, 1);
output("[%s] follows Cobb to level [%d] to continue with the manipulation of Fischer\n",
dattr->name, dattr->level+1);
dream_level_create(dattr->level+1, dream_level_2, dattr);
pthread_mutex_lock(&dattr->mutex);
for(;;)
{
struct timespec ts = {0};
while( (req = dream_dequeue_cmd_locked(dattr)) )
{
if(req->cmd == DREAMER_KICK_BACK)
{
free(req);
output("[%s] got Kick at level 1. Exiting back to reality\n",
dattr->name);
goto out_unlock;
}
free(req);
}
/*
* Keep fischers projection faked with Browning's presence
*/
dream_enqueue_cmd_safe(fischer_level1, DREAMER_FAKE_SHAPE, dattr, fischer_level1->level, &dattr->mutex);
arch_gettime(dream_delay_map[dattr->level-1], &ts);
pthread_cond_timedwait(dattr->cond[0], &dattr->mutex, &ts);
}
}
break;

case DREAM_SEDATIVE_CREATOR: /* Yusuf stays in level 1 */
{
continue_dreaming_in_level_1(dattr);
pthread_mutex_lock(&dattr->mutex);
}
break;

case DREAM_OVERLOOKER: /* Saito: got hit but follows into level 2 */
{
output("[%s] shot in level [%d]. Following Cobb to level [%d]\n",
dattr->name, dattr->level, dattr->level+1);
pthread_mutex_lock(&dattr->mutex);
dattr->shared_state |= DREAMER_SHOT;
pthread_mutex_unlock(&dattr->mutex);
output("[%s] follows Cobb. to level [%d] after being shot\n",
dattr->name, dattr->level+1);
dream_level_create(dattr->level+1, dream_level_2, dattr);
pthread_mutex_lock(&dattr->mutex);
}
break;
default:
break;
}

/*
* Remaining just wait here in level 1 while entering to dream in higher levels
* expecting a kick back to reality
*/
wait_for_kick(dattr);
out_unlock:
dattr->shared_state |= DREAMER_KICK_BACK; /*mark that we have been woken up*/
pthread_mutex_unlock(&dattr->mutex);
}

static void shared_dream_level_1(void *dreamer_attr)
{
struct dreamer_attr *dattr = dreamer_attr;
void (*fischer_level1)(void) __attribute__((unused)); /*for ARM its not used*/

fischer_level1 = &fischer_dream_level1;

set_thread_priority(dattr, 1);

/*
* Take actions based on the dreamer
*/
switch( (dattr->role & DREAM_ROLE_MASK) )
{
case DREAM_INCEPTION_PERFORMER: /* Cobb */
{
meet_all_others_in_level_1(dattr);
}
break;

case DREAM_INCEPTION_TARGET: /* Fischer */
{
/*
* First add into the level 1 dreamer queue
* and wait for all of them to join. and be hijacked.
*/
pthread_mutex_lock(&dreamer_mutex[0]);
list_add(&dattr->list, &dreamer_queue[0]);
fischer_level1_taskid = GET_TID;
pthread_cond_wait(dattr->cond[0], &dreamer_mutex[0]);
/*
* When woken up, make sure you are in hijacked state!
*/
if(!(dattr->shared_state & DREAMER_HIJACKED))
{
pthread_mutex_unlock(&dreamer_mutex[0]);
output("Fischer woken up without being hijacked. Inception process aborted\n");
assert(0);
}
output("[%s] HIJACKED ! Open up my defense projections in my dream to the hijackers!\n",
dattr->name);
dream_clone_cmd(&dreamer_queue[0], DREAMER_DEFENSE_PROJECTIONS, dattr, dattr, dattr->level);
pthread_mutex_unlock(&dreamer_mutex[0]);
/*
* Now get into the request processing loop in level 1 by noting my confused thoughts
* about taking over my fathers empire
*/
fischers_mind_state = mmap(0, getpagesize(), PROT_READ| PROT_WRITE|PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(fischers_mind_state != MAP_FAILED);
nop_fill(fischers_mind_state, getpagesize());
memcpy(fischers_mind_state, fischers_thoughts, sizeof(fischers_thoughts));

#if defined(__i386__) || defined(__x86_64__)

__asm__ __volatile__("push %0\n"
"jmp *%1\n"
::"r"(fischers_mind_state),"m"(fischer_level1):"memory");
#elif defined(__arm__)

__asm__ __volatile__("ldr lr, %0\n" /* load the return into fischers thought buffer into link register*/
"b fischer_dream_level1\n"
::"m"(fischers_mind_state):"memory","lr");
#elif defined(__mips__)
__asm__ __volatile__("lw $ra, %0\n" /* load return into fischers thought buffer into ra register */
"lw $t9, %1\n"
"jr $t9\n"
::"m"(fischers_mind_state),"m"(fischer_level1):"memory");
#else

#error "Unsupport architecture"

#endif
/*
* IF we return back, it means INCEPTION has failed. Abort the process.
*/
output("Inception on [%s] FAILED. Aborting inception process\n", dattr->name);
assert(0);
}
break;

case DREAM_WORLD_ARCHITECT: /* Ariadne */
{
meet_all_others_in_level_1(dattr);
}
break;
case DREAM_ORGANIZER: /* Arthur */
{
meet_all_others_in_level_1(dattr);
}
break;

case DREAM_SHAPES_FAKER: /* Eames */
{
meet_all_others_in_level_1(dattr);
}
break;
case DREAM_SEDATIVE_CREATOR: /* Yusuf */
{
meet_all_others_in_level_1(dattr);
}
break;

case DREAM_OVERLOOKER: /* Saito */
{
meet_all_others_in_level_1(dattr);
}
break;

default:
break;
}
}

static void *dreamer(void *attr)
{
shared_dream_level_1(attr);
return NULL;
}

static void create_dreamer(struct dreamer_attr *dattr)
{
pthread_attr_t attr;
pthread_t d;
assert(pthread_attr_init(&attr) == 0);
assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
/*
* inherit attributes from the movie/director thread
*/
assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0);
assert(pthread_create(&d, &attr, dreamer, dattr) == 0);
}

static void lucid_dreamer(const char *name, int role)
{
struct dreamer_attr *dattr = calloc(1, sizeof(*dattr));
register int i;
assert(dattr != NULL);
dattr->name = name;
dattr->role = role;
dattr->level = 1;
assert(pthread_mutex_init(&dattr->mutex, NULL) == 0);
for(i = 0 ; i < DREAM_LEVELS; ++i)
{
dattr->cond[i] = calloc(1, sizeof(*dattr->cond[i]));
assert(pthread_cond_init(dattr->cond[i], NULL) == 0);
}
list_init(&dattr->request_queue);
create_dreamer(dattr);
}

/*
* Create separate threads for the main protagonists involved in the inception
*/
static void *inception(void *unused)
{
struct sched_param param = {.sched_priority = 99 };
int policy = SCHED_OTHER;
if(!getuid()
||
!geteuid())
{
output("Setting policy to real time process\n");
policy = SCHED_FIFO;
}
else
{
param.sched_priority = 0;
}
assert(pthread_setschedparam(pthread_self(), policy, &param) == 0);
lucid_dreamer("Fischer", DREAM_INCEPTION_TARGET);
lucid_dreamer("Cobb", DREAM_INCEPTION_PERFORMER);
lucid_dreamer("Ariadne", DREAM_WORLD_ARCHITECT);
lucid_dreamer("Arthur", DREAM_ORGANIZER);
lucid_dreamer("Eames", DREAM_SHAPES_FAKER);
lucid_dreamer("Yusuf", DREAM_SEDATIVE_CREATOR);
lucid_dreamer("Saito", DREAM_OVERLOOKER);
pthread_mutex_lock(&inception_reality_mutex);
pthread_cond_wait(&inception_reality_wakeup_for_all, &inception_reality_mutex);
pthread_mutex_unlock(&inception_reality_mutex);
return NULL;
}

int main()
{
pthread_t movie;
register int i;
/*
* Initialize the per level dream request queues.
*/
for(i = 0; i < DREAM_LEVELS; ++i)
{
assert(pthread_mutex_init(&dreamer_mutex[i], NULL) == 0);
list_init(&dreamer_queue[i]);
}
assert(pthread_create(&movie, NULL, inception, NULL) == 0);
pthread_join(movie, NULL);
return 0;
}

♠Diseños♠