| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE.md file. | |
| 4 | |
| 5 #include "platforms/stm/disco_fletch/src/circular_buffer.h" | |
| 6 | |
| 7 #include <stdlib.h> | |
| 8 #include <string.h> | |
| 9 | |
| 10 CircularBuffer::CircularBuffer(size_t capacity) { | |
| 11 monitor_ = fletch::Platform::CreateMonitor(); | |
| 12 // One additional byte needed to distinguish between empty and full. | |
| 13 capacity_ = capacity + 1; | |
| 14 buffer_ = new uint8_t[capacity_]; | |
| 15 head_ = tail_ = 0; | |
| 16 } | |
| 17 | |
| 18 CircularBuffer::~CircularBuffer() { | |
| 19 delete[] buffer_; | |
| 20 } | |
| 21 | |
| 22 bool CircularBuffer::IsEmpty() { | |
| 23 fletch::ScopedMonitorLock locker(monitor_); | |
| 24 return head_ == tail_; | |
| 25 } | |
| 26 | |
| 27 bool CircularBuffer::IsFull() { | |
| 28 fletch::ScopedMonitorLock locker(monitor_); | |
| 29 return ((head_ + 1) % capacity_) == tail_; | |
| 30 } | |
| 31 | |
| 32 size_t CircularBuffer::Read(uint8_t* data, size_t count, Blocking block) { | |
| 33 fletch::ScopedMonitorLock locker(monitor_); | |
| 34 | |
| 35 // If buffer is empty wait for data. | |
| 36 if (block == kBlock) { | |
| 37 if (head_ == tail_) { | |
| 38 monitor_->Wait(); | |
| 39 } | |
| 40 } | |
| 41 | |
| 42 int bytes; | |
| 43 int read = 0; | |
| 44 | |
| 45 if (tail_ > head_) { | |
| 46 bytes = MIN(capacity_ - tail_, count); | |
| 47 memcpy(data, buffer_ + tail_, bytes); | |
| 48 read = bytes; | |
| 49 tail_ = (tail_ + bytes) % capacity_; | |
| 50 } | |
| 51 | |
| 52 if (tail_ < head_) { | |
| 53 bytes = MIN(head_ - tail_, count - read); | |
| 54 memcpy(data + read, buffer_ + tail_, bytes); | |
| 55 read += bytes; | |
| 56 tail_ = (tail_ + bytes) % capacity_; | |
| 57 } | |
| 58 | |
| 59 monitor_->Notify(); | |
| 60 | |
| 61 return read; | |
| 62 } | |
| 63 | |
| 64 size_t CircularBuffer::Write( | |
| 65 const uint8_t* data, size_t count, Blocking block) { | |
| 66 fletch::ScopedMonitorLock locker(monitor_); | |
| 67 | |
| 68 // If buffer is full wait for room. | |
| 69 if (block == kBlock) { | |
| 70 if (((head_ + 1) % capacity_) == tail_) { | |
| 71 monitor_->Wait(); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 int bytes; | |
| 76 int written = 0; | |
| 77 | |
| 78 if (head_ >= tail_) { | |
| 79 bytes = (capacity_ - head_) - (tail_ == 0 ? 1 : 0); | |
| 80 bytes = MIN(bytes, count); | |
| 81 memcpy(buffer_ + head_, data, bytes); | |
| 82 written = bytes; | |
| 83 head_ = (head_ + bytes) % capacity_; | |
| 84 } | |
| 85 | |
| 86 if (head_ < tail_) { | |
| 87 bytes = MIN(tail_ - head_ - 1, count - written); | |
| 88 memcpy(buffer_ + head_, data + written, bytes); | |
| 89 written += bytes; | |
| 90 head_ = (head_ + bytes) % capacity_; | |
| 91 } | |
| 92 | |
| 93 monitor_->Notify(); | |
| 94 | |
| 95 return written; | |
| 96 } | |
| OLD | NEW |