Пример #1
0
/* Test mutex */
static int 
test_mutex(void){
    sync_mutex_t m1, m2;
    printf("UNIT TEST | sync/mutex: ");
    m1 = sync_create_mutex();
    test_assert(m1);
    m2 = sync_create_mutex();
    test_assert(m2);
    /* Test simple operations */
    test_assert(sync_try_acquire(m1));
    test_assert(!sync_try_acquire(m1));
    sync_release(m1);
    test_assert(sync_try_acquire(m1));
    sync_release(m1);
    sync_acquire(m1);
    sync_release(m1);
    sync_acquire(m1);
    sync_release(m1);
    /* Test independance */
    test_assert(sync_try_acquire(m1));
    test_assert(sync_try_acquire(m2));
    sync_release(m1);
    sync_release(m2);
    /* Clean up */
    sync_destroy_mutex(m1);
    sync_destroy_mutex(m2);
    printf("PASSED\n");
    return 0;
}
Пример #2
0
int sys_sync_create_object(sync_object_type_t obj_type,
                           void *uobj,uint8_t *attrs,
                           ulong_t flags)
{
  kern_sync_object_t *kobj=NULL;
  int r;
  sync_id_t id;
  task_t *caller=current_task();
  uint8_t shared;
  task_sync_data_t *sync_data;

  if( !s_check_system_capability(SYS_CAP_SYNC) ) {
    return ERR(-EPERM);
  }

  if( !uobj || obj_type > __SO_MAX_TYPE ) {
    return ERR(-EINVAL);
  }

  if( !attrs ) {
    shared=0;
  } else {
    if( get_user(shared,attrs) ) {
      return ERR(-EINVAL);
    }
    if( shared != PTHREAD_PROCESS_PRIVATE &&
        shared != PTHREAD_PROCESS_SHARED ) {
      return ERR(-EINVAL);
    }
  }

  sync_data=get_task_sync_data(caller);
  if( !sync_data ) {
    return ERR(-EAGAIN);
  }

  LOCK_SYNC_DATA_W(sync_data);
  r=__sync_allocate_id(caller,shared,&id);
  if( r ) {
    goto put_sync_data;
  }
  UNLOCK_SYNC_DATA_W(sync_data);

  switch( obj_type ) {
    case __SO_MUTEX:
      r=sync_create_mutex(&kobj,uobj,attrs,flags);
      break;
    case __SO_RAWEVENT:
      r=sync_create_uevent(&kobj,uobj,attrs,flags);
      break;
    case __SO_RWSEMAPHORE:
      r=sync_create_urw_semaphore(&kobj,uobj,attrs,flags);
      break;
    case __SO_CONDVAR:
    case __SO_SEMAPHORE:
    default:
      r=-EINVAL;
      break;
  }

  /* Copy ID to user without holding the lock for better performance. */
  if( !r ) {
    r=copy_to_user(uobj,&id,sizeof(id));
  }

  LOCK_SYNC_DATA_W(sync_data);
  if( r ) {
    goto put_id;
  }
  __install_sync_object(caller,kobj,id);
  UNLOCK_SYNC_DATA_W(sync_data);

  return 0;
put_id:
  __sync_free_id(caller,id);
put_sync_data:
  UNLOCK_SYNC_DATA_W(sync_data);

  /* Free object, if any. */
  if( kobj ) {
    sync_put_object(kobj);
  }
  release_task_sync_data(sync_data);
  return ERR(r);
}