Struct cmb_resourceguard

Struct Documentation

struct cmb_resourceguard

The gatekeeper class for resources a process can wait for. It is derived from cmi_hashheap and inherits its methods, adding a pointer to the resource it guards and a list of any observer resource guards that get signals forwarded from this one.

Public Types

bool() cmb_resourceguard_demand_func (const struct cmi_resourcebase *rbp, const struct cmb_process *pp, const void *ctx)

Function prototype for a resource demand predicate.

Param rbp:

Pointer to a resource base object.

Param pp:

Pointer to a process

Param ctx:

Pointer to whatever context is needed to determine the outcome.

Return:

true if the demand is considered satisfied (e.g., a resource is available), false if not.

Public Functions

void cmb_resourceguard_initialize(struct cmb_resourceguard *rgp, struct cmi_resourcebase *rbp)

Make a resource guard ready for use.

Parameters:
  • rgp – Pointer to a resource guard.

  • rbp – Pointer to the thing it will be guarding.

void cmb_resourceguard_terminate(struct cmb_resourceguard *rgp)

Un-initializes a resource guard.

Parameters:
  • rgp – Pointer to a resource guard.

int64_t cmb_resourceguard_wait(struct cmb_resourceguard *rgp, cmb_resourceguard_demand_func *demand, const void *ctx)

Enqueue and suspend the calling process until it reaches the front of the priority queue and its demand function returns true.

ctx is whatever context the demand function needs to evaluate if it is satisfied or not, such as the number of units needed from the resource or something more complex and user application defined. Returns whatever signal was received when the process was reactivated. Cannot be called from the main process.

Parameters:
  • rgp – Pointer to a resource guard.

  • demand – Pointer to the demand predicate function

  • ctx – The context argument to the demand predicate function.

bool cmb_resourceguard_signal(struct cmb_resourceguard *rgp)

Ring the bell for a resource guard to check if any of the waiting processes should be resumed. Will evaluate the demand function for the first process in the queue, if any, and will resume it if (and only if) its demand function (*demand)(rp, pp, ctx) returns true.

Resumes zero or one waiting processes. Call it again if there is a chance that more than one process could be ready, e.g., if some process just returned five units of a resource and there are several processes waiting for one unit each.

Returns true if some process was resumed, false otherwise, hence easy to wrap in a loop like while (cmb_resource_guard_signal(rgp)) { ... }

By default, Cimba does not allow potential priority inversion where a sequence of lower-priority processes could starve a higher-priority process indefinitely. In cases where some waiting process needs to bypass another, e.g., if there are three available units of the resource, the first process in the queue demands five, and there are three more behind it that demands one each, it is up to the application to dynamically change process priorities to bring the correct process to the front of the queue and make it eligible to resume. If this sort of thing is important in your use case, you probably want to write that code yourself.

Parameters:
  • rgp – Pointer to a resource guard.

bool cmb_resourceguard_cancel(struct cmb_resourceguard *rgp, struct cmb_process *pp)

Remove this process from the priority queue and resume it with a CMB_PROCESS_CANCELLED signal.

Parameters:
  • rgp – Pointer to a resource guard.

  • pp – Pointer to a process

Returns:

true if the process was in the queue, false if not.

bool cmb_resourceguard_remove(struct cmb_resourceguard *rgp, const struct cmb_process *pp)

Remove this process from the priority queue without resuming it.

Parameters:
  • rgp – Pointer to a resource guard.

  • pp – Pointer to a process

Returns:

true if the process was in the queue, false if not.

void cmb_resourceguard_register(struct cmb_resourceguard *rgp, struct cmb_resourceguard *obs)

Register another resource guard as an observer of this one, forwarding signals and causing the observer to evaluate its demand predicates as well.

Parameters:
  • rgp – Pointer to the subject resource guard.

  • obs – Pointer to an observer resource guard.

bool cmb_resourceguard_unregister(struct cmb_resourceguard *rgp, const struct cmb_resourceguard *obs)

Unregister another resource guard as an observer of this one.

Parameters:
  • rgp – Pointer to the subject resource guard.

  • obs – Pointer to an observer resource guard.

Returns:

true if the observer was registered, false if not.

Public Members

struct cmi_hashheap priority_queue

The base hashheap class

struct cmi_resourcebase *guarded_resource

The resource it guards

struct cmi_slist_head observers

Any other resource guards observing this one