Harlequin RIP SDK

This file implements the RIP Data Resource (RDR) System. More...

#include "rdrpriv.h"
#include "hqspin.h"
#include "pjwhash.h"
#include <string.h>

Enumerations

enum  { RDR_FREELIST_THRESHOLD = 100 }
 

Functions

static __forceinline void * rdr_freelist_alloc (rdr_freelist_t **plist, size_t size)
 
static __forceinline void rdr_freelist_release (rdr_freelist_t **plist, void *ptr)
 
int rdr_hashmap_create (void)
 
void rdr_hashmap_destroy (void)
 
rdr_lookup_tlookup_acquire_classtype (sw_rdr_class Class, sw_rdr_type Type)
 
static rdr_lookup_tlookup_acquire_named (sw_rdr_namespace Namespace, const char *name, size_t length)
 
static rdr_lookup_tnew_lookup (void)
 
static rdr_lookup_tlookup_acquire_create (intptr_t key, rdr_lookup_t *inlookup)
 
void lookup_release (rdr_lookup_t **plookup)
 
static void move_iterator (sw_rdr_iterator *find, sw_rdr_iterator **from, sw_rdr_iterator **to)
 
static sw_rdrfind_rdr (sw_rdr_iterator *find, int unlock)
 Find an rdr from an iterator structure. More...
 
void link_iterator (sw_rdr_iterator *iterator, sw_rdr_iterator **list)
 Link an iterator into a list.
 
void unlink_iterator (sw_rdr_iterator *iterator)
 unlink an iterator from either list
 
static sw_rdr_iteratornew_iterator (int32 flags)
 Create a new iterator and add it to the list.
 
void unlock_previous_rdr (sw_rdr_iterator *iterator)
 Unlock a previously locked RDR.
 
static sw_rdr_result find_next_rdr (sw_rdr_iterator *iterator, sw_rdr_class *pclass, sw_rdr_type *ptype, sw_rdr_id *pid, void **pptr, size_t *plength, HqBool lock)
 Find and optionally lock an RDR from an iterator. More...
 
static sw_rdrinit_rdr (sw_rdr *rdr, sw_rdr_class rdrclass, sw_rdr_type rdrtype, sw_rdr_id rdrid, void *ptr, size_t length, sw_rdr_priority priority)
 Initialise a new sw_rdr structure, but don't add it.
 

Variables

static hq_atomic_counter_t curr_free
 

Detailed Description

This file implements the RIP Data Resource (RDR) System.

Copyright (C) 2023 Global Graphics Software Ltd. All rights reserved. This source code contains the confidential and trade secret information of Global Graphics Software Ltd. It may not be used, copied or distributed for any reason except as set forth in the applicable Global Graphics license agreement.

The RDR API is primarily used to share blocks of data between the skin and core, or in general, between multiple Providers and Consumers.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
RDR_FREELIST_THRESHOLD 

If the total number of items on freelists exceeds this threshold, attempt to purge an entry, but only if it's not the last entry on its freelist. We only look at freelists for purging when we are allocating, so we're outside of the RDR mutex.

Function Documentation

◆ find_next_rdr()

static sw_rdr_result find_next_rdr ( sw_rdr_iterator iterator,
sw_rdr_class pclass,
sw_rdr_type ptype,
sw_rdr_id pid,
void **  pptr,
size_t *  plength,
HqBool  lock 
)
static

Find and optionally lock an RDR from an iterator.

This is an internal call but is marked HQNCALL in case that makes it easier to optimise the tail-calls in SwNextRDR() and SwLockNextRDR().

◆ find_rdr()

static sw_rdr* find_rdr ( sw_rdr_iterator find,
int  unlock 
)
static

Find an rdr from an iterator structure.

This is the central find routine used by all API find and iterate calls, and used internally by the (de)registration calls.

As well as finding the first matching RDR for a particular set of criteria, it returns the parent of the returned RDR (or the last in the list), and the next RDR to check (for continuing the search).

