Esempio n. 1
0
int
main_the_rest (void)
{
  while (1)
    {
      main_thread_ready = 1;
      semaphore_enter (background_sem);
      if (db_shutdown)
	{
	  sf_shutdown (NULL, NULL);
	}
      else
	{
	  if (main_continuation_reason == MAIN_CONTINUE_ON_SCHEDULER &&
	      cfg_scheduler_period > 0)
	    {
	      sched_do_round ();
	    }
	  else if (cfg_autocheckpoint)
	    {
	      sf_make_auto_cp ();	/* Use the one and same old log file. */
	    }
	  else
	    /* Should not happen! */
	    {
	      GPF_T1 ("Initial thread continued, "
		  "although autocheckpointing is not used.");
	    }
	  main_continuation_reason = MAIN_CONTINUE_ON_CHECKPOINT;
	}
    }
  return 0;
}
Esempio n. 2
0
static void *high_run(void *arg) {
	test_emit('e');
	semaphore_enter(&s);
	test_emit('g');
	semaphore_leave(&s);
	test_emit('h');
	return NULL;
}
Esempio n. 3
0
static void *mid_run(void *arg) {
	test_emit('c');
	semaphore_enter(&s);
	test_emit('d');
	test_assert_zero(thread_launch(high));
	test_emit('f');
	semaphore_leave(&s);
	test_emit('i');
	return NULL;
}
Esempio n. 4
0
static void *low_run(void *arg) {
	test_emit('a');
	semaphore_enter(&s);
	test_emit('b');
	test_assert_zero(thread_launch(mid));
	test_emit('j');
	semaphore_leave(&s);
	test_emit('k');
	return NULL;
}
Esempio n. 5
0
int
mutex_enter (dk_mutex_t *mtx)
#endif
{
#ifndef MTX_DEBUG
  return semaphore_enter (mtx->mtx_handle);
#else
  semaphore_t *sem = (semaphore_t *) mtx->mtx_handle;
#ifdef MALLOC_DEBUG
  if (_current_fiber == NULL)
    {
      assert (mtx == _dbgmal_mtx);
      return semaphore_enter (sem);
    }
#endif
  assert (_current_fiber != NULL);
  if (sem->sem_entry_count)
    {
      assert (sem->sem_entry_count == 1);
      assert (mtx->mtx_owner == NULL);
      sem->sem_entry_count--;
    }
  else
    {
      assert (mtx->mtx_owner != _current_fiber);
      thread_queue_to (&sem->sem_waiting, _current_fiber);
      _fiber_status (_current_fiber, WAITSEM);
      _fiber_schedule_next ();
      assert (sem->sem_entry_count == 0);
    }
  assert (mtx->mtx_owner == NULL);
  if (mtx->mtx_entry_check
      && !mtx->mtx_entry_check (mtx, THREAD_CURRENT_THREAD, mtx->mtx_entry_check_cd))
    GPF_T1 ("Mtx entry check fail");

  mtx->mtx_owner = _current_fiber;
  mtx->mtx_entry_file = (char *) file;
  mtx->mtx_entry_line = line;

  return 0;
#endif
}
Esempio n. 6
0
static void
freeze_thread_write (dk_session_t * ses)
{
  USE_GLOBAL
  SESSION_SCH_DATA (ses)->sio_random_write_ready_action = unfreeze_thread_write;
  SESSION_SCH_DATA (ses)->sio_writing_thread = current_process;
  add_to_served_sessions (ses);

  ss_dprintf_4 (("Write on Thread %p blocked.", (void *) current_process));

  semaphore_enter (current_process->thr_sem);
}
Esempio n. 7
0
/*
   service_read ()

   Used to read from a session. Handles scheduling
   if the session would block.

   Used for reading from a service thread. If the read would block,
   put the thread to wait. When the scheduling cycle sees input on this
   session the random_input_ready_action is called.
   This wakes up this thread and schedules it for execution on the next
   round

   The need_all argument controls whether this function may return after reading
   fewer than the requested number of bytes. This function always reads at
   least 1 byte.

   If the calling thread is the scheduling thread and io would block, this
   allows schedule and recursively blocks on all pending i/o.
   If the calling thread is some other thread, this disables
   the thread and tells the scheduler to resume this when the input is ready.

   Returns the number of bytes read.
 */
