コード例 #1
0
ファイル: cpu-keepalive.c プロジェクト: spiiroin/mce
/** Set keepalive state
 *
 * @param active  true to start keepalive, false to end keepalive
 */
static void cka_state_set(bool active)
{
  static bool keepalive_is_active = false;
  static bool flagged = false;
  static tick_t started = 0;

  if( keepalive_is_active != active )
  {
    tick_t now = cka_tick_get_current();

    if( (keepalive_is_active = active) )
    {
#ifdef ENABLE_WAKELOCKS
      wakelock_lock(cpu_wakelock, -1);
#endif
      started = now;
      mce_log(LL_DEVEL, "keepalive started");
    }
    else
    {
      tick_t dur = now - started;

      if( dur > KEEPALIVE_STATE_WARN_LIMIT_MS )
      {
        mce_log(LL_CRIT, "long keepalive stopped after %"PRId64" ms", dur);
      }
      else
      {
        mce_log(LL_DEVEL, "keepalive stopped after %"PRId64" ms", dur);
      }

      flagged = false;

#ifdef ENABLE_WAKELOCKS
      wakelock_unlock(cpu_wakelock);
#endif
    }
  }
  else if( keepalive_is_active && !flagged ) {
    tick_t now = cka_tick_get_current();
    tick_t dur = now - started;
    if( dur > KEEPALIVE_STATE_WARN_LIMIT_MS )
    {
      flagged = true;
      mce_log(LL_CRIT, "long keepalive active after %"PRId64" ms", dur);
    }
  }
}
コード例 #2
0
ファイル: android-wakelock.c プロジェクト: chihchun/ofono
static int android_wakelock_acquire(struct wakelock *lock)
{
	if (lock == NULL)
		return -EINVAL;

	if (lock->acquisitions > 0) {
		lock->acquisitions++;
		return 0;
	}

	if (wakelock_lock(lock->name) < 0)
		return -EIO;

	lock->acquisitions++;

	return 0;
}
コード例 #3
0
/** Evaluate need for suspend blocking
 */
static void mia_keepalive_rethink(void)
{
    static bool have_lock = false;

    bool need_lock = (mia_keepalive_id != 0);

    if( have_lock == need_lock )
        goto EXIT;

    mce_log(LL_DEBUG, "inactivity notify wakelock: %s",
            need_lock ? "OBTAIN" : "RELEASE");

    if( (have_lock = need_lock) )
        wakelock_lock("mce_inactivity_notify", -1);
    else
        wakelock_unlock("mce_inactivity_notify");

EXIT:
    return;
}
コード例 #4
0
ファイル: cpu-keepalive.c プロジェクト: Vesuri/mce
/** Re-evaluate the end of cpu-keepalive period
 *
 * Calculates maximum of wakeup period and per client renew periods
 * and uses it to reprogram the end of cpu-keepalive period
 */
static
void
cpu_keepalive_rethink(void)
{
  time_t maxtime = wakeup_timeout;

  GHashTableIter iter;
  gpointer key, val;

#ifdef ENABLE_WAKELOCKS
  wakelock_lock(cpu_wakelock, -1);
#endif

  g_hash_table_iter_init(&iter, clients);
  while( g_hash_table_iter_next (&iter, &key, &val) )
  {
    client_t *client = val;
    if( maxtime < client->timeout )
    {
      maxtime = client->timeout;
    }
  }
  cpu_keepalive_set_timer(maxtime);
}
コード例 #5
0
ファイル: mce-io.c プロジェクト: ClementFan/mce
/**
 * Callback for successful chunk I/O
 *
 * @param source The source of the activity
 * @param condition The I/O condition
 * @param data The iomon structure
 * @return Depending on error policy this function either exits
 *         or returns TRUE
 */