Note that when multithreading this function MUST be protected by mutex on entry. It can optionally unlock the mutex during the search.

Parameters
[in]findThe iterator to use and update. When multithreading, access to iterators MUST be protected by mutex.
[in]unlockTRUE if called with a mutex that is to be unlocked during the iteration. The concurrency count is incremented and the mutex unlocked, then locked and decremented on exit.
Returns
The RDR found, or NULL. Note that when multithreading the RDR found by find_rdr() could nevertheless be deregistered before this function has returned so must be protected against by the caller using mutex.

◆ lookup_acquire_classtype()

rdr_lookup_t* lookup_acquire_classtype ( sw_rdr_class  Class,
sw_rdr_type  Type 
)

Lookup an existing RDR list using Class,Type and acquire a reference count.

Parameters
[in]ClassThe class of the lookup to perform.
[in]TypeThe type of the lookup to perform.
Returns
If the Class,Type exists, an RDR lookup structure, with an increased reference count. This reference must be released by the caller using lookup_release(). If the Class,Type does not exist, NULL is returned.

This function must be called with the RDR mutex locked.

◆ lookup_acquire_create()

static rdr_lookup_t* lookup_acquire_create ( intptr_t  key,
rdr_lookup_t inlookup 
)
static

Lookup an RDR list and acquire a reference count, or create the list header and store in the hash map if it does not exist.

Parameters
[in]keyA Class,Type or Namespace,Name key created with new_key_classtype() or new_key_named(). Ownership of the key is taken by this function, regardless of the result.
[in]inlookupA new lookup structure, created with new_lookup(). Ownership of the lookup is taken by this function, regardless of the result.
Returns
If the Class,Type or Namespace,Name exists or if it could be created, an RDR lookup structure with an increased reference count. This reference must be released by the caller using lookup_release(). If the Class,Type or Namespace,Name does not exist and could not be created due to an error, NULL is returned.

This function must be called with the RDR mutex locked.

◆ lookup_acquire_named()

static rdr_lookup_t* lookup_acquire_named ( sw_rdr_namespace  Namespace,
const char *  name,
size_t  length 
)
static

Lookup an existing RDR list using Namespace,Name and acquire a reference count.

Parameters
[in]NamespaceThe namespace class of the lookup to perform.
[in]nameThe name to lookup in the RDR namespace
[in]lengthThe length of name.
Returns
If the Namespace,Name exists, an RDR lookup structure, with an increased reference count. This reference must be released by the caller using lookup_release(). If the Namespace,Name does not exist, NULL is returned.

This function must be called with the RDR mutex locked.

◆ lookup_release()

void lookup_release ( rdr_lookup_t **  plookup)

Release a reference to an RDR lookup, freeing it and removing from the map if necessary. This must be called with the mutex locked.

◆ move_iterator()

static void move_iterator ( sw_rdr_iterator find,
sw_rdr_iterator **  from,
sw_rdr_iterator **  to 
)
static

Find an iterator in one list and if found move it to another. This MUST be protected by a mutex.

◆ new_lookup()

static rdr_lookup_t* new_lookup ( void  )
static

Create a new lookup structure, in case a registration or iterator creation needs it. This may involve an allocation, so is preferably done outside the RDR mutex.

◆ rdr_freelist_alloc()

static __forceinline void* rdr_freelist_alloc ( rdr_freelist_t **  plist,
size_t  size 
)
static

Allocate one of the freelist-managed objects.

◆ rdr_freelist_release()

static __forceinline void rdr_freelist_release ( rdr_freelist_t **  plist,
void *  ptr 
)
static

Release one of the freelist-managed objects.

◆ rdr_hashmap_create()

int rdr_hashmap_create ( void  )

Glue function to create the map of RDRs.

◆ rdr_hashmap_destroy()

void rdr_hashmap_destroy ( void  )

Glue function to destroy the map of RDRs.

Variable Documentation

◆ curr_free

hq_atomic_counter_t curr_free
static

Atomic count of number of items across all freelists.