int
service_read (dk_session_t * ses, char *buffer, int req_bytes, int need_all)
{
  USE_GLOBAL
  int last_read = 0;
  int bytes = req_bytes;
  du_thread_t *cur_proc;	/* mty NEW */
  int rc;

  DBG_CHECK_READ_FAIL (ses);

  while (bytes > 0)
    {
      without_scheduling_tic ();
      if (!ses->dks_is_read_select_ready && ses->dks_session && ses->dks_session->ses_class != SESCLASS_STRING)
	{
	  tcpses_is_read_ready (ses->dks_session, &ses->dks_read_block_timeout);
	  if (DKSESSTAT_ISSET (ses, SST_TIMED_OUT))
	    rc = -1;
	  else
	    rc = session_read (ses->dks_session, &(buffer[last_read]), bytes);
	}
      else
	{
	  if (!ses->dks_session)
	    longjmp_splice (&(SESSION_SCH_DATA (ses)->sio_read_broken_context), 1);

	  rc = session_read (ses->dks_session, &(buffer[last_read]), bytes);
	}
      ses->dks_is_read_select_ready = 0;
      restore_scheduling_tic ();

      if (rc == 0)
	PROCESS_ALLOW_SCHEDULE ();
      else if (rc > 0)
	{
	  bytes = bytes - rc;
	  last_read = last_read + rc;
	  if (!need_all)
	    {
	      ses->dks_bytes_received += last_read;
	      return (last_read);
	    }
	}
      if (rc <= 0)
	{
	  if (SESSTAT_ISSET (ses->dks_session, SST_INTERRUPTED))
	    {
	      PROCESS_ALLOW_SCHEDULE ();
	    }
	  else if (SESSTAT_ISSET (ses->dks_session, SST_BLOCK_ON_READ))
	    {
	      /* would block. suspend thread */

	      cur_proc = current_process;	 /* mty NEW */
	      if (!PROCESS_TO_DK_THREAD (cur_proc))
		{
		  /* We have a block on a server thread. We recognize it
		   * because a server thread is not associated to a request.
		   * The read would block the server thread. Run others and
		   * do a recursive check_inputs to resume other threads that
		   * may now be ready for i/o. Do a timeout round to unblock
		   * threads waiting on timed-out futures if the select times
		   * out. Finally retry read.
		   */
		  int rc2;
		  PROCESS_ALLOW_SCHEDULE ();
		  rc2 = check_inputs (PASS_G & atomic_timeout, 1);
		  if (rc2 == 0)
		    timeout_round (PASS_G ses);
		}
	      else
		{
		  SESSION_SCH_DATA (ses)->sio_random_read_ready_action = unfreeze_thread_read;
		  SESSION_SCH_DATA (ses)->sio_reading_thread = cur_proc;
		  add_to_served_sessions (ses);
		  semaphore_enter (cur_proc->thr_sem);
		}
	    }
	  else if (1 ||				 /* ?? */
	      SESSTAT_ISSET (ses->dks_session, SST_TIMED_OUT) || SESSTAT_ISSET (ses->dks_session, SST_BROKEN_CONNECTION))
	    {
	      SESSTAT_CLR (ses->dks_session, SST_OK);
	      SESSTAT_SET (ses->dks_session, SST_BROKEN_CONNECTION);

	      longjmp_splice (&(SESSION_SCH_DATA (ses)->sio_read_broken_context), 1);
	    }
	  else
	    {
	      ses->dks_bytes_received += last_read;

	      ss_dprintf_2 (("Unrecognized I/O error rc=%d errno=%d in service_read.", rc, errno));
	      longjmp_splice (&(SESSION_SCH_DATA (ses)->sio_read_broken_context), 1);
	    }
	}
    }
  ses->dks_bytes_received += last_read;
  return (last_read);
}