static gboolean io_chunk_cb(GIOChannel *source,
			    GIOCondition condition,
			    gpointer data)
{
	iomon_struct *iomon = data;
	gchar *buffer = NULL;
	gsize bytes_want = 4096;
	gsize bytes_read = 0;
	gsize chunks_read = 0;
	gsize chunks_done = 0;
	GIOStatus io_status;
	GError *error = NULL;
	gboolean status = TRUE;

	/* Silence warnings */
	(void)condition;

	if (iomon == NULL) {
		mce_log(LL_CRIT, "iomon == NULL!");
		status = FALSE;
		goto EXIT;
	}

	iomon->latest_io_condition = 0;

	/* Seek to the beginning of the file before reading if needed */
	if (iomon->rewind == TRUE) {
		g_io_channel_seek_position(source, 0, G_SEEK_SET, &error);
		if( error ) {
			mce_log(LL_ERR,	"%s: seek error: %s",
				iomon->file, error->message);
		}

		/* Reset errno,
		 * to avoid false positives down the line
		 */
		errno = 0;
		g_clear_error(&error);
	}

	if( iomon->chunk_size < bytes_want ) {
		bytes_want -= bytes_want % iomon->chunk_size;
	} else {
		bytes_want = iomon->chunk_size;
	}

	buffer = g_malloc(bytes_want);

#ifdef ENABLE_WAKELOCKS
	/* Since the locks on kernel side are released once all
	 * events are read, we must obtain the userspace lock
	 * before reading the available data */
	wakelock_lock("mce_input_handler", -1);
#endif

	io_status = g_io_channel_read_chars(source, buffer,
					    bytes_want, &bytes_read, &error);


	/* If the read was interrupted, ignore */
	if (io_status == G_IO_STATUS_AGAIN) {
		g_clear_error(&error);
	}

	if( bytes_read % iomon->chunk_size ) {
		mce_log(LL_WARN, "Incomplete chunks read from: %s", iomon->file);
	}

	/* Process the data, and optionally ignore some of it */
	if( (chunks_read = bytes_read / iomon->chunk_size) ) {
		gchar *chunk = buffer;
		for( ; chunks_done < chunks_read ; chunk += iomon->chunk_size ) {
			++chunks_done;
			if (iomon->callback(chunk, iomon->chunk_size) != TRUE) {
				continue;
			}
			/* if possible, seek to the end of file */
			if (iomon->seekable) {
				g_io_channel_seek_position(iomon->iochan, 0,
							   G_SEEK_END, &error);
			}
			/* in any case ignore rest of the data already read */
			break;
		}
	}

	mce_log(LL_INFO, "%s: status=%s, data=%d/%d=%d+%d, skipped=%d",
		iomon->file, io_status_name(io_status),
		bytes_read, (int)iomon->chunk_size, chunks_read,
		bytes_read % (int)iomon->chunk_size, chunks_read - chunks_done);

#ifdef ENABLE_WAKELOCKS
	/* Release the lock after we're done with processing it */
	wakelock_unlock("mce_input_handler");
#endif


	g_free(buffer);

	/* Were there any errors? */
	if (error != NULL) {
		mce_log(LL_ERR,
			"Error when reading from %s: %s",
			iomon->file, error->message);

		if ((error->code == G_IO_CHANNEL_ERROR_FAILED) &&
		    (errno == ENODEV) &&
		    (iomon->seekable)) {
			errno = 0;
			g_clear_error(&error);
			g_io_channel_seek_position(iomon->iochan, 0,
						   G_SEEK_END, &error);
			if( error ) {
				mce_log(LL_ERR,	"%s: seek error: %s",
					iomon->file, error->message);
			}
		} else {
			status = FALSE;
		}

		/* Reset errno,
		 * to avoid false positives down the line
		 */
		errno = 0;
		g_clear_error(&error);
	} else if ((bytes_read == 0) &&
		   (io_status != G_IO_STATUS_EOF) &&
		   (io_status != G_IO_STATUS_AGAIN)) {
		mce_log(LL_ERR,
			"Empty read from %s",
			iomon->file);
	}

EXIT:
	if ((status == FALSE) &&
	    (iomon != NULL) &&
	    (iomon->error_policy == MCE_IO_ERROR_POLICY_EXIT)) {
		// FIXME: this is not how one should exit from mainloop
		mce_quit_mainloop();
		exit(EXIT_FAILURE);
	}

	return TRUE;
}