Looks like I forgot the patch.

[EMAIL PROTECTED] wrote:
Hello Eddie,
   I have attached a minor patch to FromUserDevice.  The patch changes the
element to use an array of Packet pointers instead of using a slot based buffer.
 This eliminates one extra memory copy.

Roman
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click

diff --git a/elements/linuxmodule/fromuserdevice.cc 
b/elements/linuxmodule/fromuserdevice.cc
index c8b22f9..56832f5 100644
--- a/elements/linuxmodule/fromuserdevice.cc
+++ b/elements/linuxmodule/fromuserdevice.cc
@@ -65,7 +65,6 @@ FromUserDevice::FromUserDevice()
     _size = 0;
     _capacity = CAPACITY;
     _devname = DEV_NAME;
-    _slot_size = SLOT_SIZE; 
     _buff = 0;
     _r_slot = 0;
     _w_slot = 0;
@@ -77,6 +76,7 @@ FromUserDevice::FromUserDevice()
     _block_count = 0;
     _failed_count = 0;
     _exit = false;
+    _max = 0;
 }
 
 FromUserDevice::~FromUserDevice()
@@ -135,14 +135,13 @@ ssize_t FromUserDevice::dev_write (struct file *filp, 
const char *buf,
                              size_t count, loff_t *ppos)
 {
     FromUserDevice *elem = (FromUserDevice*)filp->private_data;
-    int          err;
-    struct slot *slot;
+    int             err;
+    WritablePacket *p;
     // there is a private field and that doesn't compile in C++ so we can't 
use DEFINE_WAIT macro
     wait_queue_t wq;
 #include <click/cxxprotect.h>
     init_wait(&wq);
 #include <click/cxxunprotect.h>
-    u_char      *temp_buff; 
     ulong        flags;
 
     //click_chatter("FromUserDevice_write %d\n", count);
@@ -151,34 +150,37 @@ ssize_t FromUserDevice::dev_write (struct file *filp, 
const char *buf,
         click_chatter("Empty private struct!\n");
         return -EIO;
     }
+    
+    // the incoming buffer is too big
+    if (count > SLOT_SIZE)
+    {
+        spin_lock_irqsave(&elem->_lock, flags);
+        elem->_drop_count++;
+        spin_unlock_irqrestore(&elem->_lock, flags);
+        click_chatter("Incoming buffer is bigger than current slot size\n");
+        return -EFAULT;
+    }
+    
     // we should make a copy_from_user here and not while we hold the spinlock
-    temp_buff = (u_char*)click_lalloc(SLOT_SIZE);
-    err = copy_from_user(temp_buff, buf, count);
+    p = WritablePacket::make(count);
+    err = copy_from_user((char*)p->data(), buf, count);
     if (err != 0)
     {
-        click_lfree(temp_buff, SLOT_SIZE);
+        p->kill();
+        spin_lock_irqsave(&elem->_lock, flags);
         elem->_failed_count++;
+        spin_unlock_irqrestore(&elem->_lock, flags);
         click_chatter("Write Fault");
         return -EFAULT;
     }
 
     spin_lock_irqsave(&elem->_lock, flags);
-    // the incoming buffer is too big
-    if (count > elem->_slot_size)
-    {
-        elem->_drop_count++;
-
-        spin_unlock_irqrestore(&elem->_lock, flags);
-        click_lfree(temp_buff, SLOT_SIZE);
-        click_chatter("Incoming buffer is bigger than current slot size\n");
-        return -EFAULT;
-    }
     while(1)
     {
         if (elem->_exit)
         {
             spin_unlock_irqrestore(&elem->_lock, flags);
-            click_lfree(temp_buff, SLOT_SIZE);
+            p->kill();
             return -EIO;
         }
         if (elem->_size >= elem->_capacity)
@@ -191,27 +193,26 @@ ssize_t FromUserDevice::dev_write (struct file *filp, 
const char *buf,
             prepare_to_wait(&elem->_proc_queue, &wq, TASK_INTERRUPTIBLE);
             schedule();
             finish_wait(&elem->_proc_queue, &wq);
-           if (elem->_exit)
-               return -EIO;
+            if (elem->_exit)
+                return -EIO;
             spin_lock_irqsave(&elem->_lock, flags);
             elem->_sleep_proc--;
         }
         else
             break; // we are sure that size is not zero so continue now
     }
-    slot = elem->_buff + elem->_w_slot;
-    slot->size = count;
-    // copy from our temp buff into the ring buffer
-    memcpy(slot->buff, temp_buff, count);
+    // put the packet pointer into the buffer
+    elem->_buff[elem->_w_slot] = p;
+
     elem->_w_slot = (elem->_w_slot + 1) % elem->_capacity;
     elem->_size++;
     elem->_write_count++;
-
+    if (elem->_size > elem->_max)
+        elem->_max = elem->_size;
     //click_ip  *ip = (click_ip*)slot->buff;
     //click_chatter("%x %x %d %d", ip->ip_src.s_addr, ip->ip_dst.s_addr,
     //              ip->ip_v, ip->ip_hl);
     spin_unlock_irqrestore(&elem->_lock, flags);
-    click_lfree(temp_buff, SLOT_SIZE);
     return count;
 }
 
