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;
}

lunes, 4 de abril de 2011

Candidatos y Premios Darwin

El Premio Darwin es un premio irónico que toma su nombre del creador de la teoría de la evolución Charles Darwin, basandose en el supuesto que la gente, el ser humano mejora genéticamente accidentalmente matandose o esterilizándose por un error absurdo o un descuido.

Para ser el desgraciado ganador de uno de estos premios anuales, se deben cumplir 5 requisitos:
"Incapacidad de crear descendencia" - El nominado ha de estar muerto, esterilizado o simplemente haber dejado inútiles sus Órganos sexuales
"Excelencia" - Increíble despiste o pasmosa lógica que no puede funcionar nunca. Estupidez única y/o sensacional aplicación de esta.
"Auto-selección" - Causa y efecto de su propia desaparición o esterilización. Mérito incondicionalmente individual
"Madurez" - En la totalidad de sus facultades mentales y físicas. Homo Sapiens
"Veracidad" - El hecho ha de estar perfectamente corroborado. Nada de Leyendas Urbanas

________________________________

Abril 2001, Memphis, Tennessee (EEUU)
Un hombre intentó ganarle al tren conduciendo su automóvil alrededor de las barreras de seguridad del cruce--y como resultado chocó violentamente contra otro vehículo que estaba ejecutando la misma maniobra desde el lado opuesto de los carriles. El otro conductor había tenido la misma brillante idea. El primer conductor murió en el impacto. El accidente ocurrió a un lado de los rieles, y el tren pasó sin ser obstaculado por los vehículos.

La historia del Chevy Impala JET

El último ganador fue el misterio dueño de un Chevy Impala propulsado a chorro. La Patrulla de Carreteras de Arizona (E.E.U.U.) tropezó con un montón de metal derretido empotrado en la ladera de un precipicio junto a una curva de la carretera. Los restos se parecían a los de un accidente aéreo, pero tenían aspecto de automóvil y no se había informado de ningún accidente aéreo en la zona.

Un laboratorio reconstruyó la historia. Parece ser que el conductor había conseguido de alguna manera una unidad JATO (Jet Assisted take off-en realidad un cohete de combustible sólido) que se utiliza para dar una "empuje" extra a los aviones militares de transporte pesado para despegar desde aeródromos cortos.

Condujo su Chevy Impala al interior del desierto y encontró un largo tramo recto. Entonces enganchó la unidad JATO a su coche, entró dentro, cogió velocidad y encendió el dispositivo de motor a reacción. Los policías estimaron que el conductor del coche encendió el cohete a una distancia de 3 millas (5 km.), aproximadamente, del lugar del choque. Allí, el asfalto estaba quemado y derretido.

Alcanzó el empuje máximo en menos de 5 segundos, con lo que el Chevy alcanzó velocidades de más de 350 mph (560 km./h.) y continuó a máximo empuje durante unos 20-25 segundos adicionales, el conductor, que no era piloto, habría experimentado lo más parecido a las fuerzas gravitatorias que normalmente están reservadas a los pilotos de cazas F-14 bajo una post-combustión completa, básicamente le provocó quedar inconsciente durante el resto del suceso.

El individuo siguió sobre la carretera durante aproximadamente 2,5 millas (4 km.) (15-20 segundos) antes de que el conductor aplicara y quemara completamente los frenos, reventara los neumáticos y dejara marcas de goma sobre la superficie de la carretera.

Llegó a volar durante otras 1,4 millas (2,3 km.), impactando en la ladera del precipicio a una altura de 125 pies (40 m.), dejando un cráter negro de tres pies de profundidad en la roca. La mayoría de los restos del conductor no fueron recuperables; no obstante, se extrajeron fragmentos pequeños de hueso, dientes y cabellos del cráter y se quitaron fragmentos de una uña en un trozo de escombros que parecía ser un trozo del volante.

20 de mayo, 2000, EEUU
Un motociclista de 30 años fue aplastado cerca de Phoenix, Arizona, en diciembre después de que aparentemente, queriendo vengarse del automovilista de una camioneta que lo había hecho disminuir la velocidad al encontrarse adelante en el mismo carril, el motociclista aceleró, rebasó la camioneta y luego frenó bruscamente.

25 de agosto, 1999, Alemania
La policía de Bodenwerder hizo un espantoso descubrimiento el miércoles por la tarde. Dos agentes encontraron el cuerpo demacrado y en parcial estado de descomposición de una anciana de 75 años en su apartamento. Había muerto varias semanas antes. Según la policía, la señora había sido víctima de su propia manía de coleccionismo. Las habitaciones de su apartamento estaban repletas de aparatos domésticos, comida, ropa y folletos archivados. Una pila de artículos le había caído encima y la había parcialmente enterrada. Ella no había podido liberarse y murió de sed. Vivía sola y raramente hablaba con los vecinos, así que su ausencia no fue notada inmediatamente.
La policía encontró 50 latas de pescado, pilas de tubos de pasta dental, 30 linternas, diez grandes maletas de cuero e hileras de publicidad cuidadosamente archivada. De su apartamento sólo quedaban unos cuantos metros cuadrados de espacio habitable en el pasillo.

