Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  threads.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#include "threads.h"
#include "machine.h"
#include "thread.h"

static struct threads_table_entry *threads__table(struct threads *threads, pid_t tid)
{
 /* Cast it to handle tid == -1 */
 return &threads->table[(unsigned int)tid % THREADS__TABLE_SIZE];
}

static size_t key_hash(long key, void *ctx __maybe_unused)
{
 /* The table lookup removes low bit entropy, but this is just ignored here. */
 return key;
}

static bool key_equal(long key1, long key2, void *ctx __maybe_unused)
{
 return key1 == key2;
}

void threads__init(struct threads *threads)
{
 for (int i = 0; i < THREADS__TABLE_SIZE; i++) {
  struct threads_table_entry *table = &threads->table[i];

  hashmap__init(&table->shard, key_hash, key_equal, NULL);
  init_rwsem(&table->lock);
  table->last_match = NULL;
 }
}

void threads__exit(struct threads *threads)
{
 threads__remove_all_threads(threads);
 for (int i = 0; i < THREADS__TABLE_SIZE; i++) {
  struct threads_table_entry *table = &threads->table[i];

  hashmap__clear(&table->shard);
  exit_rwsem(&table->lock);
 }
}

size_t threads__nr(struct threads *threads)
{
 size_t nr = 0;

 for (int i = 0; i < THREADS__TABLE_SIZE; i++) {
  struct threads_table_entry *table = &threads->table[i];

  down_read(&table->lock);
  nr += hashmap__size(&table->shard);
  up_read(&table->lock);
 }
 return nr;
}

/*
 * Front-end cache - TID lookups come in blocks,
 * so most of the time we dont have to look up
 * the full rbtree:
 */

static struct thread *__threads_table_entry__get_last_match(struct threads_table_entry *table,
           pid_t tid)
{
 struct thread *th, *res = NULL;

 th = table->last_match;
 if (th != NULL) {
  if (thread__tid(th) == tid)
   res = thread__get(th);
 }
 return res;
}

static void __threads_table_entry__set_last_match(struct threads_table_entry *table,
        struct thread *th)
{
 thread__put(table->last_match);
 table->last_match = thread__get(th);
}

static void threads_table_entry__set_last_match(struct threads_table_entry *table,
      struct thread *th)
{
 down_write(&table->lock);
 __threads_table_entry__set_last_match(table, th);
 up_write(&table->lock);
}

struct thread *threads__find(struct threads *threads, pid_t tid)
{
 struct threads_table_entry *table  = threads__table(threads, tid);
 struct thread *res;

 down_read(&table->lock);
 res = __threads_table_entry__get_last_match(table, tid);
 if (!res) {
  if (hashmap__find(&table->shard, tid, &res))
   res = thread__get(res);
 }
 up_read(&table->lock);
 if (res)
  threads_table_entry__set_last_match(table, res);
 return res;
}

struct thread *threads__findnew(struct threads *threads, pid_t pid, pid_t tid, bool *created)
{
 struct threads_table_entry *table  = threads__table(threads, tid);
 struct thread *res = NULL;

 *created = false;
 down_write(&table->lock);
 res = thread__new(pid, tid);
 if (res) {
  if (hashmap__add(&table->shard, tid, res)) {
   /* Add failed. Assume a race so find other entry. */
   thread__put(res);
   res = NULL;
   if (hashmap__find(&table->shard, tid, &res))
    res = thread__get(res);
  } else {
   res = thread__get(res);
   *created = true;
  }
  if (res)
   __threads_table_entry__set_last_match(table, res);
 }
 up_write(&table->lock);
 return res;
}

void threads__remove_all_threads(struct threads *threads)
{
 for (int i = 0; i < THREADS__TABLE_SIZE; i++) {
  struct threads_table_entry *table = &threads->table[i];
  struct hashmap_entry *cur, *tmp;
  size_t bkt;

  down_write(&table->lock);
  __threads_table_entry__set_last_match(table, NULL);
  hashmap__for_each_entry_safe(&table->shard, cur, tmp, bkt) {
   struct thread *old_value;

   hashmap__delete(&table->shard, cur->key, /*old_key=*/NULL, &old_value);
   thread__put(old_value);
  }
  up_write(&table->lock);
 }
}

void threads__remove(struct threads *threads, struct thread *thread)
{
 struct threads_table_entry *table  = threads__table(threads, thread__tid(thread));
 struct thread *old_value;

 down_write(&table->lock);
 if (table->last_match && RC_CHK_EQUAL(table->last_match, thread))
  __threads_table_entry__set_last_match(table, NULL);

 hashmap__delete(&table->shard, thread__tid(thread), /*old_key=*/NULL, &old_value);
 thread__put(old_value);
 up_write(&table->lock);
}

int threads__for_each_thread(struct threads *threads,
        int (*fn)(struct thread *thread, void *data),
        void *data)
{
 for (int i = 0; i < THREADS__TABLE_SIZE; i++) {
  struct threads_table_entry *table = &threads->table[i];
  struct hashmap_entry *cur;
  size_t bkt;

  down_read(&table->lock);
  hashmap__for_each_entry(&table->shard, cur, bkt) {
   int rc = fn((struct thread *)cur->pvalue, data);

   if (rc != 0) {
    up_read(&table->lock);
    return rc;
   }
  }
  up_read(&table->lock);
 }
 return 0;

}

Messung V0.5
C=97 H=90 G=93

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge