mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-15 07:27:42 -04:00
Protect correctly packet reception
This commit is contained in:
parent
f815e67033
commit
966e8422f0
100
kernel/include/conc/deferred_unique_semaphore.hpp
Normal file
100
kernel/include/conc/deferred_unique_semaphore.hpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
//=======================================================================
|
||||||
|
// Copyright Baptiste Wicht 2013-2016.
|
||||||
|
// Distributed under the terms of the MIT License.
|
||||||
|
// (See accompanying file LICENSE or copy at
|
||||||
|
// http://www.opensource.org/licenses/MIT)
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
#ifndef DEFERRED_UNIQUE_SEMAPHORE_H
|
||||||
|
#define DEFERRED_UNIQUE_SEMAPHORE_H
|
||||||
|
|
||||||
|
#include "conc/int_lock.hpp"
|
||||||
|
|
||||||
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief A deferred unique semaphore lock implementation.
|
||||||
|
*
|
||||||
|
* This must be used when the notifier is an IRQ handler.
|
||||||
|
*
|
||||||
|
* Once the lock is acquired, the critical section is only accessible by the
|
||||||
|
* thread who acquired the mutex.
|
||||||
|
*/
|
||||||
|
struct deferred_unique_semaphore {
|
||||||
|
/*!
|
||||||
|
* \brief Claim the mutex
|
||||||
|
*/
|
||||||
|
void claim() {
|
||||||
|
this->pid = scheduler::get_pid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Wait for the lock
|
||||||
|
*/
|
||||||
|
void wait() {
|
||||||
|
int_lock lock;
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
if (value > 0) {
|
||||||
|
--value;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
} else {
|
||||||
|
waiting = true;
|
||||||
|
|
||||||
|
scheduler::block_process_light(pid);
|
||||||
|
lock.unlock();
|
||||||
|
scheduler::reschedule();
|
||||||
|
|
||||||
|
waiting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Release the lock, from an IRQ handler.
|
||||||
|
*/
|
||||||
|
void notify() {
|
||||||
|
if (!waiting) {
|
||||||
|
++value;
|
||||||
|
} else {
|
||||||
|
scheduler::unblock_process_hint(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Release the lock, from a preeemptible process
|
||||||
|
*/
|
||||||
|
void pt_notify() {
|
||||||
|
direct_int_lock lock;
|
||||||
|
|
||||||
|
if (!waiting) {
|
||||||
|
++value;
|
||||||
|
} else {
|
||||||
|
scheduler::unblock_process_hint(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Release the lock several times, from an IRQ
|
||||||
|
*/
|
||||||
|
void notify(size_t n) {
|
||||||
|
if (!waiting) {
|
||||||
|
value += n;
|
||||||
|
} else {
|
||||||
|
scheduler::unblock_process_hint(pid);
|
||||||
|
--n;
|
||||||
|
|
||||||
|
if (n) {
|
||||||
|
value += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t pid = 0; ///< The claimed pid
|
||||||
|
volatile size_t value = 0; ///< The value of the mutex
|
||||||
|
volatile bool waiting = false; ///< Indicates if the process is waiting
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -8,9 +8,6 @@
|
|||||||
#ifndef NETWORK_H
|
#ifndef NETWORK_H
|
||||||
#define NETWORK_H
|
#define NETWORK_H
|
||||||
|
|
||||||
#include <conc/mutex.hpp>
|
|
||||||
#include <conc/semaphore.hpp>
|
|
||||||
|
|
||||||
#include <types.hpp>
|
#include <types.hpp>
|
||||||
#include <string.hpp>
|
#include <string.hpp>
|
||||||
#include <circular_buffer.hpp>
|
#include <circular_buffer.hpp>
|
||||||
@ -18,6 +15,10 @@
|
|||||||
#include <tuple.hpp>
|
#include <tuple.hpp>
|
||||||
#include <expected.hpp>
|
#include <expected.hpp>
|
||||||
|
|
||||||
|
#include <conc/mutex.hpp>
|
||||||
|
#include <conc/semaphore.hpp>
|
||||||
|
#include <conc/deferred_unique_semaphore.hpp>
|
||||||
|
|
||||||
#include "tlib/net_constants.hpp"
|
#include "tlib/net_constants.hpp"
|
||||||
|
|
||||||
#include "net/ethernet_packet.hpp"
|
#include "net/ethernet_packet.hpp"
|
||||||
@ -42,7 +43,7 @@ struct interface_descriptor {
|
|||||||
|
|
||||||
mutable mutex tx_lock; ///< Mutex protecting the queues
|
mutable mutex tx_lock; ///< Mutex protecting the queues
|
||||||
mutable semaphore tx_sem; ///< Semaphore for transmission
|
mutable semaphore tx_sem; ///< Semaphore for transmission
|
||||||
mutable semaphore rx_sem; ///< Semaphore for reception
|
mutable deferred_unique_semaphore rx_sem; ///< Semaphore for reception
|
||||||
|
|
||||||
size_t rx_thread_pid; ///< The pid of the rx thread
|
size_t rx_thread_pid; ///< The pid of the rx thread
|
||||||
size_t tx_thread_pid; ///< The pid of the tx thread
|
size_t tx_thread_pid; ///< The pid of the tx thread
|
||||||
|
@ -30,7 +30,7 @@ void send_packet(network::interface_descriptor& interface, network::ethernet::pa
|
|||||||
std::copy_n(packet.payload, packet.payload_size, packet_buffer);
|
std::copy_n(packet.payload, packet.payload_size, packet_buffer);
|
||||||
|
|
||||||
interface.rx_queue.emplace_push(packet_buffer, packet.payload_size);
|
interface.rx_queue.emplace_push(packet_buffer, packet.payload_size);
|
||||||
interface.rx_sem.unlock();
|
interface.rx_sem.pt_notify();
|
||||||
|
|
||||||
logging::logf(logging::log_level::TRACE, "loopback: Packet transmitted correctly\n");
|
logging::logf(logging::log_level::TRACE, "loopback: Packet transmitted correctly\n");
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ void packet_handler(interrupt::syscall_regs*, void* data){
|
|||||||
network::ethernet::packet packet(packet_buffer, packet_only_length);
|
network::ethernet::packet packet(packet_buffer, packet_only_length);
|
||||||
|
|
||||||
interface.rx_queue.push(packet);
|
interface.rx_queue.push(packet);
|
||||||
interface.rx_sem.irq_unlock();
|
interface.rx_sem.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_rx = (cur_rx + packet_length + 4 + 3) & ~3; //align on 4 bytes
|
cur_rx = (cur_rx + packet_length + 4 + 3) & ~3; //align on 4 bytes
|
||||||
@ -196,7 +196,7 @@ void send_packet(network::interface_descriptor& interface, network::ethernet::pa
|
|||||||
direct_int_lock lock;
|
direct_int_lock lock;
|
||||||
|
|
||||||
interface.rx_queue.emplace_push(packet_buffer, packet.payload_size);
|
interface.rx_queue.emplace_push(packet_buffer, packet.payload_size);
|
||||||
interface.rx_sem.unlock();
|
interface.rx_sem.pt_notify();
|
||||||
|
|
||||||
logging::logf(logging::log_level::TRACE, "rtl8139: Packet to self transmitted correctly\n");
|
logging::logf(logging::log_level::TRACE, "rtl8139: Packet to self transmitted correctly\n");
|
||||||
|
|
||||||
|
@ -53,10 +53,12 @@ void rx_thread(void* data){
|
|||||||
|
|
||||||
auto pid = scheduler::get_pid();
|
auto pid = scheduler::get_pid();
|
||||||
|
|
||||||
|
interface.rx_sem.claim();
|
||||||
|
|
||||||
logging::logf(logging::log_level::TRACE, "network: RX Thread for interface %u started (pid:%u)\n", interface.id, pid);
|
logging::logf(logging::log_level::TRACE, "network: RX Thread for interface %u started (pid:%u)\n", interface.id, pid);
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
interface.rx_sem.lock();
|
interface.rx_sem.wait();
|
||||||
|
|
||||||
auto packet = interface.rx_queue.pop();
|
auto packet = interface.rx_queue.pop();
|
||||||
network::ethernet::decode(interface, packet);
|
network::ethernet::decode(interface, packet);
|
||||||
@ -158,7 +160,6 @@ void network::init(){
|
|||||||
|
|
||||||
interface.tx_lock.init(1);
|
interface.tx_lock.init(1);
|
||||||
interface.tx_sem.init(0);
|
interface.tx_sem.init(0);
|
||||||
interface.rx_sem.init(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sysfs_publish(interface);
|
sysfs_publish(interface);
|
||||||
@ -181,7 +182,6 @@ void network::init(){
|
|||||||
|
|
||||||
interface.tx_lock.init(1);
|
interface.tx_lock.init(1);
|
||||||
interface.tx_sem.init(0);
|
interface.tx_sem.init(0);
|
||||||
interface.rx_sem.init(0);
|
|
||||||
|
|
||||||
loopback::init_driver(interface);
|
loopback::init_driver(interface);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user