15 de julio, 1999
Tres jóvenes en Oklahoma (EEUU) estaban disfrutando los festejos del día de independencia y aparentemente quisieron encender algunos fuegos artificiales. El único problema fue el sitio que eligieron para hacerlo. Se pusieron encima de un tanque de destilación de combustible de más de cien mil litros. Curiosamente, había una fuga minúscula, y al encenderse los juegos pirotécnicos se produjo una bola de fuego vista por varios kilómetros a la redonda. Los amigos fueron lanzados varios centenares de metros y sus cuerpos fueron encontrados a 230 metros de sus respectivos asientos.

2 de septiembre, 1999
Un abogado y dos amigos suyos estaban pescando en el lago Caddo en Texas cuando se desató una tormenta eléctrica sobre el lago. Todos los demás barcos se dirigieron inmediatamente hacia la costa, pero no el abogado y sus amigos. Solo en la parte trasera de su botecito de aluminio, este individuo se puso de pie, alargó los brazos en forma de crucifijo y gritó “AQUí ESTOY, DIOS, ¡DISPARA!” Y Dios respondió. Los otros dos pasajeros del barquito sobrevivieron el rayo con sólo quemadas menores.

7 de mayo, 1999
En marzo en Bucharest, Romania, el fútbolista profesional Mario Bugeanu y su novia murieron accidentalmente de envenenamiento por inhalación de monóxido de carbono en su automóvil mientras hacían el amor.

30 de septiembre, 1998
William S. Burress, de 49 años, cayó y murió en Cincinnati (EEUU) en octubre, minutos después de haberse deslizado de una ventana del segundo piso de la cárcel del condado de Hamilton, donde estaba detenido bajo cargos de robo. La cuerda de seis metros que Burress se había confeccionado con sábanas se cortó en dos, haciéndolo caer al pavimento. Un empleado de la cárcel dijo que oyó un ruido fuerte en la calle y alguien que gemía “Ohhh, mi cabeza.”

28 de agosto, 1998
En julio, un hombre de 28 años se ahogó en Mount Clemens, Michigan (EEUU), en una piscina de un complejo de apartamentos mientras ganaba un juego con amigos sobre quién podía contener el aliento por más tiempo.

12 de junio, 1998
En marzo, tres hombres que habían estado excavando en una montaña por casi un año, supuestamente para encontrar y robar de una tumba de la antigua Dinastía Han en la provincia de Shandong, en China, murieron por los gases tóxicos que había en la tumba.

[Agencia Reuters, Londres, 1996]
Un campesino polaco, Krystof Azninski, podría clasificarse como el hombre más "macho" de Europa al decapitarse él solo. Azninski, de 30 años, había estado bebiendo con amigos cuando alguien sugirió que se desnudaran y jugaran algunos "juegos de hombres". Comenzaron por golpearse uno a otro en la cabeza con carámbanos, pero luego un hombre tomó una sierra de cadena y se cortó la punta del pie. No queriendo quedarse atrás, Azninski tomó la sierra y gritó "¡Miren esto, entonces!" giró la sierra eléctrica hacia su propia cabeza y se la cortó.
"Es raro," dijo un compañero, "porque cuando era joven, le gustaba ponerse la ropa interior de su hermana. Pero murió como un hombre."

[N.Y. Times, 23 de mayo, 1998] [Santa Cruz Sentinel, 8 de mayo 1998] [San Francisco Chronicle, 13 de mayo 1998] [AP wirecopy, 5 de mayo, 1998]
En EEUU, las siguientes personas fueron atropelladas por un tren en mayo: El Sr. Heath Hess, en Hornell, N.Y. (no oyó el silbido porque estaba hablando con un teléfono celular mientras se tapaba el otro oído para bloquear el ruido que no le permitía oír bien); Jesse Jones, en San Mateo, California (intentó ganarle al tren, yendo alrededor de la barrera que le cerraba el paso), Brian McArdle, de 27 años, en Burlingame, California (sentado en el extremo de la plataforma de la estación, pensó que el tren pasaría sin tocarlo); y David Flannery, de 22 años, en Berkeley Springs, Virginia Occidental (le ganó a un amigo en una competencia de “Quién Puede Estar De Pie Por Más Tiempo En Los Rieles Delante De Un Tren Que Se Aproxima”).

