Example #1
0
int main() {
  SIM_SLEEP_OFF();

  // some variables
  int corenum   = RigelGetCoreNum();
  int threadnum = RigelGetThreadNum();
	int numcores  = RigelGetNumCores();
  int numthreads = RigelGetNumThreads();
  int th_per_core    = RigelGetNumThreadsPerCore();
  int th_per_cluster = RigelGetNumThreadsPerCluster();

  int rows_per_thread = SIZE / numthreads; // statically divide work up
  int start = rows_per_thread * threadnum;
  int end   = start + rows_per_thread;
  int i=0, j=0;

  // setup on thread 0
  if(threadnum == 0) {

    BARRIER_INIT(&bi);

    // init values
    for(i=0;i<SIZE;i++){
      for(j=0;j<SIZE;j++){
        MATRIX[j][i] = j; 
      }
      VECTOR[i] = i;
      RESULT[i] = 0xbeef;
    }

    //printf("rpf:%d numthreads:%d\n", rows_per_thread, numthreads);
    ClearTimer(0);
    // get started
    StartTimer(0);
    atomic_flag_set(&Init_Flag);
  }

  // wait for core 0 to finish setup
  atomic_flag_spin_until_set(&Init_Flag);

  // do the work
  for( i=start; i<end; i++ ) {
    RESULT[i] = MVM(i);  
  }

  BARRIER_ENTER(&bi);

  // cleanup on thread 0
  if(threadnum == 0) {
    StopTimer(0);
    // print results
    for(i=0; i<SIZE; i++) {
      RigelPrint(RESULT[i]);
    }
  }

  return 1;
}
//NOTE: I'm omitting the key checks in get/setspecific b/c they're not
//required by the standard (behavior is undefined).
void *pthread_getspecific(pthread_key_t key)
{
  //if(key > __MAX_KEYS_PER_THREAD)
  //  return -EINVAL;
  __pthread_tls_t * const tls = &(pthread_tls[RigelGetThreadNum()]);
  //const unsigned int mask = 1U << key;
  //if(!(tls->valid & (1U << key)))
  //  return -EINVAL;
  return tls->data[key];
}
//TODO: Need some global structure to track joiners, in order to:
//1) Detect deadlock (2 thread try to join() each other)
//2) Detect if multiple threads are trying to join() the same thread
//Both of these are required for this function by the POSIX standard.
int pthread_join(pthread_t thread, void **retval)
{
  if(thread == RigelGetThreadNum()) return EDEADLK;
  if(thread >= RigelGetNumThreads()) return ESRCH;
  while(_pt[thread].funcptr != NULL) {
  //spin
  }
  if(retval != NULL) {
    *retval = _pt[thread].retval;
  }
  return 0;
}
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg)
{
  for(int i = 0; i < (__MAX_NUM_CORES*___MAX_THREADS_PER_CORE); i++) {
    if(_pt[i].funcptr == NULL) { //Thread is available
      *thread = i;
      RigelBroadcastUpdate(arg, _pt[i].funcarg);
      RigelBroadcastUpdate(_pt[RigelGetThreadNum()].tid, _pt[i].callingtid);
      RigelBroadcastUpdate(i, _pt[i].tid);
      RigelBroadcastUpdate(start_routine, _pt[i].funcptr); //The thread will be polling on this, so it should be the last thing to update.
      return 0;
    }
  }
  //No threads are available.
  return EAGAIN;
}
int pthread_key_delete(pthread_key_t key)
{
  if(key > __MAX_KEYS_PER_THREAD)
    return -EINVAL;
  __pthread_tls_t * const tls = &(pthread_tls[RigelGetThreadNum()]);
  const unsigned int mask = 1U << key;
  if(!(tls->valid & mask))
    return -EINVAL;
  tls->valid &= ~mask;
  unsigned int tries = 0;
  while((tls->data[key] != NULL) && (tries < PTHREAD_MAX_DESTRUCTOR_ITERATIONS)) {
    tls->destructors[key](tls->data[key]);
    tries++;
  }
  return 0;
}
int pthread_key_create(pthread_key_t *key, void(*destructor)(void *))
{
  __pthread_tls_t * const tls = &(pthread_tls[RigelGetThreadNum()]);
  for(unsigned int i = 0; i < __MAX_KEYS_PER_THREAD; i++)
  {
    const unsigned int mask = 1U << i;
    if(!(tls->valid & mask))
    {
      tls->valid |= mask;
      tls->destructors[i] = destructor;
      *key = i;
      return 0;
    }
  }
  return -EAGAIN; //Out of keys.
}
void __rigel_premain(void)
{
  int tid = RigelGetThreadNum();
  if(tid == 0) {
    SIM_SLEEP_ON();
    SIM_SLEEP_OFF();
    _pt[tid].funcptr = (void *)0xFFFFFFFF; //Make sure we don't get a thread spawned on us by accident
  }
  else {
    RigelPrint(0xFEDC);
    while(1) {
      while(_pt[tid].funcptr == NULL);
      void *retval = _pt[tid].funcptr(_pt[tid].funcarg);
      RigelBroadcastUpdate(retval, _pt[tid].retval);
      RigelBroadcastUpdate(NULL, _pt[tid].funcptr);
    }
  }
}
Example #8
0
int main(int argc, char *argv[])
{
  if(RigelGetThreadNum() == 0) {
    SIM_SLEEP_OFF();
  }
  void *mallocs[100];
  for(int i = 0; i < 100; i++) {
    mallocs[i] = malloc(RigelRandUInt(4, 2000)*4);
    RigelPrint(i);
  }
  for(int i = 0; i < 100; i++) {
    free(mallocs[i]);
    RigelPrint(0xFFFF0000 | i);
  }
  //SIM_SLEEP_OFF();
  //}
  return 0;
}
Example #9
0
struct _reent *
__getreent (void)
{
  return __reent_ptrs[RigelGetThreadNum()];
}