Ignore:
Timestamp:
Oct 12, 2001, 1:17:10 AM (24 years ago)
Author:
aubourg
Message:

* empty log message *

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ArchTOIPipe/Kernel/toisegment.cc

    r1671 r1686  
    11#include "toisegment.h"
    22
    3 
     3/*******************************/
    44/******* BufferSegment *********/
     5/*******************************/
     6
    57TOISegmented::BufferSegment::BufferSegment(int sz) {
    68  status     = NEW;
     
    2426  pthread_mutex_destroy(&refcount_mutex);
    2527}
    26 
    2728
    2829void TOISegmented::BufferSegment::putData(int sn, double d, uint_8 f) {
     
    6061}
    6162
     63
     64/*******************************/
     65/********** BufferView *********/
     66/*******************************/
     67
     68TOISegmented::BufferView::BufferView(MasterView* m) {
     69  master = m;
     70  sn0 = -1;
     71  segmentSize = m->segmentSize;
     72  pthread_mutex_init(&mutex, NULL);
     73  pthread_cond_init(&condv, NULL);
     74}
     75
     76TOISegmented::BufferView::~BufferView() {
     77  pthread_mutex_destroy(&mutex);
     78  pthread_cond_destroy(&condv);
     79}
     80
     81double TOISegmented::BufferView::getData(int sn) { /* Single-thread */
     82  ensure(sn);
     83  int seg = (sn-sn0)/segmentSize;
     84  return segments[seg]->getData(sn);
     85}
     86
     87uint_8 TOISegmented::BufferView::getFlag(int sn) { /* Single-thread */
     88  ensure(sn);
     89  int seg = (sn-sn0)/segmentSize;
     90  return segments[seg]->getFlag(sn);
     91}
     92
     93void  TOISegmented::BufferView::ensure(int sn) { /* Single-thread */
     94  if (sn < sn0) {
     95    throw RangeCheckError("requested sample before first");
     96  }
     97
     98  if (sn >= sn0 + segmentSize*segments.size()) {
     99    cout << "BufferView : read fault for " << sn << endl;
     100    sync();
     101    while (sn >= sn0 + segmentSize*segments.size()) {
     102      wait();
     103      cout << "BufferView : waiting for " << sn << endl;
     104      sync();
     105    }
     106    cout << "BufferView : resuming for " << sn << endl;   
     107  }
     108}
     109
     110void TOISegmented::BufferView::sync() { /* Single-thread */
     111  master->updateView(this); // update me !
     112}
     113
     114void TOISegmented::BufferView::wait() { /* From reader thread */
     115  pthread_mutex_lock(&mutex);
     116  master->addToWaitList(this); // needing wake-up call
     117  pthread_cond_wait(&condv, &mutex);
     118  pthread_mutex_unlock(&mutex);
     119}
     120
     121void TOISegmented::BufferView::signal() { /* From masterview, writer thread */
     122  pthread_mutex_lock(&mutex);
     123  pthread_cond_signal(&condv); // only one thread can be sleeping
     124  master->removeFromWaitList(this);
     125  pthread_mutex_unlock(&mutex); 
     126}
     127
     128
     129/*******************************/
     130/********** MasterView *********/
     131/*******************************/
     132
     133TOISegmented::MasterView::MasterView(int bufsz, int maxseg) {
     134  currentSegment = NULL;
     135  maxSegments    = maxseg;
     136  segmentSize    = bufsz;
     137  sn0            = -1;
     138 
     139  pthread_mutex_init(&views_mutex, NULL);
     140  pthread_mutex_init(&write_mutex, NULL);
     141  pthread_cond_init(&condv, NULL);
     142  pthread_key_create(&buffer_key, BufferDestroy);
     143
     144  waitStatus = NO_WAIT;
     145}
     146
     147TOISegmented::MasterView::~MasterView() {
     148  pthread_mutex_destroy(&views_mutex);
     149  pthread_mutex_destroy(&write_mutex);
     150  pthread_cond_destroy(&condv);
     151  pthread_key_delete(buffer_key);
     152
     153  // There should not be any BufferView left... Check ?
     154 
     155  // decrement count for segments ?
     156}
     157
     158void TOISegmented::MasterView::putData(int sn, double data, uint_8 flags) {
     159  // can fit in current segment ?
     160  if (!(currentSegment != NULL &&
     161        sn >= currentSegment->sn0 &&
     162        sn < currentSegment->sn0 + currentSegment->bufferSize)) {
     163    nextSegment();
     164  }
     165  currentSegment->putData(sn, data, flags);
     166}
     167
     168double TOISegmented::MasterView::getData(int sn) {
     169  return getView()->getData(sn);
     170}
     171
     172uint_8 TOISegmented::MasterView::getFlag(int sn) {
     173  return getView()->getFlag(sn);
     174}
     175
     176void TOISegmented::MasterView::addToWaitList(BufferView* bv) { /* reader thread */
     177  // A view needs to wait for new data.
     178
     179  // There is a possible deadlock if no view can free old segments
     180  // and we are waiting for write.
     181
     182  // we need to record "wont need before" for each view, and
     183  // signal deadlock if any view that needs first segment data is sleeping
     184  // while we are asleep
     185
     186  pthread_mutex_lock(&views_mutex);
     187  waitingBuffers.insert(bv);
     188  pthread_mutex_unlock(&views_mutex);
     189  checkDeadLock();
     190}
     191
     192void TOISegmented::MasterView::removeFromWaitList(BufferView* bv) { /* reader thread */
     193  pthread_mutex_lock(&views_mutex);
     194  waitingBuffers.erase(bv);
     195  pthread_mutex_unlock(&views_mutex); 
     196}
     197
     198TOISegmented::BufferView* TOISegmented::MasterView::getView() { /* reader thread */
     199  BufferView* bv = (BufferView*) pthread_getspecific(buffer_key);
     200  if (bv == NULL) {
     201    bv = createView();
     202    pthread_setspecific(buffer_key, bv);
     203  }
     204  return bv;
     205}
Note: See TracChangeset for help on using the changeset viewer.