@@ -232,7 +233,7 @@ int FromUserDevice::configure(Vector<String> &conf, 
ErrorHandler *errh)
         return -1;
 
     spin_lock_init(&_lock);
-    if (!(_buff = (struct slot*)click_lalloc(_capacity * sizeof(struct slot))))
+    if (!(_buff = (WritablePacket**)click_lalloc(_capacity * 
sizeof(WritablePacket**))))
     {
         click_chatter("FromUserDevice Failed to alloc %lu slots\n", _capacity);
         return -1;
@@ -251,7 +252,7 @@ int FromUserDevice::configure(Vector<String> &conf, 
ErrorHandler *errh)
         {
             click_chatter("Failed to Register Dev:%s Major:%d Minor:%d\n", 
                 DEV_NAME, _dev_major, _dev_minor);
-            click_lfree((char*)_buff, _capacity * sizeof(struct slot));
+            click_lfree((char*)_buff, _capacity * sizeof(WritablePacket**));
             _buff = 0;
             return - EIO;
         }
@@ -294,26 +295,16 @@ int FromUserDevice::initialize(ErrorHandler *errh)
 Packet* FromUserDevice::pull(int)
 {
     WritablePacket *p = 0;
-    struct slot    *slot;
     ulong           flags;
 
     spin_lock_irqsave(&_lock, flags);
-    click_ip       *ip;
-    struct sk_buff *skb;
 
     if (_size)
     {
-        slot = _buff + _r_slot;
+        p = _buff[_r_slot];
         _r_slot = (_r_slot + 1) % _capacity;
         _size--;
 
-        p = Packet::make(slot->size);
-
-        memcpy(p->data(), slot->buff, slot->size);
-        /*ip = (click_ip*)(p->data());
-        p->timestamp_anno().set_now();
-        p->set_dst_ip_anno(ip->ip_dst);
-        p->set_ip_header(ip, sizeof(click_ip));*/
         // output the packet
 
         //click_chatter("%x %x %d %d", ip->ip_src.s_addr, ip->ip_dst.s_addr,
@@ -349,12 +340,12 @@ void FromUserDevice::cleanup(CleanupStage)
         if (!DEV_NUM)
             unregister_chrdev(_dev_major, DEV_NAME);
         // now clear out the memory
-        click_lfree((char*)_buff, _capacity * sizeof(struct slot));
+        click_lfree((char*)_buff, _capacity * sizeof(WritablePacket**));
     }  
 }
 
 enum { H_COUNT, H_DROPS, H_WRITE_CALLS, H_CAPACITY,
-       H_SLOT_SIZE, H_SIZE, H_BLOCK, H_FAILED };
+       H_SLOT_SIZE, H_SIZE, H_BLOCK, H_FAILED, H_MAX };
 
 String FromUserDevice::read_handler(Element *e, void *thunk)
 {
@@ -369,7 +360,7 @@ String FromUserDevice::read_handler(Element *e, void *thunk)
         case H_DROPS:       return String(c->_drop_count);
         case H_WRITE_CALLS: return String(c->_write_count);
         case H_CAPACITY:    return String(c->_capacity);
-        case H_SLOT_SIZE:   return String(c->_slot_size);
+        case H_MAX:         return String(c->_max);
         default:            return "<error>";
     }
 }
@@ -384,6 +375,7 @@ void FromUserDevice::add_handlers()
     add_read_handler("writes", read_handler, (void *)H_WRITE_CALLS);
     add_read_handler("capacity", read_handler, (void *)H_CAPACITY);
     add_read_handler("slot_size", read_handler, (void *)H_SLOT_SIZE);
+    add_read_handler("max", read_handler, (void *)H_MAX);
 }
 
 
diff --git a/elements/linuxmodule/fromuserdevice.hh 
b/elements/linuxmodule/fromuserdevice.hh
index 6e37407..d2c91e8 100644
--- a/elements/linuxmodule/fromuserdevice.hh
+++ b/elements/linuxmodule/fromuserdevice.hh
@@ -78,26 +78,20 @@ class FromUserDevice : public Element
     static uint    dev_poll(struct file *, struct poll_table_struct *);
 
 private:
-    struct slot
-    {
-        uint32_t size;
-        u_char   buff[SLOT_SIZE];
-    };
-
-    String          _devname;
-    ulong           _size;
-    struct slot    *_buff;
-    ulong           _slot_size;
-    ulong           _r_slot; // where we read from
-    ulong           _w_slot; // where we write to
-    ulong           _capacity;
-    spinlock_t      _lock;
-    ulong           _write_count;
-    ulong           _drop_count;
-    ulong           _pkt_count;
-    ulong           _block_count;
-    atomic_uint32_t _failed_count;
-    bool            _exit;
+    String           _devname;
+    ulong            _size;
+    WritablePacket **_buff;
+    ulong            _r_slot; // where we read from
+    ulong            _w_slot; // where we write to
+    ulong            _capacity;
+    spinlock_t       _lock;
+    ulong            _write_count;
+    ulong            _drop_count;
+    ulong            _pkt_count;
+    ulong            _block_count;
+    ulong            _max;
+    ulong            _failed_count;
+    bool             _exit;
 
     // related to the device management
     ulong                  _sleep_proc;
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click

Reply via email to