none of the above (aisa0) wrote in dailysrc,
none of the above
aisa0
dailysrc

creative (ab)use of threads and setjmp

i've discovered (?) what i think is an extremely creative misuse of threads:
  • create a new thread and save the stack with setjmp.
  • from the main thread, longjmp to this saved stack.
  • the main thread will start executing the stack of the worker thread!
if the worker thread is still running, this generally causes a problem... but surprisingly, it works if the worker thread has exited. i'm using a loose definition of working, as i'm sure the operating system thinks the memory that was being used for the worker thread stack is free. but the fact that it works at all is shocking. zombie threads!

the setjmp interface predates threading by... a decade or more? i got started on this path by wondering how an interface as old and not-designed-for-threads as setjmp would possibly behave in a brave-new-world. now i've got a whole playground i never knew existed.

i totally deserve a medal! this is probably my best hack evar. ^_^ now if only i could figure out a way to actually *use* it.

the code:
/*public domain*/
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <pthread.h>

static struct global {
  pthread_mutex_t _mutex,
                  *mutex;
  pthread_cond_t _cond,
                 *cond;;
  jmp_buf jmp;
} g={
  PTHREAD_MUTEX_INITIALIZER,
  &g._mutex,
  PTHREAD_COND_INITIALIZER,
  &g._cond,
  { 0 },
};

static void*
thread(c)
  void *c;
{
  char sp;

  printf("jmp thread 0x%016lu with stack 0x%016lx\n",
         (unsigned long)pthread_self(),
         (void*)&sp);
  
  switch(setjmp(g.jmp)) {
  case 0:
    printf("setjmp from thread 0x%016lu with stack 0x%016lx\n",
           (unsigned long)pthread_self(),
           (void*)&sp);
    longjmp(g.jmp, 1);
  
  case 1:
    printf("longjmp from thread 0x%016lu with stack 0x%016lx\n",
           (unsigned long)pthread_self(),
           (void*)&sp);
    pthread_cond_broadcast(g.cond);
    pthread_exit(c);

  default:
    printf("longjmp to thread 0x%016lu with stack 0x%016lx\n",
           (unsigned long)pthread_self(),
           (void*)&sp);
    pthread_exit(c);
  }
}

main(argc, argv)
  char *argv[];
{
  pthread_t id;

  printf("main thread 0x%016lu with stack 0x%016lx\n",
         (unsigned long)pthread_self(),
         (void*)&id);

  pthread_create(&id, (pthread_attr_t*)0, &thread, (void*)0);
  pthread_mutex_lock(g.mutex);
  pthread_cond_wait(g.cond, g.mutex);
  pthread_join(id, (void**)0);
  longjmp(g.jmp, 2);

  exit(0x80);
}


the output:
main thread 0x0000000134557696 with stack 0x00000000bfbfe874
jmp thread 0x0000000134558720 with stack 0x00000000bf8fdfb7
setjmp from thread 0x0000000134558720 with stack 0x00000000bf8fdfb7
longjmp from thread 0x0000000134558720 with stack 0x00000000bf8fdfb7
longjmp to thread 0x0000000134557696 with stack 0x00000000bf8fdfb7


[x-posted to aisa0, cs_wos, cprogramming, and dailysrc.]
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

  • 6 comments