| 289 | } |
| 290 | |
| 291 | int |
| 292 | addKernelToCache( |
| 293 | struct KernelCache *kcache, |
| 294 | solver_id_t sid, |
| 295 | Kernel *kern, |
| 296 | const KernelKey *key, |
| 297 | KernelExtraCmpFn extraCmp) |
| 298 | { |
| 299 | size_t ksize; |
| 300 | KernelNode *knode; |
| 301 | ListHead truncList; |
| 302 | |
| 303 | knode = container_of(kern, kern, KernelNode); |
| 304 | assert(knode->magic == KNODE_MAGIC); |
| 305 | |
| 306 | if ((unsigned)sid >= kcache->nrSolvers || key->nrDims > MAX_SUBDIMS) { |
| 307 | return -1; |
| 308 | } |
| 309 | |
| 310 | listInitHead(&truncList); |
| 311 | ksize = fullKernelSize(kern); |
| 312 | |
| 313 | KCACHE_LOCK(kcache); |
| 314 | |
| 315 | if (kcache->sizeLimit) { |
| 316 | if (ksize > kcache->sizeLimit) { |
| 317 | KCACHE_UNLOCK(kcache); |
| 318 | return -1; |
| 319 | } |
| 320 | else if (ksize > kcache->sizeLimit - kcache->totalSize) { |
| 321 | removeKernels(&truncList, kcache, ksize * TRUNC_AHEAD_FACTOR); |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | knode->hash = kernHash(key->subdims, key->nrDims); |
| 326 | knode->extraCmp = extraCmp; |
| 327 | |
| 328 | knode->key.device = key->device; |
| 329 | knode->key.context = key->context; |
| 330 | clRetainContext(knode->key.context); |
| 331 | knode->key.nrDims = key->nrDims; |
| 332 | memset(knode->key.subdims, 0, sizeof(knode->key.subdims)); |
| 333 | memcpy(knode->key.subdims, key->subdims, sizeof(SubproblemDim) * |
| 334 | knode->key.nrDims); |
| 335 | |
| 336 | listAddToTail(&kcache->dimKern[sid], &knode->dimNode); |
| 337 | listAddToHead(&kcache->lruKern, &knode->lruNode); |
| 338 | kcache->totalSize += ksize; |
| 339 | |
| 340 | KCACHE_UNLOCK(kcache); |
| 341 | |
| 342 | if (!isListEmpty(&truncList)) { |
| 343 | putRemovedKernels(kcache, &truncList); |
| 344 | } |
| 345 | |
| 346 | return 0; |
| 347 | } |
| 348 | |