* tsd_set - set thread specific data * @key: lookup key * @value: value to set * * Caller must prevent racing tsd_create() or tsd_destroy(), protected * from racing tsd_get() or tsd_set() because it is thread specific. * This function has been optimized to be fast for the update case. * When setting the tsd initially it will be slower due to additional * required locking and potential memo
| 456 | * required locking and potential memory allocations. |
| 457 | */ |
| 458 | int |
| 459 | tsd_set(uint_t key, void *value) |
| 460 | { |
| 461 | tsd_hash_table_t *table; |
| 462 | tsd_hash_entry_t *entry; |
| 463 | pid_t pid; |
| 464 | int rc; |
| 465 | /* mark remove if value is NULL */ |
| 466 | boolean_t remove = (value == NULL); |
| 467 | |
| 468 | table = tsd_hash_table; |
| 469 | pid = curthread->pid; |
| 470 | ASSERT3P(table, !=, NULL); |
| 471 | |
| 472 | if ((key == 0) || (key > TSD_KEYS_MAX)) |
| 473 | return (EINVAL); |
| 474 | |
| 475 | /* Entry already exists in hash table update value */ |
| 476 | entry = tsd_hash_search(table, key, pid); |
| 477 | if (entry) { |
| 478 | entry->he_value = value; |
| 479 | /* remove the entry */ |
| 480 | if (remove) |
| 481 | tsd_remove_entry(entry); |
| 482 | return (0); |
| 483 | } |
| 484 | |
| 485 | /* don't create entry if value is NULL */ |
| 486 | if (remove) |
| 487 | return (0); |
| 488 | |
| 489 | /* Add a process entry to the hash if not yet exists */ |
| 490 | entry = tsd_hash_search(table, PID_KEY, pid); |
| 491 | if (entry == NULL) { |
| 492 | rc = tsd_hash_add_pid(table, pid); |
| 493 | if (rc) |
| 494 | return (rc); |
| 495 | } |
| 496 | |
| 497 | rc = tsd_hash_add(table, key, pid, value); |
| 498 | return (rc); |
| 499 | } |
| 500 | EXPORT_SYMBOL(tsd_set); |
| 501 | |
| 502 | /* |
no test coverage detected