aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/compute/skc/platforms/cl_12/handle_pool_cl_12.h
blob: 4fefae35521246ca89ef8338ea5e60d2289ca46e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can
 * be found in the LICENSE file.
 *
 */

#pragma once

//
//
//

#include "macros.h"
#include "handle.h"
#include "extent_cl_12.h"
#include "device_cl_12.h"

//
// FIXME -- THIS DOCUMENTATION IS STALE NOW THAT A REFERENCE COUNT REP
// IS A {HOST:DEVICE} PAIR.
//
// Host-side handle pool
//
// The bulk size of the three extents is currently 6 bytes of overhead
// per number of host handles.  The number of host handles is usually
// less than the number of blocks in the pool.  Note that the maximum
// number of blocks is 2^27.
//
// A practical instantiation might provide a combined 2^20 path and
// raster host handles. This would occupy 6 MB of host RAM for the
// 32-bit handle, 8-bit reference count and 8-bit handle-to-grid map.
//
// Also note that we could use isolated/separate path and raster block
// pools. Worst case, this would double the memory footprint of SKC.
//
// Host-side handle reference count
//
//   [0      ] : release
//   [1..UMAX] : retain
//
// In a garbage-collected environment we might want to rely on an
// existing mechanism for determing whether a handle is live.
//
// Otherwise, we probably want to have a 16 or 32-bit ref count.
//
// The handle reference count is defensive and will not allow the host
// to underflow a handle that's still retained by the pipeline.
//
// The single reference counter is split into host and device counts.
//

union skc_handle_refcnt
{
  skc_ushort  hd; // host and device

  struct {
    skc_uchar h;  // host
    skc_uchar d;  // device
  };
};

SKC_STATIC_ASSERT(SKC_MEMBER_SIZE(union skc_handle_refcnt,hd) ==
                  SKC_MEMBER_SIZE(union skc_handle_refcnt,h) +
                  SKC_MEMBER_SIZE(union skc_handle_refcnt,d));

//
//
//

struct skc_handle_bih
{
  skc_uint       block;
  skc_uint       rem;
  skc_handle_t * handles;
};

struct skc_handle_reclaim
{
  struct skc_handle_bih bih;

  cl_kernel             kernel;
  skc_device_kernel_id  kernel_id;
};

union skc_handle_reclaim_rec
{
  // ELEMENT  0
  struct skc_runtime * runtime;
  
  // ELEMENT  1
  struct {
    skc_uint           rem;   // # of available records
    skc_uint           head;  // index of first record
  };

  // ELEMENTS 2+
  struct {
    skc_uint           index; // index of this record -- never modified
    union {
      skc_uint         next;  // index of next record
      skc_uint         block; // block index of reclaimed handles
    };
  };
};

SKC_STATIC_ASSERT(sizeof(union skc_handle_reclaim_rec) == sizeof(skc_uint2));

//
//
//

typedef enum skc_handle_reclaim_type_e {

  SKC_HANDLE_RECLAIM_TYPE_PATH,
  SKC_HANDLE_RECLAIM_TYPE_RASTER,

  SKC_HANDLE_RECLAIM_TYPE_COUNT

} skc_handle_reclaim_type_e;

struct skc_handle_pool
{
  //
  // FIXME -- should we be pedantic and make these always-host-side
  // allocations "extents" as well?  I think it's OK not being an
  // extent structure for now and is mostly consistent with the rest
  // of the code.
  //
  // FIXME -- the cbs[] array is a little idiosyncratic but the intent
  // is to avoid storing the 64-bit backpointer inside of every single
  // record.  This can be harmonized later.  Note that only a few
  // hundred outstanding callbacks would represent many many subgroups
  // of work and would fully occupy the GPU (if we allow it).
  //
  //
  struct skc_extent_pdrw         map;     // device-managed extent mapping a host handle to device block id

  struct {
    skc_handle_t               * indices; // array of individual host handles -- fragmented into blocks
    union skc_handle_refcnt    * refcnts; // array of reference counts indexed by an individual handle
    skc_uint                     count;
  } handle;

  struct {
    skc_uint                   * indices; // stack of indices to fixed-size blocks of host handles
    skc_uint                     count;   // number of handles -- valid from [0,size)
    skc_uint                     width;   // width of a fixed-size block of handles
    skc_uint                     tos;     // grows upward   / push++ / --pop / # fixed-size blocks for reading
    skc_uint                     bos;     // grows downward / --push / pop++ / # fixed-size blocks for writing
  } block;

  union skc_handle_reclaim_rec * recs;    // array of reclaim records

  struct skc_handle_bih          acquire;
  struct skc_handle_reclaim      reclaim[SKC_HANDLE_RECLAIM_TYPE_COUNT];
};

//
//
//

void
skc_handle_pool_create(struct skc_runtime     * const runtime,
                       struct skc_handle_pool * const handle_pool,
                       skc_uint                 const size,
                       skc_uint                 const width,
                       skc_uint                 const recs);

void
skc_handle_pool_dispose(struct skc_runtime     * const runtime,
                        struct skc_handle_pool * const handle_pool);

//
//
//