blob: 0139e1a68d05285f708b88a169bc78665d658747 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <zircon/types.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/unique_ptr.h>
// A running Zircon job, with an open handle and cached properties.
//
// Defines a globally-sortable "importance key" that can be used to
// rank all jobs by relative importance.
//
// Importance keys have the form:
//
// <capped-importance> ':' <importance-chain> '~'
//
// <capped-importance> is the Job's capped_importance() as two hex digits.
// <importance-chain> is the concatenation of the importance() values of a
// Job's ancestors and itself, with the root-most Job's importance first.
//
// This produces a key that, when sorted using strcmp(), will cluster Jobs
// with the same capped_importance(), then break ties using a Job's
// ancestors' importances. The trailing '~' causes shorter strings to sort
// higher than longer strings, ensuring that parents are more important
// than their children.
//
// Example values:
//
// 32:c8c8c896c83264~ << A deep BACKGROUND job, capped to DISPOSABLE
// 32:c8c8c896c832~
// 32:c8c8c896c89632~
// 64:c8c8c896c86464~
// 64:c8c8c896c864c8~
// 96:c8c8c896c8~ << A CRITICAL job, capped to FOREGROUND
// 96:c8c8c896~ << The previous job's FOREGROUND parent
// 96:c8c8c8c896~
// c8:c8c8~
// c8:c8~
//
// TODO(dbort): Consider using a similarly-structured uint64_t instead of a
// string.
class Job : public fbl::DoublyLinkedListable<fbl::unique_ptr<Job>> {
public:
using importance_t = uint32_t;
// Takes ownership of |handle|, even on failure. To aid testability, this
// class must not perform any syscalls on |handle| except zx_handle_close.
static zx_status_t Create(
zx_koid_t koid, zx_handle_t handle,
const char* name, importance_t importance,
const Job* parent, fbl::unique_ptr<Job>* out);
~Job();
zx_koid_t koid() const { return koid_; }
const char* name() const { return name_.get(); }
// The importance returned by ZX_PROP_JOB_IMPORTANCE.
importance_t importance() const { return importance_; }
// Like importance(), but capped to be no more important
// than any ancestor.
importance_t capped_importance() const {
return capped_importance_;
}
// An opaque, strcmp()-comparable string for sorting Jobs by their global
// relative importance. Higher importance will sort higher.
// See the class comment for a description of the keys.
const char* importance_key() const { return importance_key_.get(); }
// Returns the handle but maintains ownership.
zx_handle_t handle() const { return handle_; }
// Type for linked lists of this class.
using List = fbl::DoublyLinkedList<fbl::unique_ptr<Job>>;
private:
Job(zx_koid_t koid, zx_handle_t handle, fbl::unique_ptr<char[]> name,
importance_t importance, importance_t capped_importance,
fbl::unique_ptr<char[]> importance_key);
const zx_koid_t koid_;
// An open handle to the underlying job object, or ZX_HANDLE_INVALID.
// Closed when this object is destroyed.
const zx_handle_t handle_;
const fbl::unique_ptr<char[]> name_;
const importance_t importance_;
const importance_t capped_importance_;
const fbl::unique_ptr<char[]> importance_key_;
};
// Reorders |jobs| so entries are ordered by importance_key(), with
// the least-important job first.
void sort_jobs_by_importance_key(Job::List *jobs);