1ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// 22f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor// SkTLS.h 32f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor// 42f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor// 52f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor// Created by Mike Reed on 4/21/12. 62def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor// Copyright (c) 2012 __MyCompanyName__. All rights reserved. 72def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor// 82def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor 92def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor#ifndef SkTLS_DEFINED 102def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor#define SkTLS_DEFINED 112def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor 12578b69b186d9cba0a6ae1dd7f4c04cd6a49f0aacJohn McCall#include "SkTypes.h" 132def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor 144cde94a04694d5d24dc9e3bf6c5fa3403629838eEli Friedman/** 154cde94a04694d5d24dc9e3bf6c5fa3403629838eEli Friedman * Maintains a per-thread cache, using a CreateProc as the key into that cache. 162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor */ 172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorclass SkTLS { 182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorpublic: 192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor typedef void* (*CreateProc)(); 2010bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor typedef void (*DeleteProc)(void*); 2110bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor 222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor /** 232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * If Get() has previously been called with this CreateProc, then this 242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * returns its cached data, otherwise it returns NULL. The CreateProc is 252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * never invoked in Find, it is only used as a key for searching the 262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * cache. 272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor */ 286e4750188e836e119f8605cbd34023d0a3b18011Chris Lattner static void* Find(CreateProc); 296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /** 316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines * Return the cached data that was returned by the CreateProc. This proc 326e4750188e836e119f8605cbd34023d0a3b18011Chris Lattner * is only called the first time Get is called, and there after it is 336e4750188e836e119f8605cbd34023d0a3b18011Chris Lattner * cached (per-thread), using the CreateProc as a key to look it up. 346e4750188e836e119f8605cbd34023d0a3b18011Chris Lattner * 356e4750188e836e119f8605cbd34023d0a3b18011Chris Lattner * When this thread, or Delete is called, the cached data is removed, and 362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * if a DeleteProc was specified, it is passed the pointer to the cached 372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * data. 382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor */ 392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor static void* Get(CreateProc, DeleteProc); 402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor /** 422f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * Remove (optionally calling the DeleteProc if it was specificed in Get) 432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * the cached data associated with this CreateProc. If no associated cached 442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * data is found, do nothing. 455f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner */ 465f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner static void Delete(CreateProc); 472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 482f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorprivate: 492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Our implementation requires only 1 TLS slot, as we manage multiple values 502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ourselves in a list, with the platform specific value as our head. 512f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 522f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor /** 532f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * Implemented by the platform, to return the value of our (one) slot per-thread 542f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * 552f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * If forceCreateTheSlot is true, then we must have created the "slot" for 562f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * our TLS, even though we know that the return value will be NULL in that 577c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall * case (i.e. no-slot and first-time-slot both return NULL). This ensures 5858f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner * that after calling GetSpecific, we know that we can legally call 597c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall * SetSpecific. 602f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor * 613201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl * If forceCreateTheSlot is false, then the impl can either create the 623201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl * slot or not. 633201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl */ 64d1a272204cef9304df3930d94f66713b05db27d6Douglas Gregor static void* PlatformGetSpecific(bool forceCreateTheSlot); 653201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl 66b1622a1fd7b7f4ab8d00d0183d17c90ad25c14e3John McCall /** 673201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl * Implemented by the platform, to set the value for our (one) slot per-thread 683201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl * 697abfbdbc97ad8e7f340789f751df1e32b10118b4Douglas Gregor * The implementation can rely on GetSpecific(true) having been previously 703201f6beec688ab9fe8750527e28f52d5420e22dSebastian Redl * called before SetSpecific is called. 717c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall */ 722c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson static void PlatformSetSpecific(void*); 732c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson 742c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlssonpublic: 752c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson /** 762c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson * Will delete our internal list. To be called by the platform if/when its 772c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson * TLS slot is deleted (often at thread shutdown). 782c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson * 792c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson * Public *only* for the platform's use, not to be called by a client. 802c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson */ 812c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson static void Destructor(void* ptr); 822c59d3c19715cb318a0a5939c735b8345d14d281Anders Carlsson}; 83b191e2dda9f4dc033cb21f9625a78fe80d4ac105Fariborz Jahanian 84b191e2dda9f4dc033cb21f9625a78fe80d4ac105Fariborz Jahanian#endif 85b191e2dda9f4dc033cb21f9625a78fe80d4ac105Fariborz Jahanian