Пример #1
0
static FFTW_WORKER worker(void *arg)
{
     struct worker *ego = (struct worker *)arg;
     struct work *w;

     for (;;) {
	  /* wait until work becomes available */
	  os_sem_down(&ego->ready);

	  w = ego->w;

	  /* !w->proc ==> terminate worker */
	  if (!w->proc) break;

	  /* do the work */
          w->proc(&w->d);

	  /* signal that work is done */
	  os_sem_up(&ego->done);
     }

     /* termination protocol */
     os_sem_up(&termination_semaphore);

     os_destroy_thread();
     /* UNREACHABLE */
     return 0;
}
Пример #2
0
/**
 * Test scenario:
 * This is the same scenario as in scen5 but here we use mtx1 instead of mtx0.
 * This makes situation where mutexes are unlocked in the same order as locking
 * order, which additionally checks is if OS does not force the unlock sequence.
 *
 * L locks mtx0 and mtx1
 * H locks mtx1
 * L unlock mtx0 (critical moment)
 * We should see context switch to H even if L holds some other mtx
 * IMPORTANT: unlocking mtx0 before mtx1 creates same unlock order as locking
 * order. Additional check is that M should not be scheduled until H exits
 */
int test_scen6_workerH(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow L to progress */
   ret = os_sem_down(&test_sem[1], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   test_assert(3 == test_atomic[0]);
   test_atomic[0] = 4;

   /* try to lock mtx0, we should switch to L */
   ret = os_mtx_lock(&test_mtx[0]);
   test_assert(0 == ret);

   /* we should now get mtx0 locked in L and we have mtx1 */
   test_assert(5 == test_atomic[0]);
   test_atomic[0] = 6;

   /* finish test we should switch to M */
   os_mtx_unlock(&test_mtx[0]);
   test_assert(6 == test_atomic[0]);
   test_atomic[0] = 7;

   return 0;
}
Пример #3
0
int test_scen4_workerHM(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow L to progress */
   ret = os_sem_down(&test_sem[1], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* we will be woken up from L */
   test_assert(5 == test_atomic[0]);
   test_atomic[0] = 6;

   /* lock mtx1, this will switch back to L */
   ret = os_mtx_lock(&test_mtx[1]);
   test_assert(0 == ret);

   /* we should switch from H */
   test_assert(14 == test_atomic[0]);
   test_atomic[0] = 15;

   /* prepare to finish task (no ctx switch this time) */
   os_mtx_unlock(&test_mtx[1]);
   test_assert(15 == test_atomic[0]);
   test_atomic[0] = 16;
   /* by finishing the task we should switch to M */

   return 0;
}
Пример #4
0
static void* run(void* h)
{
	DEBUGOUT("%p: logw__run", h);
    HANDLE;
    os_sem_down();
    LOCK;
    while(1) {
		if (handle->shared.buf == NULL) {
			DEBUGOUT("%p: logw__run: i'm waiting...", h);
			WAIT;
			DEBUGOUT("%p: logw__run: i woke up", h);
		}
        assert (handle->shared.buf);

        int fd = handle->shared.fd;
        void* buf = handle->shared.buf;
        uint8_t len = handle->shared.len;
		handle->shared.buf = NULL;
		UNLOCK;

        hs_send(fd, (unsigned char*)buf, len);

		LOCK;
		cb_lock_acquire();
		handle->callback->appendDone(handle, buf, len, false, SUCCESS);
		cb_lock_release();
	}
	UNLOCK;
	return NULL;
}
Пример #5
0
/**
 * Test scenario:
 * Recursive bounded priority inversion problem
 * Here we focus on os_unlock_mtx() implementation. We check if during call of
 * this function the task at the end of recursive locking chain gets the right
 * priority while prio_reset() operation.
 *
 * Task L locks mtx0 and mtx1
 * Task M locks mtx2 and mtx0
 * Task HM lock mtx1
 * Task H locks mtx2
 * Task L unlocks mtx1 (critical moment)
 * Test succeeds if during os_mtx_unlock() done by task L context is not
 * switched to task MH.
 */
int test_scen4_workerH(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow L to progress */
   ret = os_sem_down(&test_sem[2], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* we will be woken up from L */
   test_assert(7 == test_atomic[0]);
   test_atomic[0] = 8;

   /* lock mtx2, this will switch back to L */
   ret = os_mtx_lock(&test_mtx[2]);
   test_assert(0 == ret);

   /* we should switch from M */
   test_assert(12 == test_atomic[0]);
   test_atomic[0] = 13;

   /* prepare to finish task */
   os_mtx_unlock(&test_mtx[2]);
   test_assert(13 == test_atomic[0]);
   test_atomic[0] = 14;
   /* by finishing the task we should switch to HM */

   return 0;
}
Пример #6
0
/**
 * test procedure for test1 task1
 */
int test1_task_proc1(void *OS_UNUSED(param))
{
   int ret;

   ret = os_sem_down(&(worker_tasks[0].sem), OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   return 0;
}
Пример #7
0
/**
 * test procedure for os_sem_down with timeout
 */
int task_proc(void *param)
{
   int ret;
   task_data_t *data = (task_data_t*)param;

   data->result = false; /* reseting the test result */

   /* checking if sem have 0 */
   ret = os_sem_down(&(data->sem), OS_TIMEOUT_TRY);
   test_assert(OS_WOULDBLOCK == ret);
   /* sleeping for task assigned time */
   ret = os_sem_down(&(data->sem), data->idx);
   test_assert(OS_TIMEOUT == ret);

   data->result = true;

   return 0;
}
Пример #8
0
/**
 * test procedure for test1 task2
 */
int test1_task_proc2(void *OS_UNUSED(param))
{
   int ret;

   /* wait until timeout - (if still exist the bug will not update the priomax
    * while wakup by timeout) */
   ret = os_sem_down(&(worker_tasks[0].sem), 10);
   test_assert(OS_TIMEOUT == ret);
   /* signalize the same sem to wake up the task1 */
   os_sem_up(&(worker_tasks[0].sem));

   return 0;
}
Пример #9
0
int test_scen3_workerM(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow L to progress */
   ret = os_sem_down(&test_sem[0], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* we should return here when H will finish */
   test_assert(11 == test_atomic[0]);
   test_atomic[0] = 12;

   return 0;
}
Пример #10
0
int task_proc(void* param)
{
   int ret;
   unsigned idx = (unsigned)(size_t)param;

   while(task_data[idx].loop < TEST_CYCLES)
   {
      ++(task_data[idx].loop);
      os_sem_up(&(task_data[(idx + 1) % 2].sem));
      ret = os_sem_down(&(task_data[idx].sem), OS_TIMEOUT_INFINITE);
      test_assert(0 == ret);
   }

   return 0;
}
Пример #11
0
int test_scen4_workerM(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow L to progress */
   ret = os_sem_down(&test_sem[0], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* we will return here from L */
   test_assert(2 == test_atomic[0]);
   test_atomic[0] = 3;

   /* lock mtx2 */
   ret = os_mtx_lock(&test_mtx[2]);
   test_assert(0 == ret);
   test_assert(3 == test_atomic[0]);
   test_atomic[0] = 4;

   /* lock mtx0 this will switch to L */
   ret = os_mtx_lock(&test_mtx[0]);
   test_assert(0 == ret);

   /* we should switch from L */
   test_assert(10 == test_atomic[0]);
   test_atomic[0] = 11;
   /* the effective priority of this task should still be on H level */
   test_assert(4 == task_worker[2].prio_current);

   /* unlock mtx0, no context switch yet */
   os_mtx_unlock(&test_mtx[0]);
   test_assert(11 == test_atomic[0]);
   test_atomic[0] = 12;

   /* unlock mtx2, we should switch to H */
   os_mtx_unlock(&test_mtx[2]);

   /* we should return from HM */
   test_assert(16 == test_atomic[0]);
   test_atomic[0] = 17;

   /* prepare to finish task */
   /* by finishing the task we should switch to L */

   return 0;
}
Пример #12
0
int test_scen2_workerM(void *OS_UNUSED(param))
{
   int ret;

   /* M also need goes to sleep to allow L to lock the mutex,
    * after it will be woken up (simultaneously with L) it should not schedule
    * until L will unlock the mtx */
   ret = os_sem_down(&test_sem[1], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* B should be scheduled after H
    * Verify that H finishes his task function */
   test_assert(1 == test_atomic[0]);
   test_atomic[0] = 2;

   /* if test_assertion was meet this is the end of the test */
   return 0;
}
Пример #13
0
/**
 * Test scenario:
 * Classic priority inversion problem
 * Three tasks with different prio H (high prio) M (mid prio) L (low prio)
 * L locks the mtx as a first, then we force context switch to H which tries to
 * lock the same mtx. H should boost the prio of L and block on mtx.
 * Next L should be scheduled instead of M (which will happened it prio boost
 *will
 * not work). Sequence of scheduling is verified by tracking execution sequence
 * in global variable.
 */
int test_scen2_workerH(void *OS_UNUSED(param))
{
   int ret;

   /* we need to sleep to allow the L to lock the mutex */
   ret = os_sem_down(&test_sem[0], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* try to lock the mtx
    * this should boost the prio of L since it already lock it */
   ret = os_mtx_lock(&test_mtx[0]);
   test_assert(0 == ret);

   /* signalize that M can be scheduled now
    * finish the task */
   test_atomic[0] = 1;

   return 0;
}
Пример #14
0
int test_scen3_workerLM(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow LM and L to progress */
   ret = os_sem_down(&test_sem[1], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   test_assert(2 == test_atomic[0]);
   test_atomic[0] = 3;

   /* lock the mtx0 then mtx1 (second will switch the context to L)*/
   ret = os_mtx_lock(&test_mtx[0]);
   test_assert(0 == ret);
   test_assert(3 == test_atomic[0]);
   test_atomic[0] = 4;
   ret = os_mtx_lock(&test_mtx[1]);
   test_assert(0 == ret);

   /* we should return here when L will unlock mtx1 */
   test_assert(8 == test_atomic[0]);
   test_atomic[0] = 9;
   /* also this means that LM should still have p(H) */
   test_assert(4 == task_worker[2].prio_current);
   /* while L should have its original prio */
   test_assert(1 == task_worker[3].prio_current);

   /* unlock mtx1 and mtx0, last one should cause switch to H */
   os_mtx_unlock(&test_mtx[1]);
   /* no context switch */
   test_assert(9 == test_atomic[0]);
   test_atomic[0] = 10;
   os_mtx_unlock(&test_mtx[0]);

   /* we should return here when H and M will finish */
   test_assert(12 == test_atomic[0]);
   test_atomic[0] = 13;
   /* also this means that LM should have original prio */
   test_assert(2 == task_worker[2].prio_current);

   return 0;
}
Пример #15
0
int test_scen6_workerM(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow L to progress */
   ret = os_sem_down(&test_sem[0], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   test_assert(2 == test_atomic[0]);
   test_atomic[0] = 3;

   /* switch context to H */
   os_sem_up(&test_sem[1]);

   /* finish test */
   test_assert(7 == test_atomic[0]);
   test_atomic[0] = 8;

   return 0;
}
Пример #16
0
/**
 * Test scenario:
 * Recursive bounded priority inversion problem
 * To not duplicate description of the problem please refer to Comment 2 in
 * os_mtx.c
 *
 * Task L locks only mtx2
 * Task LN locks both mtx1 and mtx2
 * Task H locks only mtx1
 * Task M is woken up (critical moment)
 * Test succeeds if task L is scheduled instead task M
 */
int test_scen3_workerH(void *OS_UNUSED(param))
{
   int ret;

   /* block on sem, allow M, LM and L to progress */
   ret = os_sem_down(&test_sem[0], OS_TIMEOUT_INFINITE);
   test_assert(0 == ret);

   /* we should return here from L */
   test_assert(5 == test_atomic[0]);
   test_atomic[0] = 6;

   /* try to lock mtx0, this will preempt and switch to L */
   ret = os_mtx_lock(&test_mtx[0]);
   test_assert(0 == ret);

   /* we should return here when LM will unlock mtx0 */
   test_assert(10 == test_atomic[0]);
   test_atomic[0] = 11;

   return 0;
}