Kalamazoo Gazette, 1 de abril, 1995
James Burns, de 34 años, de Alamo, Michigan, EEUU, murió en marzo mientras trataba de reparar lo que la policía describió como “una especie de vehículo de granja”. Burns le pidió a un amigo que condujera el vehículo mientras él se colgaba por debajo para poder darse cuenta del origen del ruido sospechoso. La ropa de Burns se atoró en algo, sin embargo, y el otro hombre encontró a Burns “envuelto alrededor del eje conductor.”

17 de julio, 1998
Un hombre de 47 años murió en Arjay, Kentucky (EEUU) en junio cuando su amigo de toda la vida, Silas Caldwell, también de 47 años, “apuntó bajo” cuando trató de dispararle a la lata de cerveza que el hombre se puso sobre la cabeza. Y un hombre de 28 años murió ahogado en Fox Lake, Illinois (EEUU) en junio después de que un explosivo accidentalmente abrió un agujero en el fondo de su barco. (La policía teoriza que el hombre tuviera intenciones de usar el explosivo para hacer subir los peces a la superficie y así capturarlos más fácilmente.)

[1997]
La mañana del 11 de noviembre, dos buenos amigos, de 27 y 41 años de edad y residentes de Whitney (EEUU), al norte de Waco, Tejas, hicieron lo que acostumbraban hacer cada vez que se encontraban en los caminos rurales desiertos: conducían sus vehículos directamente el uno hacia el otro en un juego para ver quién “se rajaba” primero. Esa mañana chocaron a 110 Km. por hora. El más joven se salvó por haberse puesto el cinturón; el otro no se lo había abrochado y murió instantáneamente.

De nuevo la ciencia triunfa sobre Budweiser

Tenemos muchas líneas de alta tensión cruzando el estado. Éstas líneas van sobre torres de diferentes tipos de construcción. Cerca de las áreas urbanas éstas son normalmente "Torres Decorativas de Metal" (deben ser más bonitas que las torres de madera).

A veces tenemos gente que piensan que sería agradable escalar estas torres y disfrutar del aire nocturno. La mayoría disfrutan de las vistas, permanecen lejos de los cables, y cuando se aburren, vuelven abajo.

Pues ésta es una historia de un tipo que estaba un poco abatido por una reciente pelea con una novia y decidió que necesitaba un poco de aire fresco para aclarar su cabeza. Pensó en subir a una torre. Procedió a escalar una torre al sur de Hartford al lado de la carretera I-91. Antes de llegar a su torre, decidió detenerse para comprar un pack de 6 botellas que le ayudara a despejar sus pensamientos.

Así que nuestro candidato al Premio Darwin se sentó a 60 pies (20 m.) por encima de la carretera, bebiendo su cerveza, consolando su dañado ego. Nuestro amigo llevaba 5 cervezas cuando se dio cuenta de que necesitaba un servicio de caballeros. Había un largo camino de bajada, así que se bajó la cremallera y decidió hacer sus necesidades hacia fuera de la torre. La electricidad es una cosa divertida. No necesitas tocar un cable para electrocutarte. En estas líneas de 115,000 voltios, dependiendo de las condiciones, se puede estar a una distancia de 6 pulgadas (15 cm.) y aun así resultar electrocutado. Pues, nuestro amigo procedió a orinar cerca del conductor (cable) cuando la corriente formó un arco con su "chorro" (el agua salada es un excelente conductor de la electricidad) alcanzó sus partes pudendas y le arrojó fuera de la torre.

Los tipos de mi trabajo tuvieron un corte momentáneo en esta línea y enviaron a unos operarios para que comprobaran si había alguna avería. Cuando nuestros chicos llegaron al escenario del accidente, encontraron a una persona muy muerta, con la cremallera bajada, qué tenía sus partes pudendas humeando y una única cerveza encima de la torre.

[1997]
Un hombre de 38 años murió en Jenkins Township, Pennsylvania (EEUU), en noviembre, un par de horas después de haber visitado a un amigo para ver sus culebras. Según el amigo, el hombre había metido la mano en el tanque de una cobra y había tocado a la víbora, que luego lo había mordido. Negándose a ir al hospital, el hombre dijo “soy un hombre, yo me las arreglo,” y se fue a un bar, donde tomó tres bebidas y les presumió a todos los presentes que una cobra lo acababa de morder. Una hora después, había muerto.

[1989]
*En Francia, Jacques LeFevrier quiso asegurarse de su muerte cuando intentó el suicido. Fue a la cima de un acantilado y se ató un nudo alrededor del cuello con una soga. Amarró la otra extremidad de la soga a una roca grande. Bebió veneno y se incendió la ropa. Hasta trató de dispararse al último momento. Saltó al precipicio y se disparó al mismo tiempo. La bala no lo tocó pero al pasar cortó la soga sobre él. Libre de la amenaza de ahorcarse, cayó al mar. El repentino zambullido en el agua extinguió las llamas y le hizo vomitar el veneno. Un pescador caritativo lo sacó del agua y lo llevó a un hospital, donde murió... de hipotermia.

3 de febrero de 1990
*En EEUU, un hombre de Renton, Washington trat%oacute; de cometer un asalto. Probablemente se trataba de su primera vez, dado que no tenía récord de crímenes violentos y debido a las decisiones estúpidas que tomó:

  • el objetivo fue H&J Leather & Firearms, un negocio que vende armas;
  • el negocio estaba lleno de clientes, en un estado donde un número considerable de la población adulta tiene licencia para traer pistola de mano escondida en lugares públicos;
  • para poder entrar al local, el ladrón tuvo que rodear un auto de policía estacionado frente a la puerta;
  • un agente de policía uniformado estaba de pie frente al mostrador tomando café antes de entrar en servicio.

Al ver al agente de policía, el presunto ladrón anunció el asalto y disparó un par de veces al aire. El policía y un empleado respondieron a los disparos inmediatamente, matándolo. Varios otros clientes también sacaron sus armas, pero no dispararon. Nadie más fue herido.

[1997, Buxton, Carolina del Norte, EEUU]
* Un hombre murió en la playa cuando un hoyo de 2.5 metros de profundidad se derrumbó con él sentado dentro. Gente que se encontraba en la playa en ese momento dijo que Daniel Jones, de 21 años, había excavado el hoyo por diversión, o para protegerse del viento, y había estado sentado en una silla plegable en el fondo del hoyo el jueves en la tarde cuando el hoyo se derrumbó, enterrándolo bajo casi dos metros de arena. La gente en la playa de Outer Banks usó las manos y palas para tratar de llegar a Jones, residente de Woodbridge, Virginia, pero no lo alcanzaron. Trabajadores de rescate usando equipo pesado tardaron casi una hora en liberar a Jones mientras cerca de 200 personas observaban. Jones fue pronunciado muerto en el hospital.

[1997]
*Santiago Alvarado, de 24 años, murió en febrero en Lompoc, California (EEUU), cuando cayó de bruces del techo de un negocio de bicicletas donde estaba tratando de entrar para robar. Lo que causó su muerte fue la linterna que se había puesto en la boca (para tener las manos libres) y que con la caída se le atiborró contra la base del cráneo cuando golpeó el suelo.

[1997]
*Sylvester Briddell, Jr., de 26 años, se mató en febrero en Selbyville, Delaware (EEUU), mientras ganaba una apuesta hecha con sus amigos, quienes afirmaban que él no se atrevería a meterse un revólver cargado con cuatro balas en la boca y oprimir el gatillo.

[Hickory Daily Record 21/12/92]
* Ken Barger, de 47 años, se disparó accidentalmente y murió en Newton, Carolina del Norte, EEUU, cuando, al despertarlo el sonido del teléfono al lado de su cama, trató de alcanzar el teléfono pero en vez de eso tomó una Smith & Wesson .38 Especial, la cual se descargó cuando Ken se la acercó al oído.

[Associated Press de Cairo, Egipto, 31/8/95]
* Seis personas se ahogaron mientras trataban de rescatar una gallina que se había caído en un pozo en el sur de Egipto. Un joven campesino de 18 años fue el primero en bajar al pozo de 20 metros de profundidad. Se ahogó, aparentemente después que la resaca lo sumergió, dijo la policía. Su hermana y dos hermanos, ninguno de los cuales podía nadar bien, bajaron uno por uno para tratar de ayudarlo, pero también se ahogaron. Luego llegaron dos campesinos a ayudar, pero también ellos fueron víctimas de la resaca. Los cuerpos de los seis fueron sacados más tarde del pozo de Nazlat Imara, al sur de Cairo. También sacaron a la gallina. Ésta última sobrevivió.

[Desconocido, 3/25/93]
* Una dieta terrible y una habitación sin ventilación se han indicado como las causas principales de la muerte de un hombre a quien su propio gas lo mató. No había señal alguna en su cuerpo pero la autopsia reveló grandes cantidades de gas metano en su sistema. Su dieta consistóa principalmente de legumbres y coliflor (y algunas otras cosas): una combinación perfecta de alimentos. Aparentemente, el hombre murió mientras dormía por haber respirado la nube venenosa que flotaba sobre su cama. Si hubiese estado afuera, o si hubiese tenido la ventana abierta, no habría sido fatal. Pero el hombre estaba herméticamente encerrado en su habitación aislada. Era "...un hombre obeso con una gran capacidad para crear (este gas peligroso)." Tres de los rescatadores se enfermaron y uno fue hospitalizado.

♠Diseños♠