[Xen-devel] New Outreachy Applicant

2016-09-13 Thread Ronald Rojas
Hi, I'm Ronald Rojas an undergraduate junior studying 
computer science at New York Unversity. I would like
to apply fo the Xen projects Outreachy Program. After
looking through the available projects I think I would 
be a good fit for creating the golang bindings for 
libxl. I'm proficient in C , familar with Golang, and 
very comfortable with linux. Would I be able to get a 
bit-sized task for the application process? 

Thank you, 
Ronald Rojas


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] New Outreachy Applicant

2016-10-02 Thread Ronald Rojas
On Tue, Sep 20, 2016 at 04:24:47PM +0100, George Dunlap wrote:
> Thanks for your interest in the Xen Project!  Sorry for the delay in
> responding -- somehow your mail either never made it to my personal
> inbox or I accidentally deleted it instead of filing it properly.  I
> saw your question on IRC and now found your mail here on xen-devel.
> 
> First, I want to emphasize that Outreachy internships should be
> considered a full-time job.  As part of the application process you
> will be asked to confirm that you will not be taking any classes, nor
> have any other significant commitments (such as another job) during
> the period of the internship.

I'll confirm now that won't be taking any classes or working during the
majority of the program, however the fall semester for my college will
end around the 20th of December. 
> 
> Now on to the bite-sized task.  We've actually found that one of the
> difficult parts of getting going with our project is making sure that
> you understand how to get your whole system and environment set up.
> And another thing we want to see is to what degree you can balance
> figuring things out, finding the answers on the web, and asking for
> help when you need it.
> 
> So with that in mind, we've started experimenting with tasks which
> don't contribute very much to the project directly, but provide a
> really solid base of knowledge to do further contributions.
> 
> So here's my challenge for you.
> 
> ---
> OUTCOME
> 
> Write a simple go program that will list the current cpu pools,
> similar to the output of "xl cpupool-list".  No need to handle extra
> arguments or modify libxl.go (beyond what may be needed to compile it).

RESULTS:
I've managed to get xen running on my local machine. I am running linux natively
on ubuntu with xen 4.8-unstable and it is running reasonable well.
There are two VM's running on my computer, one is named tutorial-pv-guest that I
created by following the xen beginners guide. The other is called ubuntu1 and
was created through a custom configuration file that I created. I wasn't having
much luck with the outreachy tutorial provided so after some googling the link 
below really helped me get through the process.

http://www.virtuatopia.com/index.php/Building_a_Xen_Guest_Domain_using_Xen-Tools

> 
> Please post a copy of your .go program, along with the results of
> output *when more than one VM is running*.

The output when I run "sudo go run libxl.go" is pasted below. The output was 
made 
when the two VM's mentioned above were running. It prints out the appropiate 
output for Pool Name, Scheduler, and Domain Count. 
All the changes in libxl.go are contained within the main() method and the 
libxl.go
file is pasted below as well.


CONCERNS/QUESTIONS:
I believe I was only able to print out the information for Name, Sched, and 
Domain 
count because the other information such as Active and CPU's are not stored 
within
CpupoolInfo. Was there a way I could obtain that information? I don't think the 
code privided had that functionality. Maybe the next task could be to add that 
functionality?
It also seems that Domain Count is off. The command "xl cpupool-list" lists 3 
domains
(which are Dom0, tutorial-pv-guest, and ubuntu1) but my program returns 11 
domains. 
Would you like me to look into the issue? I'm using the information called from 
Ctx.ListCpupool() so I may have to take a closer look at that code. 

Thank You!
Ronald Rojas
NameSched   Domain count
Pool-0  credit  11
/*
 * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License only.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
package main

/*
#cgo LDFLAGS: -lyajl -lxenlight
#include 
#include 
*/
import "C"

import (
"unsafe"
"fmt"
"time"
)

type Context struct {
ctx *C.libxl_ctx
}

var Ctx Context

func (Ctx *Context) IsOpen() bool {
return Ctx.ctx != nil
}

func (Ctx *Context) Open() (err error) {
if Ctx.ctx != nil {
return
}

ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIB

Re: [Xen-devel] New Outreachy Applicant

2016-10-06 Thread Ronald Rojas
On Wed, Oct 05, 2016 at 06:44:08PM +0100, George Dunlap wrote:
> On Tue, Oct 4, 2016 at 3:23 PM, George Dunlap  
> wrote:
> > Thanks for this -- if you're up for it, let me see what kinds of next
> > steps you can do (obviously when you have the opportunity).
> 
> So there are a couple of things we could do next.
> 
> * If you want a simple change that you can use to get experience with
> sending patches to the list:
> 
> There are a number of instances in tools/libxl/xl_cmdimpl.c where
> where domid is listed as uint32_t (or libxl_domid), but the printf
> specifier is used as '%d'.  Change this to '%u'.
> 
> * If you want an investigation to do:
> 
> At least a couple of times I've accidentally run a golang program with
> libxl functionality on a system that wasn't running Xen (i.e., I'd
> rebooted onto Linux baremetal).  Instead of throwing an error, as you
> would expect, it crashed with a SEGV.
> 
> Try to reproduce this bug, and see if you can fix it.
> 
> * If you want to dive into the project:
> 
> I can send you my most recent version of libxl.go (which has a few
> more things implemented).  Modify it so that it builds as a package (I
> think "xenproject.org/xenlight" is probably the best name), and wire
> it into the build system in tools/golang/xenlight, and installs into
> $prefix/share/gocode/src/xenproject.org/.
> 
> The key thing with the last one is not to get too bogged down in
> systems you're not familiar with -- if you get stuck ask for help
> relatively quickly; and if it's turning into a mess, I can just do the
> Makefile side of things so that you can get to the actual Go side of
> the project.
> 
> What do you think?

I think I would prefer to do the first task and then the last task. I 
have not used stgit so I think it would be beneficial to do that first
and then I can dive into the project. 
I will probably do the first task on either Sunday or Monday, depending
on when I can start working on it. The packaging task seems much more 
difficult and I really only have a significant amount of time to work 
on this during the weekend, so it'll probably take 1 or 2 more weeks 
to complete that. 
In the meantime I think it would be helpful to look at the makefile 
of another subproject from xen so I could get some inspiration on how 
structure this new project. Is there any Makefile that you think I 
should look at? If not I'll just read through a couple of files in xen
and try to follow a similar style. 

Does that sound like a good plan?
 
Ronald Rojas

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC 59/59] tools/xenlight: Create interface for xenlight info

2017-01-03 Thread Ronald Rojas
On Thu, Dec 29, 2016 at 01:45:54PM +, George Dunlap wrote:
> Hey Ronald!  Looks like you're getting going pretty well here.
> 
> At a high level: I think I began by saying that this would probably all
> be a single patch.  But I think it would probably be easier to review
> the different decisions made at each point by filling out the file bit
> by bit, and explaining what's going on at each point.
> 
> I think also it would be helpful to have somewhere -- either in a
> comment or in a text file -- a description of the general approach to
> converting the libxl C style into xenlight golang style.  For instance,
> saying that for functions, we'll take the function name
> (libxl_cpupool_remove), remove the libxl_ prefix (since the packages are
> namespaced already) and convert it to CamelCase by capitalizing the first
> 
> I'll take a stab at breaking it down in an example order that makes some
> sense to me, and then you can see what you think.

I made some guidelines that I think would nicely adjust the naming convention
from C to Go. I'll add it as a file below.
> 
> Futher comments...
> 
> On 29/12/16 01:14, Ronald Rojas wrote:
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > new file mode 100644
> > index 000..b0eb6f8
> > --- /dev/null
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -0,0 +1,1000 @@
> > +/*
> > + * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; version 2 of the
> > + * License only.
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> > + * 02110-1301, USA.
> > + */
> > +package xenlight
> > +
> > +/*
> > +#cgo LDFLAGS: -lxenlight -lyajl
> > +#include 
> > +#include 
> > +*/
> > +import "C"
> 
> I see you switched back to dynamic linking -- any particular reason?
> 
> We probably need to put a "// FIXME" here saying that we need to
> generate these compile-time dependencies using pkg-config.

We discussed this on IRC but I'll just restate here that I was not able 
to compile the program through static linking and it would be fine to 
just use dynamic linking for now.
Since we are doing dynamic linking do we still need to use pkg-config?
> 
> > +
> > +/*
> > + * Other flags that may be needed at some point:
> > + *  -lnl-route-3 -lnl-3
> > +#cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
> > -lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall 
> > -lz -luuid -lutil
> > + *
> > + * To get back to simple dynamic linking:
> > +*/
> 
> Comment needs updating (to "To use static linking").

Fixed.
> 
> > +
> > +import (
> > +   "fmt"
> > +   "time"
> > +   "unsafe"
> > +)
> > +
> > +/*
> > + * Errors
> > + */
> > +const (
> > +   ErrorNonspecific  = int(C.ERROR_NONSPECIFIC)
> > +   ErrorVersion  = int(C.ERROR_VERSION)
> > +   ErrorFail = int(C.ERROR_FAIL)
> > +   ErrorNi   = int(C.ERROR_NI)
> > +   ErrorNomem= int(C.ERROR_NOMEM)
> > +   ErrorInval= int(C.ERROR_INVAL)
> > +   ErrorBadfail  = int(C.ERROR_BADFAIL)
> > +   ErrorGuestTimedout= int(C.ERROR_GUEST_TIMEDOUT)
> > +   ErrorTimedout = int(C.ERROR_TIMEDOUT)
> > +   ErrorNoparavirt   = int(C.ERROR_NOPARAVIRT)
> > +   ErrorNotReady = int(C.ERROR_NOT_READY)
> > +   ErrorOseventRegFail   = int(C.ERROR_OSEVENT_REG_FAIL)
> > +   ErrorBufferfull   = int(C.ERROR_BUFFERFULL)
> > +   ErrorUnknownChild = int(C.ERROR_UNKNOWN_CHILD)
> > +   ErrorLockFail = int(C.ERROR_LOCK_FAIL)
> > +   ErrorJsonConfigEmpty  = int(

[Xen-devel] libxl to json return string

2017-01-12 Thread Ronald Rojas
Hi,
I have an example attached below where I believe that libxl_physinfo_to_json() 
does not return all of the correct output. physinfo.c is the C program that 
outputs the json string. physc.out is the output that I recieved. physgo.out 
is the output I get using the golang bindings I'm creating for xenlight. 
The missing fields are :
scrub_pages, outstanding_pages, sharing_freed_pages,sharing_used_frames, 
the last 4 indices of hw_cap, cap_hvm, and cap_hvm_directio

I had a similar problem with libxl_dominfo_to_json() where some data fields
were not added to the string. 

It was said on the IRC channel that default values are not converted to json,
but is there a way to tell what is the default value for a data field?

Thanks!
Ronald Rojas
{
"threads_per_core": 1,
"cores_per_socket": 4,
"max_cpu_id": 3,
"nr_cpus": 4,
"cpu_khz": 3198157,
"total_pages": 4179453,
"free_pages": 32702,
"nr_nodes": 1,
"hw_cap": [
3085695999,
2012935103,
739248128,
33
]
}

{
"Threads_per_core": 1,
"Cores_per_socket": 4,
"Max_cpu_id": 3,
"Nr_cpus": 4,
"Cpu_khz": 3198157,
"Total_pages": 4179453,
"Free_pages": 32702,
"Scrub_pages": 0,
"Outstanding_pages": 0,
"Sharing_freed_pages": 0,
"Sharing_used_frames": 0,
"Nr_nodes": 1,
"Hw_cap": [
3085695999,
2012935103,
739248128,
33,
1,
10155,
0,
256
],
"Cap_hvm": false,
"Cap_hvm_directio": false
}
#include 
#include 
#include 

char * main(){

libxl_ctx *context;
libxl_ctx_alloc(&context,LIBXL_VERSION, 0, NULL);
libxl_physinfo info ;
int err= libxl_get_physinfo(context,&info );
if(err != 0){
 return NULL;
}



char * json= libxl_physinfo_to_json(context, &info);

libxl_ctx_free(context);
return json;

}
___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 4/8] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-01-18 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 91 +++
 1 file changed, 91 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 6b04850..1e25413 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -105,6 +105,12 @@ func (e Errorxl) Error() string {
 /*
  * Types: Builtins
  */
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -165,6 +171,32 @@ type VersionInfo struct {
BuildId string
 }
 
+type Dominfo struct {
+   Uuid  Uuid
+   Domid Domid
+   Ssidref   uint32
+   SsidLabel string
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   NeverStop bool
+
+   ShutdownReason   int32 // FIXME shutdown_reason enumeration
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxIduint32
+   VcpuOnline   uint32
+   Cpupool  uint32
+   DomainType   int32 //FIXME libxl_domain_type enumeration
+
+}
+
 /*
  * Context
  */
@@ -332,3 +364,62 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, 
err error) {
 
return
 }
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var cdi C.libxl_dominfo
+
+   ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(&cdi), 
C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Errorxl(ret)
+   return
+   }
+
+   // We could consider having this boilerplate generated by the
+   // idl, in a function like this:
+   //
+   // di = translateCdomaininfoToGoDomaininfo(cdi)
+   di = &Dominfo{}
+   di.Uuid = Uuid(cdi.uuid)
+   di.Domid = Domid(cdi.domid)
+   di.Ssidref = uint32(cdi.ssidref)
+   di.SsidLabel = C.GoString(cdi.ssid_label)
+   di.Running = bool(cdi.running)
+   di.Blocked = bool(cdi.blocked)
+   di.Paused = bool(cdi.paused)
+   di.Shutdown = bool(cdi.shutdown)
+   di.Dying = bool(cdi.dying)
+   di.NeverStop = bool(cdi.never_stop)
+   di.ShutdownReason = int32(cdi.shutdown_reason)
+   di.OutstandingMemkb = MemKB(cdi.outstanding_memkb)
+   di.CurrentMemkb = MemKB(cdi.current_memkb)
+   di.SharedMemkb = MemKB(cdi.shared_memkb)
+   di.PagedMemkb = MemKB(cdi.paged_memkb)
+   di.MaxMemkb = MemKB(cdi.max_memkb)
+   di.CpuTime = time.Duration(cdi.cpu_time)
+   di.VcpuMaxId = uint32(cdi.vcpu_max_id)
+   di.VcpuOnline = uint32(cdi.vcpu_online)
+   di.Cpupool = uint32(cdi.cpupool)
+   di.DomainType = int32(cdi.domain_type)
+
+   return
+}
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Errorxl(ret)
+   }
+   return
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-18 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas 
---
 tools/Makefile| 15 +++-
 tools/golang/xenlight/Makefile| 29 ++
 tools/golang/xenlight/xenlight.go | 80 +++
 3 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..fd49e7f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -6,12 +6,13 @@ SUBDIRS-y += include
 SUBDIRS-y += libs
 SUBDIRS-y += libxc
 SUBDIRS-y += flask
-SUBDIRS-y += fuzz
 SUBDIRS-y += xenstore
 SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
 SUBDIRS-y += xentrace
+#Uncomment line to build Golang libxl
+#SUBDIRS-y += golang/xenlight
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
 SUBDIRS-y += console
@@ -322,6 +323,18 @@ subdir-install-debugger/kdd: .phony
 subdir-all-debugger/kdd: .phony
$(MAKE) -C debugger/kdd all
 
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight clean
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight distclean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight install
+
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight all
+
 subdir-distclean-firmware: .phony
$(MAKE) -C firmware distclean
 
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..a45336b
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,29 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlightgo
+GO = go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight
+
+.PHONY: install
+install: build
+   ! [ -f $(BINARY) ] || $(INSTALL_PROG) xenlight.go $(DESTDIR)$(bindir)
+
+.PHONY: clean
+clean:
+   $(RM) $(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+
+xenlight: xenlight.go
+   $(GO) build -o $(BINARY) xenlight.go
+
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..1f10e51
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package xenlight
+
+/*
+#cgo LDFLAGS: -lxenlight -lyajl
+#include 
+#include 
+*/
+import "C"
+
+import (
+   "fmt"
+   "time"
+   "unsafe"
+)
+
+/*
+ * Types: Builtins
+ */
+type Context struct {
+   ctx *C.libxl_ctx
+}
+
+/*
+ * Context
+ */
+var Ctx Context
+
+func (Ctx *Context) IsOpen() bool {
+   return Ctx.ctx != nil
+}
+
+func (Ctx *Context) Open() (err error) {
+   if Ctx.ctx != nil {
+   return
+   }
+
+   ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
+
+   if ret != 0 {
+   //FIXME: proper error
+   err = createError("Allocating libxl context: ", ret)
+   }
+   return
+}
+
+func (Ctx *Context) Close() (err error) {
+   ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+   Ctx.ctx = nil
+
+   if ret != 0 {
+   //FIXME: proper error
+   err = createError("Freeing libxl context: ", ret)
+   }
+   return
+}
+
+func (Ctx *Context) CheckOpen() (err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   }
+   return
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 5/8] golang/xenlight: Implement libxl_bitmap and helper operations

2017-01-18 Thread Ronald Rojas
Implement Bitmap type, along with helper functions.

The Bitmap type is implemented interllay in a way which makes it
easy to copy into and out of the C libxl_bitmap type.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 167 ++
 1 file changed, 167 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 1e25413..8aaca6a 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -131,6 +131,20 @@ func hwcapCToGo(chwcap C.libxl_hwcap) (ghwcap Hwcap) {
return
 }
 
+// typedef struct {
+// uint32_t size;  /* number of bytes in map */
+// uint8_t *map;
+// } libxl_bitmap;
+
+// Implement the Go bitmap type such that the underlying data can
+// easily be copied in and out.  NB that we still have to do copies
+// both directions, because cgo runtime restrictions forbid passing to
+// a C function a pointer to a Go-allocated structure which contains a
+// pointer.
+type Bitmap struct {
+   bitmap []C.uint8_t
+}
+
 /*
  * Types: IDL
  *
@@ -198,6 +212,159 @@ type Dominfo struct {
 }
 
 /*
+ * Bitmap operations
+ */
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func bitmapCToGo(cbm C.libxl_bitmap) (gbm Bitmap) {
+   // Alloc a Go slice for the bytes
+   size := int(cbm.size)
+   gbm.bitmap = make([]C.uint8_t, size)
+
+   // Make a slice pointing to the C array
+   mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+   // And copy the C array into the Go array
+   copy(gbm.bitmap, mapslice)
+
+   return
+}
+
+// Must be C.libxl_bitmap_dispose'd of afterwards
+func bitmapGotoC(gbm Bitmap) (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init(&cbm)
+
+   size := len(gbm.bitmap)
+   cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
+   cbm.size = C.uint32_t(size)
+   if cbm._map == nil {
+   panic("C.calloc failed!")
+   }
+
+   // Make a slice pointing to the C array
+   mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+   // And copy the Go array into the C array
+   copy(mapslice, gbm.bitmap)
+
+   return
+}
+
+func (bm *Bitmap) Test(bit int) bool {
+   ubit := uint(bit)
+   if bit > bm.Max() || bm.bitmap == nil {
+   return false
+   }
+
+   return (bm.bitmap[bit/8] & (1 << (ubit & 7))) != 0
+}
+
+func (bm *Bitmap) Set(bit int) {
+   ibit := bit / 8
+   if ibit+1 > len(bm.bitmap) {
+   bm.bitmap = append(bm.bitmap, make([]C.uint8_t, 
ibit+1-len(bm.bitmap))...)
+   }
+
+   bm.bitmap[ibit] |= 1 << (uint(bit) & 7)
+}
+
+func (bm *Bitmap) SetRange(start int, end int) {
+   for i := start; i <= end; i++ {
+   bm.Set(i)
+   }
+}
+
+func (bm *Bitmap) Clear(bit int) {
+   ubit := uint(bit)
+   if bit > bm.Max() || bm.bitmap == nil {
+   return
+   }
+
+   bm.bitmap[bit/8] &= ^(1 << (ubit & 7))
+}
+
+func (bm *Bitmap) ClearRange(start int, end int) {
+   for i := start; i <= end; i++ {
+   bm.Clear(i)
+   }
+}
+
+func (bm *Bitmap) Max() int {
+   return len(bm.bitmap)*8 - 1
+}
+
+func (bm *Bitmap) IsEmpty() bool {
+   for i := 0; i < len(bm.bitmap); i++ {
+   if bm.bitmap[i] != 0 {
+   return false
+   }
+   }
+   return true
+}
+
+func (a Bitmap) And(b Bitmap) (c Bitmap) {
+   var max, min int
+   if len(a.bitmap) > len(b.bitmap) {
+   max = len(a.bitmap)
+   min = len(b.bitmap)
+   } else {
+   max = len(b.bitmap)
+   min = len(a.bitmap)
+   }
+   c.bitmap = make([]C.uint8_t, max)
+
+   for i := 0; i < min; i++ {
+   c.bitmap[i] = a.bitmap[i] & b.bitmap[i]
+   }
+   return
+}
+
+func (bm Bitmap) String() (s string) {
+   lastOnline := false
+   crange := false
+   printed := false
+   var i int
+   /// --x-x-x -> 2,4-8,10
+   /// --x-xxx -> 2,4-10
+   for i = 0; i <= bm.Max(); i++ {
+   if bm.Test(i) {
+   if !lastOnline {
+   // Switching offline -> online, print this cpu
+   if printed {
+   s += ","
+   }
+   s += fmt.Sprintf("%d", i)
+   printed = true
+   } else if !crange {
+   // last was online, but we're not in a range; 
print -
+   crange = true
+   s += "-"
+   } else {
+ 

[Xen-devel] [PATCH RFC 6/8] tools/xenlight: Implement libxl_scheduler enumeration

2017-01-18 Thread Ronald Rojas
Include both constants and a Stringification for libxl_scheduler.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 72 +++
 1 file changed, 72 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 8aaca6a..64e867a 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -211,6 +211,78 @@ type Dominfo struct {
 
 }
 
+// # Consistent with values defined in domctl.h
+// # Except unknown which we have made up
+// libxl_scheduler = Enumeration("scheduler", [
+// (0, "unknown"),
+// (4, "sedf"),
+// (5, "credit"),
+// (6, "credit2"),
+// (7, "arinc653"),
+// (8, "rtds"),
+// ])
+type Scheduler int
+
+var (
+   SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
+   SchedulerSedf Scheduler = C.LIBXL_SCHEDULER_SEDF
+   SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
+   SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
+   SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
+   SchedulerRTDS Scheduler = C.LIBXL_SCHEDULER_RTDS
+)
+
+// const char *libxl_scheduler_to_string(libxl_scheduler p);
+func (s Scheduler) String() string {
+   cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
+   // No need to free const return value
+
+   return C.GoString(cs)
+}
+
+// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
+func (s *Scheduler) FromString(gstr string) (err error) {
+   cstr := C.CString(gstr)
+   defer C.free(unsafe.Pointer(cstr))
+
+   var cs C.libxl_scheduler
+   ret := C.libxl_scheduler_from_string(cstr, &cs)
+   if ret != 0 {
+   err = Errorxl(ret)
+   return
+   }
+
+   *s = Scheduler(cs)
+   return
+}
+
+func translateCpupoolInfoCToGo(cci C.libxl_cpupoolinfo) (gci CpupoolInfo) {
+   gci.Poolid = uint32(cci.poolid)
+   gci.PoolName = C.GoString(cci.pool_name)
+   gci.Scheduler = Scheduler(cci.sched)
+   gci.DomainCount = int(cci.n_dom)
+   gci.Cpumap = bitmapCToGo(cci.cpumap)
+
+   return
+}
+
+func SchedulerFromString(name string) (s Scheduler, err error) {
+   cname := C.CString(name)
+   defer C.free(unsafe.Pointer(cname))
+
+   var cs C.libxl_scheduler
+
+   ret := C.libxl_scheduler_from_string(cname, &cs)
+   if ret != 0 {
+   err = Errorxl(ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
 /*
  * Bitmap operations
  */
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 2/8] golang/xenlight: Add error constants and standard handling

2017-01-18 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 77 +--
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 1f10e51..d58f8b8 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -32,6 +32,77 @@ import (
 )
 
 /*
+ * Errors
+ */
+type Errorxl int
+
+const (
+   ErrorNonspecific  = Errorxl(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Errorxl(-C.ERROR_VERSION)
+   ErrorFail = Errorxl(-C.ERROR_FAIL)
+   ErrorNi   = Errorxl(-C.ERROR_NI)
+   ErrorNomem= Errorxl(-C.ERROR_NOMEM)
+   ErrorInval= Errorxl(-C.ERROR_INVAL)
+   ErrorBadfail  = Errorxl(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Errorxl(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Errorxl(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Errorxl(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Errorxl(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Errorxl(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Errorxl(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Errorxl(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Errorxl(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Errorxl(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Errorxl(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Errorxl(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Errorxl(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = 
Errorxl(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Errorxl(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Errorxl(-C.ERROR_ABORTED)
+   ErrorNotfound = Errorxl(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Errorxl(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Errorxl(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific:  "Non-specific error",
+   ErrorVersion:  "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi:   "Null",
+   ErrorNomem:"No memory",
+   ErrorInval:"Invalid",
+   ErrorBadfail:  "Bad Fail",
+   ErrorGuestTimedout:"Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt:   "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail:   "OS event failed",
+   ErrorBufferfull:   "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty:  "JSON config empyt",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
+   ErrorDomainNotfound:   "Domain not found",
+   ErrorAborted:  "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed:  "Domain destroyed",
+   ErrorFeatureRemoved:   "Feature removed",
+}
+
+func (e Errorxl) Error() string {
+   if 0 <= -int(e) && -int(e) < len(errors) {
+   s := errors[-e]
+   if s != "" {
+   return s
+   }
+   }
+   return "errorxl " + strconv.Itoa(int(e))
+}
+
+/*
  * Types: Builtins
  */
 type Context struct {
@@ -55,8 +126,7 @@ func (Ctx *Context) Open() (err error) {
ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
 
if ret != 0 {
-   //FIXME: proper error
-   err = createError("Allocating libxl context: ", ret)
+   err = Errorxl(ret)
}
return
 }
@@ -66,8 +136,7 @@ func (Ctx *Context) Close() (err e

Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-18 Thread Ronald Rojas
On Wed, Jan 18, 2017 at 11:10:32PM +0100, Dario Faggioli wrote:
> Hey,
> 
> I'm afraid I can't comment on nothing, as I'm not at all into go.
> 
> But there's a thing that I've noticed while skipping the patch out of
> curiosity...
> 
> On Wed, 2017-01-18 at 14:56 -0500, Ronald Rojas wrote:
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 77e0723..fd49e7f 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -6,12 +6,13 @@ SUBDIRS-y += include
> >  SUBDIRS-y += libs
> >  SUBDIRS-y += libxc
> >  SUBDIRS-y += flask
> > -SUBDIRS-y += fuzz
> >
> Why does this needs to be removed?
This was a mistake and should not have been removed. I'll
fix it in the next revision.

Thanks, 
Ronald
> 
> Dario
> -- 
> <> (Raistlin Majere)
> -
> Dario Faggioli, Ph.D, http://about.me/dario.faggioli
> Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC 2/8] golang/xenlight: Add error constants and standard handling

2017-01-19 Thread Ronald Rojas
On Wed, Jan 18, 2017 at 11:16:31PM +0100, Dario Faggioli wrote:
> On Wed, 2017-01-18 at 14:56 -0500, Ronald Rojas wrote:
> > Create error type Errorxl for throwing proper xenlight
> > errors.
> > 
> > Update Ctx functions to throw Errorxl errors.
> > 
> > Signed-off-by: Ronald Rojas 
> > ---
> >  tools/golang/xenlight/xenlight.go | 77
> > +--
> >  1 file changed, 73 insertions(+), 4 deletions(-)
> > 
> > diff --git a/tools/golang/xenlight/xenlight.go
> > b/tools/golang/xenlight/xenlight.go
> > index 1f10e51..d58f8b8 100644
> > --- a/tools/golang/xenlight/xenlight.go
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -32,6 +32,77 @@ import (
> >  )
> >  
> >  /*
> > + * Errors
> > + */
> > +type Errorxl int
> > +
> > +const (
> > +   ErrorNonspecific  = Errorxl(-
> > C.ERROR_NONSPECIFIC)
> > +   ErrorVersion  = Errorxl(-
> > C.ERROR_VERSION)
> > +   ErrorFail = Errorxl(-C.ERROR_FAIL)
> > +   ErrorNi   = Errorxl(-C.ERROR_NI)
> > +   ErrorNomem= Errorxl(-C.ERROR_NOMEM)
> > +   ErrorInval= Errorxl(-C.ERROR_INVAL)
> > +   ErrorBadfail  = Errorxl(-
> > C.ERROR_BADFAIL)
> > +   ErrorGuestTimedout= Errorxl(-
> > C.ERROR_GUEST_TIMEDOUT)
> > +   ErrorTimedout = Errorxl(-
> > C.ERROR_TIMEDOUT)
> > +   ErrorNoparavirt   = Errorxl(-
> > C.ERROR_NOPARAVIRT)
> > +   ErrorNotReady = Errorxl(-
> > C.ERROR_NOT_READY)
> > +   ErrorOseventRegFail   = Errorxl(-
> > C.ERROR_OSEVENT_REG_FAIL)
> > +   ErrorBufferfull   = Errorxl(-
> > C.ERROR_BUFFERFULL)
> > +   ErrorUnknownChild = Errorxl(-
> > C.ERROR_UNKNOWN_CHILD)
> > +   ErrorLockFail = Errorxl(-
> > C.ERROR_LOCK_FAIL)
> > +   ErrorJsonConfigEmpty  = Errorxl(-
> > C.ERROR_JSON_CONFIG_EMPTY)
> > +   ErrorDeviceExists = Errorxl(-
> > C.ERROR_DEVICE_EXISTS)
> > +   ErrorCheckpointDevopsDoesNotMatch = Errorxl(-
> > C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
> > +   ErrorCheckpointDeviceNotSupported = Errorxl(-
> > C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
> > +   ErrorVnumaConfigInvalid   = Errorxl(-
> > C.ERROR_VNUMA_CONFIG_INVALID)
> > +   ErrorDomainNotfound   = Errorxl(-
> > C.ERROR_DOMAIN_NOTFOUND)
> > +   ErrorAborted  = Errorxl(-
> > C.ERROR_ABORTED)
> > +   ErrorNotfound = Errorxl(-
> > C.ERROR_NOTFOUND)
> > +   ErrorDomainDestroyed  = Errorxl(-
> > C.ERROR_DOMAIN_DESTROYED)
> > +   ErrorFeatureRemoved   = Errorxl(-
> > C.ERROR_FEATURE_REMOVED)
> > +)
> > +
> > +var errors = [...]string{
> > +   ErrorNonspecific:  "Non-specific error",
> > +   ErrorVersion:  "Wrong version",
> > +   ErrorFail: "Failed",
> > +   ErrorNi:   "Null",
> > +   ErrorNomem:"No memory",
> > +   ErrorInval:"Invalid",
> > +   ErrorBadfail:  "Bad Fail",
> > +   ErrorGuestTimedout:"Guest timed out",
> > +   ErrorTimedout: "Timed out",
> > +   ErrorNoparavirt:   "No Paravirtualization",
> > +   ErrorNotReady: "Not ready",
> > +   ErrorOseventRegFail:   "OS event failed",
> > +   ErrorBufferfull:   "Buffer full",
> > +   ErrorUnknownChild: "Unknown child",
> > +   ErrorLockFail: "Lock failed",
> > +   ErrorJsonConfigEmpty:  "JSON config empyt",
> > +   ErrorDeviceExists: "Device exists",
> > +   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does
> > not match",
> > +   ErrorCheckpointDeviceNotSupported: "Checkpoint device not
> > supported",
> > +   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
> > +   ErrorDomainNotfound:   "Domain not found",
> > +   ErrorAborted:  "Aborted",
> > +   ErrorNotfound: 

Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-19 Thread Ronald Rojas
On Thu, Jan 19, 2017 at 12:03:22PM +, Wei Liu wrote:
> On Wed, Jan 18, 2017 at 02:56:39PM -0500, Ronald Rojas wrote:
>   
> > diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> > new file mode 100644
> > index 000..a45336b
> > --- /dev/null
> > +++ b/tools/golang/xenlight/Makefile
> > @@ -0,0 +1,29 @@
> > +XEN_ROOT=$(CURDIR)/../../..
> > +include $(XEN_ROOT)/tools/Rules.mk
> > +
> > +BINARY = xenlightgo
> > +GO = go
> 
> GO ?= go
> 
> to allow overriding this command.

Fixed. Thanks!
> 
> Other than this, I don't have further comments on the actual go code and
> will let George review your series.
> 
> Wei.

Thanks,
Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 2/8] golang/xenlight: Add error constants and standard handling

2017-01-23 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 75 ++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index f82e14e..eee2254 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -38,10 +38,72 @@ import (
"unsafe"
 )
 
+/*
+ * Errors
+ */
+
+type Error int
+
+const (
+   ErrorNonspecific  = Error(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Error(-C.ERROR_VERSION)
+   ErrorFail = Error(-C.ERROR_FAIL)
+   ErrorNi   = Error(-C.ERROR_NI)
+   ErrorNomem= Error(-C.ERROR_NOMEM)
+   ErrorInval= Error(-C.ERROR_INVAL)
+   ErrorBadfail  = Error(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Error(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Error(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Error(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Error(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Error(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Error(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Error(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Error(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Error(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Error(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Error(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Error(-C.ERROR_ABORTED)
+   ErrorNotfound = Error(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Error(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Error(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific: "Non-specific error",
+   ErrorVersion: "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi: "Not Implemented",
+   ErrorNomem: "No memory",
+   ErrorInval: "Invalid argument",
+   ErrorBadfail: "Bad Fail",
+   ErrorGuestTimedout: "Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt: "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail: "OS event registration failed",
+   ErrorBufferfull: "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty: "JSON config empty",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid: "VNUMA config invalid",
+   ErrorDomainNotfound: "Domain not found",
+   ErrorAborted: "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed: "Domain destroyed",
+   ErrorFeatureRemoved: "Feature removed",
+}
 
 /*
  * Types: Builtins
  */
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -51,6 +113,17 @@ type Context struct {
  */
 var Ctx Context
 
+func (e Error) Error() string{
+   if 0< int(e) && int(e) < len(errors){
+   s:= errors[e]
+   if s != ""{
+   return s
+   }
+   }
+   return fmt.Sprintf("libxl error: %d", -e)
+
+}
+
 func (Ctx *Context) IsOpen() bool {
return Ctx.ctx != nil
 }
@@ -83,4 +156,4 @@ func (Ctx *Context) CheckOpen() (err error) {
err = fmt.Errorf("Context not opened")
}
return
-}
\ No newline at end of file
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 7/8] golang/xenlight: Implement libxl_scheduler enumeration

2017-01-23 Thread Ronald Rojas
Include both constants and a Stringification for libxl_scheduler.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 62 +++
 1 file changed, 62 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 54692fd..0990f07 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -211,6 +211,68 @@ type Dominfo struct {
 
 }
 
+// # Consistent with values defined in domctl.h
+// # Except unknown which we have made up
+// libxl_scheduler = Enumeration("scheduler", [
+// (0, "unknown"),
+// (4, "sedf"),
+// (5, "credit"),
+// (6, "credit2"),
+// (7, "arinc653"),
+// (8, "rtds"),
+// ])
+type Scheduler int
+
+var (
+   SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
+   SchedulerSedf Scheduler = C.LIBXL_SCHEDULER_SEDF
+   SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
+   SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
+   SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
+   SchedulerRTDS Scheduler = C.LIBXL_SCHEDULER_RTDS
+)
+
+// const char *libxl_scheduler_to_string(libxl_scheduler p);
+func (s Scheduler) String() string {
+   cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
+   // No need to free const return value
+
+   return C.GoString(cs)
+}
+
+// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
+func (s *Scheduler) FromString(gstr string) (err error) {
+   cstr := C.CString(gstr)
+   defer C.free(unsafe.Pointer(cstr))
+
+   var cs C.libxl_scheduler
+   ret := C.libxl_scheduler_from_string(cstr, &cs)
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   *s = Scheduler(cs)
+   return
+}
+
+func SchedulerFromString(name string) (s Scheduler, err error) {
+   cname := C.CString(name)
+   defer C.free(unsafe.Pointer(cname))
+
+   var cs C.libxl_scheduler
+
+   ret := C.libxl_scheduler_from_string(cname, &cs)
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
 /*
  * Bitmap operations
  */
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-23 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas 
---
 tools/Makefile| 17 
 tools/golang/xenlight/Makefile| 31 ++
 tools/golang/xenlight/xenlight.go | 86 +++
 3 files changed, 134 insertions(+)
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..c1e975f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -11,6 +11,8 @@ SUBDIRS-y += xenstore
 SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
+#Uncomment line to build Golang libxl
+#SUBDIRS-y += golang/xenlight
 SUBDIRS-y += xentrace
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
@@ -303,6 +305,21 @@ subdir-clean-qemu-xen-dir:
$(MAKE) -C qemu-xen-dir clean; \
fi
 
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight clean
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight distclean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight install
+
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight all
+
+subdir-distclean-firmware: .phony
+   $(MAKE) -C firmware distclean
+
 subdir-clean-debugger/gdbsx subdir-distclean-debugger/gdbsx: .phony
$(MAKE) -C debugger/gdbsx clean
 
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..1c2a2b7
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,31 @@
+XEN_ROOT=$(CURDIR)/../../..
+GOLANG_SRC=$(GOPATH)/src/xenproject.org/xenlight
+CGO_CFLAGS = -I$(DESTDIR)$(includedir)
+CGO_LDFLAGS = -L$(DESTDIR)$(libdir) -Wl,-rpath-link=$(DESTDIR)$(libdir)
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlight.a
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight.a
+
+.PHONY: install
+install: build
+   $(INSTALL_DIR) $(DESTDIR)$(GOLANG_SRC)
+   $(INSTALL_DATA) xenlight.go $(DESTDIR)$(GOLANG_SRC)
+
+.PHONY: clean
+clean:
+   $(RM) $(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+xenlight.a: xenlight.go
+   CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o 
$@ $<
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..f82e14e
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package xenlight
+
+/*
+#cgo LDFLAGS: -lxenlight -lyajl
+#include 
+#include 
+*/
+import "C"
+
+/*
+ * Other flags that may be needed at some point:
+ *  -lnl-route-3 -lnl-3
+ *
+ * To get back to static linking:
+ * #cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
+*/
+
+import (
+   "fmt"
+   "unsafe"
+)
+
+
+/*
+ * Types: Builtins
+ */
+type Context struct {
+   ctx *C.libxl_ctx
+}
+
+/*
+ * Context
+ */
+var Ctx Context
+
+func (Ctx *Context) IsOpen() bool {
+   return Ctx.ctx != nil
+}
+
+func (Ctx *Context) Open() (err error) {
+   if Ctx.ctx != nil {
+   return
+   }
+
+   ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+func (Ctx *Context) Close() (err error) {
+   ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+   Ctx.ctx = nil
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+func (Ctx *Context) CheckOpen() (err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   }
+   return
+}
\ No newline at end of file
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 6/8] golang/xenlight: Implement libxl_bitmap and helper operations

2017-01-23 Thread Ronald Rojas
Implement Bitmap type, along with helper functions.

The Bitmap type is implemented interllay in a way which makes it
easy to copy into and out of the C libxl_bitmap type.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 166 ++
 1 file changed, 166 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index dd6893c..54692fd 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -131,6 +131,19 @@ func (chwcap C.libxl_hwcap)CToGo() (ghwcap Hwcap) {
return
 }
 
+// typedef struct {
+// uint32_t size;  /* number of bytes in map */
+// uint8_t *map;
+// } libxl_bitmap;
+
+// Implement the Go bitmap type such that the underlying data can
+// easily be copied in and out.  NB that we still have to do copies
+// both directions, because cgo runtime restrictions forbid passing to
+// a C function a pointer to a Go-allocated structure which contains a
+// pointer.
+type Bitmap struct {
+   bitmap []C.uint8_t
+}
 
 /*
  * Types: IDL
@@ -199,6 +212,159 @@ type Dominfo struct {
 }
 
 /*
+ * Bitmap operations
+ */
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func (cbm C.libxl_bitmap) CToGo() (gbm Bitmap) {
+   // Alloc a Go slice for the bytes
+   size := int(cbm.size)
+   gbm.bitmap = make([]C.uint8_t, size)
+
+   // Make a slice pointing to the C array
+   mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+   // And copy the C array into the Go array
+   copy(gbm.bitmap, mapslice)
+
+   return
+}
+
+// Must be C.libxl_bitmap_dispose'd of afterwards
+func (gbm Bitmap)GoToC() (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init(&cbm)
+
+   size := len(gbm.bitmap)
+   cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
+   cbm.size = C.uint32_t(size)
+   if cbm._map == nil {
+   panic("C.calloc failed!")
+   }
+
+   // Make a slice pointing to the C array
+   mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+   // And copy the Go array into the C array
+   copy(mapslice, gbm.bitmap)
+
+   return
+}
+
+func (bm *Bitmap) Test(bit int) bool {
+   ubit := uint(bit)
+   if bit > bm.Max() || bm.bitmap == nil {
+   return false
+   }
+
+   return (bm.bitmap[bit/8] & (1 << (ubit & 7))) != 0
+}
+
+func (bm *Bitmap) Set(bit int) {
+   ibit := bit / 8
+   if ibit+1 > len(bm.bitmap) {
+   bm.bitmap = append(bm.bitmap, make([]C.uint8_t, 
ibit+1-len(bm.bitmap))...)
+   }
+
+   bm.bitmap[ibit] |= 1 << (uint(bit) & 7)
+}
+
+func (bm *Bitmap) SetRange(start int, end int) {
+   for i := start; i <= end; i++ {
+   bm.Set(i)
+   }
+}
+
+func (bm *Bitmap) Clear(bit int) {
+   ubit := uint(bit)
+   if bit > bm.Max() || bm.bitmap == nil {
+   return
+   }
+
+   bm.bitmap[bit/8] &= ^(1 << (ubit & 7))
+}
+
+func (bm *Bitmap) ClearRange(start int, end int) {
+   for i := start; i <= end; i++ {
+   bm.Clear(i)
+   }
+}
+
+func (bm *Bitmap) Max() int {
+   return len(bm.bitmap)*8 - 1
+}
+
+func (bm *Bitmap) IsEmpty() bool {
+   for i := 0; i < len(bm.bitmap); i++ {
+   if bm.bitmap[i] != 0 {
+   return false
+   }
+   }
+   return true
+}
+
+func (a Bitmap) And(b Bitmap) (c Bitmap) {
+   var max, min int
+   if len(a.bitmap) > len(b.bitmap) {
+   max = len(a.bitmap)
+   min = len(b.bitmap)
+   } else {
+   max = len(b.bitmap)
+   min = len(a.bitmap)
+   }
+   c.bitmap = make([]C.uint8_t, max)
+
+   for i := 0; i < min; i++ {
+   c.bitmap[i] = a.bitmap[i] & b.bitmap[i]
+   }
+   return
+}
+
+func (bm Bitmap) String() (s string) {
+   lastOnline := false
+   crange := false
+   printed := false
+   var i int
+   /// --x-x-x -> 2,4-8,10
+   /// --x-xxx -> 2,4-10
+   for i = 0; i <= bm.Max(); i++ {
+   if bm.Test(i) {
+   if !lastOnline {
+   // Switching offline -> online, print this cpu
+   if printed {
+   s += ","
+   }
+   s += fmt.Sprintf("%d", i)
+   printed = true
+   } else if !crange {
+   // last was online, but we're not in a range; 
print -
+   crange = true
+   s += "-"
+   } else {
+   // la

[Xen-devel] [PATCH RFC 4/8] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-01-23 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 92 +++
 1 file changed, 92 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 92410a8..dd6893c 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -36,6 +36,7 @@ import "C"
 import (
"fmt"
"unsafe"
+   "time"
 )
 
 /*
@@ -104,6 +105,12 @@ var errors = [...]string{
  * Types: Builtins
  */
 
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -165,6 +172,32 @@ type VersionInfo struct {
BuildId  string
 }
 
+type Dominfo struct {
+   Uuid   Uuid
+   Domid  Domid
+   Ssidref uint32
+   SsidLabel string
+   Runningbool
+   Blockedbool
+   Paused bool
+   Shutdown   bool
+   Dying  bool
+   NeverStop bool
+
+   ShutdownReason   int32 // FIXME shutdown_reason enumeration
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxId   uint32
+   VcpuOnline   uint32
+   Cpupool   uint32
+   DomainType   int32 //FIXME libxl_domain_type enumeration
+
+}
+
 /*
  * Context
  */
@@ -343,3 +376,62 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, 
err error) {
 
return
 }
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var cdi C.libxl_dominfo
+
+   ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(&cdi), 
C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   // We could consider having this boilerplate generated by the
+   // idl, in a function like this:
+   //
+   // di = translateCdomaininfoToGoDomaininfo(cdi)
+   di = &Dominfo{}
+   di.Uuid = Uuid(cdi.uuid)
+   di.Domid = Domid(cdi.domid)
+   di.Ssidref = uint32(cdi.ssidref)
+   di.SsidLabel = C.GoString(cdi.ssid_label)
+   di.Running = bool(cdi.running)
+   di.Blocked = bool(cdi.blocked)
+   di.Paused = bool(cdi.paused)
+   di.Shutdown = bool(cdi.shutdown)
+   di.Dying = bool(cdi.dying)
+   di.NeverStop= bool(cdi.never_stop)
+   di.ShutdownReason= int32(cdi.shutdown_reason)
+   di.OutstandingMemkb= MemKB(cdi.outstanding_memkb)
+   di.CurrentMemkb = MemKB(cdi.current_memkb)
+   di.SharedMemkb = MemKB(cdi.shared_memkb)
+   di.PagedMemkb = MemKB(cdi.paged_memkb)
+   di.MaxMemkb= MemKB(cdi.max_memkb)
+   di.CpuTime= time.Duration(cdi.cpu_time)
+   di.VcpuMaxId = uint32(cdi.vcpu_max_id)
+   di.VcpuOnline = uint32(cdi.vcpu_online)
+   di.Cpupool = uint32(cdi.cpupool)
+   di.DomainType = int32(cdi.domain_type)
+
+   return
+}
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 8/8] golang/xenlight: Implement cpupool operations

2017-01-23 Thread Ronald Rojas
Include some useful "Utility" functions:
- CpupoolFindByName
- CpupoolMakeFree

Still need to implement the following functions:
- libxl_cpupool_rename
- libxl_cpupool_cpuadd_node
- libxl_cpupool_cpuremove_node
- libxl_cpupool_movedomain

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/xenlight.go | 238 ++
 1 file changed, 238 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 0990f07..c856284 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -273,6 +273,244 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
return
 }
 
+
+// libxl_cpupoolinfo = Struct("cpupoolinfo", [
+// ("poolid",  uint32),
+// ("pool_name",   string),
+// ("sched",   libxl_scheduler),
+// ("n_dom",   uint32),
+// ("cpumap",  libxl_bitmap)
+// ], dir=DIR_OUT)
+
+type CpupoolInfo struct {
+   Poolid  uint32
+   PoolNamestring
+   Scheduler   Scheduler
+   DomainCount int
+   Cpumap  Bitmap
+}
+
+func (cci C.libxl_cpupoolinfo)CToGo ()(gci CpupoolInfo) {
+   gci.Poolid = uint32(cci.poolid)
+   gci.PoolName = C.GoString(cci.pool_name)
+   gci.Scheduler = Scheduler(cci.sched)
+   gci.DomainCount = int(cci.n_dom)
+   gci.Cpumap = cci.cpumap.CToGo()
+
+   return
+}
+
+// libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
+// void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
+func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
+   err := Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var nbPool C.int
+
+   c_cpupool_list := C.libxl_list_cpupool(Ctx.ctx, &nbPool)
+
+   defer C.libxl_cpupoolinfo_list_free(c_cpupool_list, nbPool)
+
+   if int(nbPool) == 0 {
+   return
+   }
+
+   // Magic
+   cpupoolListSlice := (*[1 << 
30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
+
+   for i := range cpupoolListSlice {
+   info := cpupoolListSlice[i].CToGo()
+
+   list = append(list, info)
+   }
+
+   return
+}
+
+// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
+func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool CpupoolInfo) {
+   err := Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var c_cpupool C.libxl_cpupoolinfo
+
+   ret := C.libxl_cpupool_info(Ctx.ctx, &c_cpupool, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+   defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
+
+   pool = c_cpupool.CToGo()
+
+   return
+}
+
+// int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
+//  libxl_scheduler sched,
+//  libxl_bitmap cpumap, libxl_uuid *uuid,
+//  uint32_t *poolid);
+// FIXME: uuid
+// FIXME: Setting poolid
+func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap 
Bitmap) (err error, Poolid uint32) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   poolid := C.uint32_t(0)
+   name := C.CString(Name)
+   defer C.free(unsafe.Pointer(name))
+
+   // For now, just do what xl does, and make a new uuid every time we 
create the pool
+   var uuid C.libxl_uuid
+   C.libxl_uuid_generate(&uuid)
+
+   cbm := Cpumap.GoToC()
+   defer C.libxl_bitmap_dispose(&cbm)
+
+   ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+   cbm, &uuid, &poolid)
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   Poolid = uint32(poolid)
+
+   return
+}
+
+// int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
+func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_cpupool_destroy(Ctx.ctx, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   return
+}
+
+// int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
+func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_cpupool_cpuadd(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   return
+}
+
+// int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
+// const libxl_bitmap *cpumap);
+func (Ct

Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-26 Thread Ronald Rojas
On Wed, Jan 25, 2017 at 04:55:38PM +, Wei Liu wrote:
> On Mon, Jan 23, 2017 at 11:43:30AM -0500, Ronald Rojas wrote:
> [...]
> > +
> > +subdir-distclean-firmware: .phony
> > +   $(MAKE) -C firmware distclean
> > +
> 
> This looks unrelated.

You're correct. Thanks for catching the mistake.
> 
> >  subdir-clean-debugger/gdbsx subdir-distclean-debugger/gdbsx: .phony
> > $(MAKE) -C debugger/gdbsx clean
> >  
> > diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> > new file mode 100644
> > index 000..1c2a2b7
> > --- /dev/null
> > +++ b/tools/golang/xenlight/Makefile
> > @@ -0,0 +1,31 @@
> > +XEN_ROOT=$(CURDIR)/../../..
> > +GOLANG_SRC=$(GOPATH)/src/xenproject.org/xenlight
> > +CGO_CFLAGS = -I$(DESTDIR)$(includedir)
> > +CGO_LDFLAGS = -L$(DESTDIR)$(libdir) -Wl,-rpath-link=$(DESTDIR)$(libdir)
> > +include $(XEN_ROOT)/tools/Rules.mk
> > +
> > +BINARY = xenlight.a
> > +GO ?= go
> > +
> > +.PHONY: all
> > +all: build
> > +
> > +.PHONY: build
> > +build: xenlight.a
> > +
> > +.PHONY: install
> > +install: build
> > +   $(INSTALL_DIR) $(DESTDIR)$(GOLANG_SRC)
> > +   $(INSTALL_DATA) xenlight.go $(DESTDIR)$(GOLANG_SRC)
> > +
> > +.PHONY: clean
> > +clean:
> > +   $(RM) $(BINARY)
> > +
> > +.PHONY: distclean
> > +distclean: clean
> > +
> > +xenlight.a: xenlight.go
> > +   CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o 
> > $@ $<
> > +
> > +-include $(DEPS)
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > new file mode 100644
> > index 000..f82e14e
> > --- /dev/null
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -0,0 +1,86 @@
> > +/*
> > + * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; version 2 of the
> > + * License only.
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> > + * 02110-1301, USA.
> > + */
> 
> My impression is that we prefer LGPL for libraries -- but of course it
> is up to the author to decide what license to use. :-)

Why the preferance for LGPL? I'm not too familiar with the differences
between the two. 
> 
> Wei.

Thanks, 
Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-26 Thread Ronald Rojas
On Wed, Jan 25, 2017 at 05:16:47PM +, George Dunlap wrote:
> On Mon, Jan 23, 2017 at 4:43 PM, Ronald Rojas  wrote:
> 
> > +func (Ctx *Context) Open() (err error) {
> > +   if Ctx.ctx != nil {
> > +   return
> > +   }
> > +
> > +   ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 
> > 0, nil)
> 
> Just discovered there's a bug here (in code that I wrote obviously) --
> you can't pass the last argument as nil; you have to include a logger.
> Otherwise if you ever get an error you'll get a NULL dereference. :-)
> 
> I think the fastest thing to do to begin with would be to create a
> "null" logger that just throws away all the data.  Then at some point
> (possibly not in your internship) someone can think about what a
> proper logging interface looks like.

Makes sense. I can modify the code so that it creates an instance of 
the xenlogger and prints it to /dev/null. I will add this in the next
version of the patch.
> 
>  -George

Thanks,
Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC] xl_cmdimpl.c: Fix printf usage

2016-10-12 Thread Ronald Rojas
Change instances of printf, fprintf, and LOG where the specifier
used is '%d' to be '%u' for domid.

Signed-off-by: Ronald Rojas 
---
 tools/libxl/xl_cmdimpl.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index cb43c00..b154e36 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2674,7 +2674,7 @@ static int preserve_domain(uint32_t *r_domid, libxl_event 
*event,
 
 libxl_uuid_generate(&new_uuid);
 
-LOG("Preserving domain %d %s with suffix%s",
+LOG("Preserving domain %u %s with suffix%s",
 *r_domid, d_config->c_info.name, strtime);
 rc = libxl_domain_preserve(ctx, *r_domid, &d_config->c_info,
strtime, new_uuid);
@@ -2758,7 +2758,7 @@ static int domain_wait_event(uint32_t domid, libxl_event 
**event_r)
 for (;;) {
 ret = libxl_event_wait(ctx, event_r, LIBXL_EVENTMASK_ALL, 0,0);
 if (ret) {
-LOG("Domain %d, failed to get event, quitting (rc=%d)", domid, 
ret);
+LOG("Domain %u, failed to get event, quitting (rc=%d)", domid, 
ret);
 return ret;
 }
 if ((*event_r)->domid != domid) {
@@ -3108,7 +3108,7 @@ start:
 }
 need_daemon = 0;
 }
-LOG("Waiting for domain %s (domid %d) to die [pid %ld]",
+LOG("Waiting for domain %s (domid %u) to die [pid %ld]",
 d_config.c_info.name, domid, (long)getpid());
 
 ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
@@ -3134,7 +3134,7 @@ start:
 switch (event->type) {
 
 case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
-LOG("Domain %d has shut down, reason code %d 0x%x", domid,
+LOG("Domain %u has shut down, reason code %d 0x%x", domid,
 event->u.domain_shutdown.shutdown_reason,
 event->u.domain_shutdown.shutdown_reason);
 switch (handle_domain_death(&domid, event, &d_config)) {
@@ -3198,7 +3198,7 @@ start:
 }
 
 case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
-LOG("Domain %d has been destroyed.", domid);
+LOG("Domain %u has been destroyed.", domid);
 libxl_event_free(ctx, event);
 ret = 0;
 goto out;
@@ -3442,7 +3442,7 @@ static int set_memory_max(uint32_t domid, const char *mem)
 }
 
 if (libxl_domain_setmaxmem(ctx, domid, memorykb)) {
-fprintf(stderr, "cannot set domid %d static max memory to : %s\n", 
domid, mem);
+fprintf(stderr, "cannot set domid %u static max memory to : %s\n", 
domid, mem);
 return EXIT_FAILURE;
 }
 
@@ -3476,7 +3476,7 @@ static int set_memory_target(uint32_t domid, const char 
*mem)
 }
 
 if (libxl_set_memory_target(ctx, domid, memorykb, 0, /* enforce */ 1)) {
-fprintf(stderr, "cannot set domid %d dynamic max memory to : %s\n", 
domid, mem);
+fprintf(stderr, "cannot set domid %u dynamic max memory to : %s\n", 
domid, mem);
 return EXIT_FAILURE;
 }
 
@@ -4133,7 +4133,7 @@ static void shutdown_domain(uint32_t domid,
 {
 int rc;
 
-fprintf(stderr, "Shutting down domain %d\n", domid);
+fprintf(stderr, "Shutting down domain %u\n", domid);
 rc=libxl_domain_shutdown(ctx, domid);
 if (rc == ERROR_NOPARAVIRT) {
 if (fallback_trigger) {
@@ -4165,7 +4165,7 @@ static void reboot_domain(uint32_t domid, 
libxl_evgen_domain_death **deathw,
 {
 int rc;
 
-fprintf(stderr, "Rebooting domain %d\n", domid);
+fprintf(stderr, "Rebooting domain %u\n", domid);
 rc=libxl_domain_reboot(ctx, domid);
 if (rc == ERROR_NOPARAVIRT) {
 if (fallback_trigger) {
@@ -5625,7 +5625,7 @@ int main_config_update(int argc, char **argv)
 printf_info(default_output_format, -1, &d_config, stdout);
 
 if (!dryrun_only) {
-fprintf(stderr, "setting dom%d configuration\n", domid);
+fprintf(stderr, "setting dom%u configuration\n", domid);
 rc = libxl_userdata_store(ctx, domid, "xl",
config_data, config_len);
 if (rc) {
@@ -5951,7 +5951,7 @@ static int vcpuset(uint32_t domid, const char* nr_vcpus, 
int check_host)
 if (rc == ERROR_DOMAIN_NOTFOUND)
 fprintf(stderr, "Domain %u does not exist.\n", domid);
 else if (rc)
-fprintf(stderr, "libxl_set_vcpuonline failed domid=%d max_vcpus=%d," \
+fprintf(stderr, "libxl_set_vcpuonline failed domid=%u max_vcpus=%d," \
 " rc: %d\n", domid, max_vcpus, rc);
 
 libxl_bitmap_dispose(&cpumap);
@@ -7113,7 +7113,7 @@ int main_domid(int argc, char **argv)
 return

[Xen-devel] [PATCH] tools/xl: Use %u for uint32_t domids

2016-10-16 Thread Ronald Rojas
domid is normally represented by uint32_t, but many format
strings in xl_cmdimpl.c use %d when printing, which is signed.
Use %u instead to print the unsigned integer domid.

Signed-off-by: Ronald Rojas 
---
 tools/libxl/xl_cmdimpl.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index cb43c00..b154e36 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2674,7 +2674,7 @@ static int preserve_domain(uint32_t *r_domid, libxl_event 
*event,
 
 libxl_uuid_generate(&new_uuid);
 
-LOG("Preserving domain %d %s with suffix%s",
+LOG("Preserving domain %u %s with suffix%s",
 *r_domid, d_config->c_info.name, strtime);
 rc = libxl_domain_preserve(ctx, *r_domid, &d_config->c_info,
strtime, new_uuid);
@@ -2758,7 +2758,7 @@ static int domain_wait_event(uint32_t domid, libxl_event 
**event_r)
 for (;;) {
 ret = libxl_event_wait(ctx, event_r, LIBXL_EVENTMASK_ALL, 0,0);
 if (ret) {
-LOG("Domain %d, failed to get event, quitting (rc=%d)", domid, 
ret);
+LOG("Domain %u, failed to get event, quitting (rc=%d)", domid, 
ret);
 return ret;
 }
 if ((*event_r)->domid != domid) {
@@ -3108,7 +3108,7 @@ start:
 }
 need_daemon = 0;
 }
-LOG("Waiting for domain %s (domid %d) to die [pid %ld]",
+LOG("Waiting for domain %s (domid %u) to die [pid %ld]",
 d_config.c_info.name, domid, (long)getpid());
 
 ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
@@ -3134,7 +3134,7 @@ start:
 switch (event->type) {
 
 case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
-LOG("Domain %d has shut down, reason code %d 0x%x", domid,
+LOG("Domain %u has shut down, reason code %d 0x%x", domid,
 event->u.domain_shutdown.shutdown_reason,
 event->u.domain_shutdown.shutdown_reason);
 switch (handle_domain_death(&domid, event, &d_config)) {
@@ -3198,7 +3198,7 @@ start:
 }
 
 case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
-LOG("Domain %d has been destroyed.", domid);
+LOG("Domain %u has been destroyed.", domid);
 libxl_event_free(ctx, event);
 ret = 0;
 goto out;
@@ -3442,7 +3442,7 @@ static int set_memory_max(uint32_t domid, const char *mem)
 }
 
 if (libxl_domain_setmaxmem(ctx, domid, memorykb)) {
-fprintf(stderr, "cannot set domid %d static max memory to : %s\n", 
domid, mem);
+fprintf(stderr, "cannot set domid %u static max memory to : %s\n", 
domid, mem);
 return EXIT_FAILURE;
 }
 
@@ -3476,7 +3476,7 @@ static int set_memory_target(uint32_t domid, const char 
*mem)
 }
 
 if (libxl_set_memory_target(ctx, domid, memorykb, 0, /* enforce */ 1)) {
-fprintf(stderr, "cannot set domid %d dynamic max memory to : %s\n", 
domid, mem);
+fprintf(stderr, "cannot set domid %u dynamic max memory to : %s\n", 
domid, mem);
 return EXIT_FAILURE;
 }
 
@@ -4133,7 +4133,7 @@ static void shutdown_domain(uint32_t domid,
 {
 int rc;
 
-fprintf(stderr, "Shutting down domain %d\n", domid);
+fprintf(stderr, "Shutting down domain %u\n", domid);
 rc=libxl_domain_shutdown(ctx, domid);
 if (rc == ERROR_NOPARAVIRT) {
 if (fallback_trigger) {
@@ -4165,7 +4165,7 @@ static void reboot_domain(uint32_t domid, 
libxl_evgen_domain_death **deathw,
 {
 int rc;
 
-fprintf(stderr, "Rebooting domain %d\n", domid);
+fprintf(stderr, "Rebooting domain %u\n", domid);
 rc=libxl_domain_reboot(ctx, domid);
 if (rc == ERROR_NOPARAVIRT) {
 if (fallback_trigger) {
@@ -5625,7 +5625,7 @@ int main_config_update(int argc, char **argv)
 printf_info(default_output_format, -1, &d_config, stdout);
 
 if (!dryrun_only) {
-fprintf(stderr, "setting dom%d configuration\n", domid);
+fprintf(stderr, "setting dom%u configuration\n", domid);
 rc = libxl_userdata_store(ctx, domid, "xl",
config_data, config_len);
 if (rc) {
@@ -5951,7 +5951,7 @@ static int vcpuset(uint32_t domid, const char* nr_vcpus, 
int check_host)
 if (rc == ERROR_DOMAIN_NOTFOUND)
 fprintf(stderr, "Domain %u does not exist.\n", domid);
 else if (rc)
-fprintf(stderr, "libxl_set_vcpuonline failed domid=%d max_vcpus=%d," \
+fprintf(stderr, "libxl_set_vcpuonline failed domid=%u max_vcpus=%d," \
 " rc: %d\n", domid, max_vcpus, rc);
 
 libxl_bitmap_dispose(&cpumap);
@@ -7113,7 +7113,7 

[Xen-devel] [PATCH] tools/xl: Use %u for uint32_t domids

2016-10-16 Thread Ronald Rojas
domid is normally represented by uint32_t, but many format
strings in xl_cmdimpl.c use %d when printing, which is signed.
Use %u instead to print the unsigned integer domid.

Signed-off-by: Ronald Rojas 
---
 tools/libxl/xl_cmdimpl.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index cb43c00..b154e36 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2674,7 +2674,7 @@ static int preserve_domain(uint32_t *r_domid, libxl_event 
*event,
 
 libxl_uuid_generate(&new_uuid);
 
-LOG("Preserving domain %d %s with suffix%s",
+LOG("Preserving domain %u %s with suffix%s",
 *r_domid, d_config->c_info.name, strtime);
 rc = libxl_domain_preserve(ctx, *r_domid, &d_config->c_info,
strtime, new_uuid);
@@ -2758,7 +2758,7 @@ static int domain_wait_event(uint32_t domid, libxl_event 
**event_r)
 for (;;) {
 ret = libxl_event_wait(ctx, event_r, LIBXL_EVENTMASK_ALL, 0,0);
 if (ret) {
-LOG("Domain %d, failed to get event, quitting (rc=%d)", domid, 
ret);
+LOG("Domain %u, failed to get event, quitting (rc=%d)", domid, 
ret);
 return ret;
 }
 if ((*event_r)->domid != domid) {
@@ -3108,7 +3108,7 @@ start:
 }
 need_daemon = 0;
 }
-LOG("Waiting for domain %s (domid %d) to die [pid %ld]",
+LOG("Waiting for domain %s (domid %u) to die [pid %ld]",
 d_config.c_info.name, domid, (long)getpid());
 
 ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
@@ -3134,7 +3134,7 @@ start:
 switch (event->type) {
 
 case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
-LOG("Domain %d has shut down, reason code %d 0x%x", domid,
+LOG("Domain %u has shut down, reason code %d 0x%x", domid,
 event->u.domain_shutdown.shutdown_reason,
 event->u.domain_shutdown.shutdown_reason);
 switch (handle_domain_death(&domid, event, &d_config)) {
@@ -3198,7 +3198,7 @@ start:
 }
 
 case LIBXL_EVENT_TYPE_DOMAIN_DEATH:
-LOG("Domain %d has been destroyed.", domid);
+LOG("Domain %u has been destroyed.", domid);
 libxl_event_free(ctx, event);
 ret = 0;
 goto out;
@@ -3442,7 +3442,7 @@ static int set_memory_max(uint32_t domid, const char *mem)
 }
 
 if (libxl_domain_setmaxmem(ctx, domid, memorykb)) {
-fprintf(stderr, "cannot set domid %d static max memory to : %s\n", 
domid, mem);
+fprintf(stderr, "cannot set domid %u static max memory to : %s\n", 
domid, mem);
 return EXIT_FAILURE;
 }
 
@@ -3476,7 +3476,7 @@ static int set_memory_target(uint32_t domid, const char 
*mem)
 }
 
 if (libxl_set_memory_target(ctx, domid, memorykb, 0, /* enforce */ 1)) {
-fprintf(stderr, "cannot set domid %d dynamic max memory to : %s\n", 
domid, mem);
+fprintf(stderr, "cannot set domid %u dynamic max memory to : %s\n", 
domid, mem);
 return EXIT_FAILURE;
 }
 
@@ -4133,7 +4133,7 @@ static void shutdown_domain(uint32_t domid,
 {
 int rc;
 
-fprintf(stderr, "Shutting down domain %d\n", domid);
+fprintf(stderr, "Shutting down domain %u\n", domid);
 rc=libxl_domain_shutdown(ctx, domid);
 if (rc == ERROR_NOPARAVIRT) {
 if (fallback_trigger) {
@@ -4165,7 +4165,7 @@ static void reboot_domain(uint32_t domid, 
libxl_evgen_domain_death **deathw,
 {
 int rc;
 
-fprintf(stderr, "Rebooting domain %d\n", domid);
+fprintf(stderr, "Rebooting domain %u\n", domid);
 rc=libxl_domain_reboot(ctx, domid);
 if (rc == ERROR_NOPARAVIRT) {
 if (fallback_trigger) {
@@ -5625,7 +5625,7 @@ int main_config_update(int argc, char **argv)
 printf_info(default_output_format, -1, &d_config, stdout);
 
 if (!dryrun_only) {
-fprintf(stderr, "setting dom%d configuration\n", domid);
+fprintf(stderr, "setting dom%u configuration\n", domid);
 rc = libxl_userdata_store(ctx, domid, "xl",
config_data, config_len);
 if (rc) {
@@ -5951,7 +5951,7 @@ static int vcpuset(uint32_t domid, const char* nr_vcpus, 
int check_host)
 if (rc == ERROR_DOMAIN_NOTFOUND)
 fprintf(stderr, "Domain %u does not exist.\n", domid);
 else if (rc)
-fprintf(stderr, "libxl_set_vcpuonline failed domid=%d max_vcpus=%d," \
+fprintf(stderr, "libxl_set_vcpuonline failed domid=%u max_vcpus=%d," \
 " rc: %d\n", domid, max_vcpus, rc);
 
 libxl_bitmap_dispose(&cpumap);
@@ -7113,7 +7113,7 

Re: [Xen-devel] Outreachy golang bindings planning

2016-10-17 Thread Ronald Rojas
On Wed, Oct 12, 2016 at 12:49:18PM +0100, George Dunlap wrote:
> Hey Ronald,
> 
> My ultimate vision for the libxl golang project is to have the following:
> 
> - Golang bindings for all core libxl functionality
> - A test program which exersises as much of that functionality as is
> reasonable
> 
> The C libxl library has two components: parts that are written by hand
> (such as libxl.h and libxl_*.c), and parts that are generated
> programmatically by the IDL compiler (such as _libxl_types.h and
> _libxl_types.c).  I think the end goal should be to extend the IDL to
> generate at least the Golang types, and probably a lot of the "helper"
> methods as well (such as ${TYPE}.String() or ${TYPE}.FromString()).
> 
> But before diving into the I think it makes sense to first implement a
> core set of functionality by hand, to see what the shape of the library
> looks like, then implement the type-generation part of the IDL.  Other
> things we might do with the IDL, such as generation of utility methods,
> we can add in at later points as well.
> 
> At the bottom of this mail, I've got all the libxl functions from
> libxl.h sorted into what seems to me a useful order to start working on
> things.
> 
> I list here the "headers".  This is a *lot* of functionality; I very
> greatly doubt that it will be possible to get all of it implemented and
> tested during the internship.  I'd much rather have a decent core set of
> functionality with a really good testing than attempt to get all the
> functions "implemented" in a way which nobody knows if it works.
> 
> If we can get the basic IDL working, and stuff implemented and
> well-tested through "Secondary host operations", I think the internship
> will have been a solid success.  If we get through "Devices: PCI", I
> think it will have been a wild success. :-)
> 

It looks like due to the large timezone difference that we have I'm not able to
catch you on #xen-devel a lot of the time so I may start relying on email 
a bit more, anyway...

I made a quick timeline in a google doc that outlines what I think I can 
accomplish during the duration of the Outreachy internship which I will link 
below(1). I gave it a fairly optimistic view of what could be done so that if 
anything happens, like an emergency or maybe something is harder then expected,
enough should still be accomplished during the internship period so that it'll 
still be considered a success. Feel free to edit it however you want. 

Since the application would have been due later today, October 17 7:00PM UTC, 
I tentatively submitted the application. It can be edited until November 8th 
so if you think I should change anything let me know and I'll do that as soon
as I can. I'm not sure if you can view my application now but I will provide
a link to a google doc that will have exactly what I submitted on my 
application(2). You should be able to edit it if you want to. 
 
Notes on school:
I have most of my midterms next week so I probably won't be able to contribute 
much then. I will try to finish all of the major problems this week, like 
finalizing the application and the project timeline. Then in two weeks I will 
have the time to do some more work, like creating the Makefile for the golang 
binding project. 

Links:
(1) 
https://docs.google.com/document/d/1X1Xyb8YBGcBsfDH1oDsUPQM8lwCLYrJQmgV52HStY6o/edit?usp=sharing
(2) 
https://docs.google.com/document/d/1yfVc5eJlIeQYiccuvu6YMLUm4_uGJOypOYjM_zmd6HQ/edit?usp=sharing

Thanks, 
Ronald Rojas

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] Outreachy golang bindings planning

2016-11-14 Thread Ronald Rojas
On Fri, Nov 11, 2016 at 12:42:52PM +, Lars Kurth wrote:
> Ronald,
> I am not sure whether you checked the Outreachy page and apologies for 
> getting back late, but this project has been accepted. Let me know of your 
> own blog and whether you'd be willing to write a guest blog or let me cover a 
> quick blog on blog.xenproject.org as an introduction to the community. I 
> would need a few sentences about yourself, what motivates you, what you are 
> trying to achieve though.

Hi Lars,
I just found out I was accepted to the outreachy program a few days ago, so 
thanks Lars and George for accepting the project! I don't have a blog but I 
know that the outreachy program reccomends a blog for the program. I will 
probably be setting up a wordpress site in the next few days and will let you
know when I get that done. 
For the Xen Project blog you can use the following:
I'm a 3rd year student at New York University studying computer science. I'm
also from New York City so New York has always been my home. This will be my 
first time working in a FOSS project and I'm really looking forward to it. 
When I first started applying to outreachy was when I first learned 
about Xen. I thought the idea was really cool and it's something that I was
already interested in so I decided to put my efforts into this project. What I 
wanted from this project was a good way to get involved with open source 
projects and to start contibuting. Once the internship is over I think I will 
try to complete my project andd try to contribute to xen in other areas as 
well. 
Feel free to paraphase what I wrote or let me know if you need more 
information. 

Ronald Rojas
> 
> > On 17 Oct 2016, at 18:15, Ronald Rojas  wrote:
> > 
> > On Wed, Oct 12, 2016 at 12:49:18PM +0100, George Dunlap wrote:
> >> Hey Ronald,
> >> 
> >> My ultimate vision for the libxl golang project is to have the following:
> >> 
> >> - Golang bindings for all core libxl functionality
> >> - A test program which exersises as much of that functionality as is
> >> reasonable
> >> 
> >> The C libxl library has two components: parts that are written by hand
> >> (such as libxl.h and libxl_*.c), and parts that are generated
> >> programmatically by the IDL compiler (such as _libxl_types.h and
> >> _libxl_types.c).  I think the end goal should be to extend the IDL to
> >> generate at least the Golang types, and probably a lot of the "helper"
> >> methods as well (such as ${TYPE}.String() or ${TYPE}.FromString()).
> >> 
> >> But before diving into the I think it makes sense to first implement a
> >> core set of functionality by hand, to see what the shape of the library
> >> looks like, then implement the type-generation part of the IDL.  Other
> >> things we might do with the IDL, such as generation of utility methods,
> >> we can add in at later points as well.
> >> 
> >> At the bottom of this mail, I've got all the libxl functions from
> >> libxl.h sorted into what seems to me a useful order to start working on
> >> things.
> >> 
> >> I list here the "headers".  This is a *lot* of functionality; I very
> >> greatly doubt that it will be possible to get all of it implemented and
> >> tested during the internship.  I'd much rather have a decent core set of
> >> functionality with a really good testing than attempt to get all the
> >> functions "implemented" in a way which nobody knows if it works.
> >> 
> >> If we can get the basic IDL working, and stuff implemented and
> >> well-tested through "Secondary host operations", I think the internship
> >> will have been a solid success.  If we get through "Devices: PCI", I
> >> think it will have been a wild success. :-)
> >> 
> > 
> > It looks like due to the large timezone difference that we have I'm not 
> > able to
> > catch you on #xen-devel a lot of the time so I may start relying on email 
> > a bit more, anyway...
> > 
> > I made a quick timeline in a google doc that outlines what I think I can 
> > accomplish during the duration of the Outreachy internship which I will 
> > link 
> > below(1). I gave it a fairly optimistic view of what could be done so that 
> > if 
> > anything happens, like an emergency or maybe something is harder then 
> > expected,
> > enough should still be accomplished during the internship period so that 
> > it'll 
> > still be considered a success. Feel free to edit it however you want. 
> > 
> > Since the applicati

[Xen-devel] (no subject)

2016-11-28 Thread Ronald Rojas
Create a Makefile for the golang xenlight project, which will
allow users to access libxl functionality in Golang. Makefile 
rules were also added to tools/Makefile for the project to be 
built and installed. A template Golang file was also created 
for the project to be properly built. 


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC] tools/xenlight: Create xenlight Makefile

2016-11-28 Thread Ronald Rojas
Created basic Makfele for the Golang xenlight
project so that the project is built and
installed. A template template is alo added.
---
 tools/Makefile| 15 +++
 tools/golang/xenlight/Makefile| 29 +
 tools/golang/xenlight/xenlight.go |  7 +++
 3 files changed, 51 insertions(+)
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 71515b4..b89f06b 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -11,6 +11,7 @@ SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
 SUBDIRS-y += xentrace
+SUBDIRS-y += golang/xenlight
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
 SUBDIRS-y += console
@@ -311,6 +312,20 @@ subdir-install-debugger/gdbsx: .phony
 subdir-all-debugger/gdbsx: .phony
$(MAKE) -C debugger/gdbsx all
 
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight all
+
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight clean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight install
+
+subdir-build-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight build
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight distclean
 
 subdir-clean-debugger/kdd subdir-distclean-debugger/kdd: .phony
$(MAKE) -C debugger/kdd clean
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..c723c1d
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,29 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlightgo
+GO = go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight
+
+.PHONY: install
+install: build
+   [ -f $(BINARY) ] || $(INSTALL_PROG) xenlight.go $(DESTDIR)$(bindir)
+
+.PHONY: clean
+clean:
+   $(RM) $(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+
+xenlight: xenlight.go
+   $(GO) build -o $(BINARY) xenlight.go
+
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..50e8d8d
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+   fmt.Println("vim-go")
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC] tools/xenlight: Create xenlight Makefile

2016-12-01 Thread Ronald Rojas
On Wed, Nov 30, 2016 at 12:30:04PM +1100, George Dunlap wrote:
> On Tue, Nov 29, 2016 at 4:18 AM, Ronald Rojas  wrote:
> > Created basic Makfele for the Golang xenlight
> > project so that the project is built and
> > installed. A template template is alo added.
> 
> Thanks Ronald!  Not a bad first submission, but a lot of things that
> need tightening up.
> 
> First, the normal style of most commit messages is more direct;
> usually in the form "Do X" (like a recipe), or in the form "We do Y".
> 
> So to translate the comment above, I'd probably say something like this:
> 
> "Create a basic Makefile to build and install libxenlight Golang
> bindings.  Also add a template."  (Or, as an example of the second
> form, "We also add a template so that we have something to build.")

Alright, I can change the commit message. I'm still getting used to
how to write patches but I'll keep it in mind of next time. 

> 
> But in the final patch, we'll probably be introducing all the libxl
> golang bindings in one go (not first the makefile, then the bindings,
> &c), so it probably makes sense to have your mock-up start with that
> assumption, then explain that it's still a work in progress.
> 
> The best way to do this is to put comments for the reviewers under a
> line with three dashes ("---") in the commit message.
> 
> So something like this:
> 
> 8<
> 
> tools: Introduce xenlight golang bindings
> 
> Create tools/golang/xenlight and hook it into the main tools Makefile.
> 
> Signed-off-by: John Smith 
> 
> ---
> 
> Eventually this patch will contain the actual bindings package; for
> now just include a stub package.
> 
> To do:
> - Make a real package
> - Have configure detect golang bindings properly
> 
> -->8

Understood :). I will do this in the next iteration of the patch

> 
> >  tools/Makefile| 15 +++
> >  tools/golang/xenlight/Makefile| 29 +
> >  tools/golang/xenlight/xenlight.go |  7 +++
> >  3 files changed, 51 insertions(+)
> >  create mode 100644 tools/golang/xenlight/Makefile
> >  create mode 100644 tools/golang/xenlight/xenlight.go
> >
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 71515b4..b89f06b 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -11,6 +11,7 @@ SUBDIRS-y += misc
> >  SUBDIRS-y += examples
> >  SUBDIRS-y += hotplug
> >  SUBDIRS-y += xentrace
> > +SUBDIRS-y += golang/xenlight
> 
> As Wei said, you should follow the python model, and put another
> Makefile in tools/golang.

Sorry but I don't really I don't really understand how the python
Makefile works. In particular I don't really understand how the 
build rule and setup.py works( maybe because I haven't written 
any python). Would you mind giving me some intuition on how it 
works?

> 
> And you should add a comment here saying that you plan to use
> autotools to do this eventually:
> 
> # FIXME: Have this controlled by a configure variable

Understood.

> 
> >  SUBDIRS-$(CONFIG_XCUTILS) += xcutils
> >  SUBDIRS-$(CONFIG_X86) += firmware
> >  SUBDIRS-y += console
> > @@ -311,6 +312,20 @@ subdir-install-debugger/gdbsx: .phony
> >  subdir-all-debugger/gdbsx: .phony
> > $(MAKE) -C debugger/gdbsx all
> >
> > +subdir-all-golang/xenlight: .phony
> > +   $(MAKE) -C golang/xenlight all
> > +
> > +subdir-clean-golang/xenlight: .phony
> > +   $(MAKE) -C golang/xenlight clean
> > +
> > +subdir-install-golang/xenlight: .phony
> > +   $(MAKE) -C golang/xenlight install
> > +
> > +subdir-build-golang/xenlight: .phony
> > +   $(MAKE) -C golang/xenlight build
> > +
> > +subdir-distclean-golang/xenlight: .phony
> > +   $(MAKE) -C golang/xenlight distclean
> >
> >  subdir-clean-debugger/kdd subdir-distclean-debugger/kdd: .phony
> > $(MAKE) -C debugger/kdd clean
> > diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> > new file mode 100644
> > index 000..c723c1d
> > --- /dev/null
> > +++ b/tools/golang/xenlight/Makefile
> > @@ -0,0 +1,29 @@
> > +XEN_ROOT=$(CURDIR)/../../..
> > +include $(XEN_ROOT)/tools/Rules.mk
> > +
> > +BINARY = xenlightgo
> > +GO = go
> > +
> > +.PHONY: all
> > +all: build
> > +
> > +.PHONY: build
> > +build: xenlight
> > +
> > +.PHONY: install
> > +install: build
> > +   [ -f $(BINARY) ] || $(INSTALL_PROG) xenlight.go $(DESTDIR)$(bindir)
> 
> Is there a reason you decided to make this a binary (and to install it
> as a binary), rather than making a stub package?
I'm not sure what you mean here. Doesn't this install the go file xenlight.go, 
not a binary file? 
Or do you want me to create a package and install that instead package? 
Sorry, I'm a little lost here.
> 
> Thanks,
>  -George
Thanks, 
Ronald 

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC] tools/xenlight: Create xenlight Makefile

2016-12-15 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings.  Also add a template.

---

Eventually this patch will contain the actual bindings package; for
now it just includes a stub package.

To Do:
- Have configure detect golang bindings properly

CC: xen-devel 
CC: Ian Jackson 
CC: Wei Liu 
CC: George Dunlap 
CC: George Dunlap 
---
 tools/Makefile| 16 
 tools/golang/Makefile | 33 +
 tools/golang/xenlight/xenlight.go |  7 +++
 3 files changed, 56 insertions(+)
 create mode 100644 tools/golang/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 71515b4..f2198e0 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -11,6 +11,8 @@ SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
 SUBDIRS-y += xentrace
+SUBDIRS-y += golang
+#FIXME: Have golang controlled by a configure variable
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
 SUBDIRS-y += console
@@ -311,6 +313,20 @@ subdir-install-debugger/gdbsx: .phony
 subdir-all-debugger/gdbsx: .phony
$(MAKE) -C debugger/gdbsx all
 
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang all
+
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang clean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang install
+
+subdir-build-golang/xenlight: .phony
+   $(MAKE) -C golang build
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang distclean
 
 subdir-clean-debugger/kdd subdir-distclean-debugger/kdd: .phony
$(MAKE) -C debugger/kdd clean
diff --git a/tools/golang/Makefile b/tools/golang/Makefile
new file mode 100644
index 000..eead226
--- /dev/null
+++ b/tools/golang/Makefile
@@ -0,0 +1,33 @@
+XEN_ROOT=$(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlight.a
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight/xenlight.a
+
+.PHONY: install
+install: build
+   if [ ! -f $(BINARY) ]; then \
+   mkdir $(GOPATH)/src/xenlight; \
+   $(INSTALL_PROG) xenlight/xenlight.go 
$(GOPATH)/src/xenlight/xenlight.go; \
+   echo "this"; \
+   fi  
+
+.PHONY: clean
+clean:
+   $(RM) $(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+
+xenlight/xenlight.a: xenlight/xenlight.go
+   $(GO) build -o $@ $<
+
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..9136676
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,7 @@
+package xenlight
+
+import "fmt"
+
+func main() {
+   fmt.Println("go")
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC] tools/xenlight: Create xenlight Makefile

2016-12-21 Thread Ronald Rojas
On Fri, Dec 16, 2016 at 12:27:31PM +0800, George Dunlap wrote:
> On Fri, Dec 16, 2016 at 7:20 AM, Ronald Rojas  wrote:
> > Create a basic Makefile to build and install libxenlight Golang
> > bindings.  Also add a template.
> 
> What's this template again?

I use 'template' to mean the same thing as 'stub package'. I can change the 
wording to say 'stub package' instead if that's more clear.
> 
> >
> > ---
> >
> > Eventually this patch will contain the actual bindings package; for
> > now it just includes a stub package.
> >
> > To Do:
> > - Have configure detect golang bindings properly
> >
> > CC: xen-devel 
> > CC: Ian Jackson 
> > CC: Wei Liu 
> > CC: George Dunlap 
> > CC: George Dunlap 
> > ---
> >  tools/Makefile| 16 
> >  tools/golang/Makefile | 33 +
> >  tools/golang/xenlight/xenlight.go |  7 +++
> >  3 files changed, 56 insertions(+)
> >  create mode 100644 tools/golang/Makefile
> >  create mode 100644 tools/golang/xenlight/xenlight.go
> >
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 71515b4..f2198e0 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -11,6 +11,8 @@ SUBDIRS-y += misc
> >  SUBDIRS-y += examples
> >  SUBDIRS-y += hotplug
> >  SUBDIRS-y += xentrace
> > +SUBDIRS-y += golang
> > +#FIXME: Have golang controlled by a configure variable
> >  SUBDIRS-$(CONFIG_XCUTILS) += xcutils
> >  SUBDIRS-$(CONFIG_X86) += firmware
> >  SUBDIRS-y += console
> > @@ -311,6 +313,20 @@ subdir-install-debugger/gdbsx: .phony
> >  subdir-all-debugger/gdbsx: .phony
> > $(MAKE) -C debugger/gdbsx all
> >
> > +subdir-all-golang/xenlight: .phony
> > +   $(MAKE) -C golang all
> > +
> > +subdir-clean-golang/xenlight: .phony
> > +   $(MAKE) -C golang clean
> > +
> > +subdir-install-golang/xenlight: .phony
> > +   $(MAKE) -C golang install
> > +
> > +subdir-build-golang/xenlight: .phony
> > +   $(MAKE) -C golang build
> > +
> > +subdir-distclean-golang/xenlight: .phony
> > +   $(MAKE) -C golang distclean
> >
> >  subdir-clean-debugger/kdd subdir-distclean-debugger/kdd: .phony
> > $(MAKE) -C debugger/kdd clean
> > diff --git a/tools/golang/Makefile b/tools/golang/Makefile
> > new file mode 100644
> > index 000..eead226
> > --- /dev/null
> > +++ b/tools/golang/Makefile
> > @@ -0,0 +1,33 @@
> > +XEN_ROOT=$(CURDIR)/../..
> > +include $(XEN_ROOT)/tools/Rules.mk
> > +
> > +BINARY = xenlight.a
> > +GO ?= go
> > +
> > +.PHONY: all
> > +all: build
> > +
> > +.PHONY: build
> > +build: xenlight/xenlight.a
> 
> I think eventually we'll want to have a makefile in tools/golang which
> calls the makefiles in tools/golang/xenlight and other directories;
> but since we have only one at the moment, I think this is probably
> fine.
I'll make a list so that if I have time late down the line, I'll remember 
to do this. 
> 
> > +.PHONY: install
> > +install: build
> > +   if [ ! -f $(BINARY) ]; then \
> > +   mkdir $(GOPATH)/src/xenlight; \
> > +   $(INSTALL_PROG) xenlight/xenlight.go 
> > $(GOPATH)/src/xenlight/xenlight.go; \
> > +   echo "this"; \
> > +   fi
> 
> A couple of things.
> 
> First, as we discussed on IRC, the if[] clause is not necessary --
> make will automatically stop if one of the prerequisites isn't
> available.
ok. I will delete the 'if' clause.
> 
> Secondly -- this is a bit confusing, but the "install" section of the
> parts of the tree that actually build things don't install files
> directly onto the host filesystem.  Instead, they install into
> $(DESTDIR) (which is xen.git/dist/install), and then the final step of
> "make install" will copy everything from dist/install into the host
> filesystem.
> 
> Also, you shouldn't do a plain mkdir, but should use $(INSTALL_DIR).
> And since the file you're installing is not going to be executed, you
> should use $(INSTALL_DATA).  (I didn't realize that distinction
> existed until I looked at tools/libxl/Makefile).
> 
> So this should look more like:
> 
> install: build
>   $(INSTALL_DIR) $(DESTDIR)$(GOLANG_SRC)
>   $(INSTALL_DATA) xenlight/xenlight.go $(DESTDIR)$(GOLANG_SRC)
Ok, I will change the the install rule with the appropriate changes
> 
> And we want the package name to be "xenproject.org/xenlight", so that
> we can put up a repo at git://xenproject.org/xenlight and have people
> download it automatically.  So GOLANG_SRC should be set by default to
> $(GOPATH)/src/xenproject.org/xenlight
Fixed
> 
> With that done I think we might be ready to add some golang code. :-)
> 
>  -George

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC] tools/xenlight: Create xenlight Makefile

2016-12-22 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings.  Also add a stub package.

---

Eventually this patch will contain the actual bindings package; for
now it just includes a stub package.

To Do:
- Have configure detect golang bindings properly

CC: xen-devel 
CC: Ian Jackson 
CC: Wei Liu 
CC: George Dunlap 
CC: George Dunlap 
---
 tools/Makefile| 16 
 tools/golang/Makefile | 29 +
 tools/golang/xenlight/xenlight.go |  7 +++
 3 files changed, 52 insertions(+)
 create mode 100644 tools/golang/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 71515b4..f2198e0 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -11,6 +11,8 @@ SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
 SUBDIRS-y += xentrace
+SUBDIRS-y += golang
+#FIXME: Have golang controlled by a configure variable
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
 SUBDIRS-y += console
@@ -311,6 +313,20 @@ subdir-install-debugger/gdbsx: .phony
 subdir-all-debugger/gdbsx: .phony
$(MAKE) -C debugger/gdbsx all
 
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang all
+
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang clean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang install
+
+subdir-build-golang/xenlight: .phony
+   $(MAKE) -C golang build
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang distclean
 
 subdir-clean-debugger/kdd subdir-distclean-debugger/kdd: .phony
$(MAKE) -C debugger/kdd clean
diff --git a/tools/golang/Makefile b/tools/golang/Makefile
new file mode 100644
index 000..96589c8
--- /dev/null
+++ b/tools/golang/Makefile
@@ -0,0 +1,29 @@
+XEN_ROOT=$(CURDIR)/../..
+GOLANG_SRC=$(GOPATH)/src/xenproject.org/xenlight
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlight.a
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight/xenlight.a
+
+.PHONY: install
+install: build
+   $(INSTALL_DIR) $(DESTDIR)$(GOLANG_SRC)
+   $(INSTALL_DATA) xenlight/xenlight.go $(DESTDIR)$(GOLANG_SRC)
+
+.PHONY: clean
+clean:
+   $(RM) xenlight/$(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+xenlight/xenlight.a: xenlight/xenlight.go
+   $(GO) build -o $@ $<
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..9136676
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,7 @@
+package xenlight
+
+import "fmt"
+
+func main() {
+   fmt.Println("go")
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] (no subject)

2016-12-28 Thread Ronald Rojas
The first 57 commits are merged from previous work done by 
George Dunlap at (https://github.com/gwd/schedbench) and 
implement manipulating Cpu pool. The last 2 commits merge 
his work onto the Xen tree and implement finding system 
information and throwing errors.

CC: xen-devel 
CC: Ian Jackson 
CC: Wei Liu 
CC: George Dunlap 
CC: George Dunlap 


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 01/59] Initial controller framework

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Go code to execute a worker and parse its output.

The go json marshaller needs capitalized structure elements; make the
output match.

Also add fflush()-es to make sure that output actually gets to the controller
in a timely manner.

Signed-off-by: George Dunlap 
---
 Makefile | 12 ++
 main.go  | 78 
 2 files changed, 90 insertions(+)
 create mode 100644 Makefile
 create mode 100644 main.go

diff --git a/Makefile b/Makefile
new file mode 100644
index 000..736d959
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+BIN = controller
+BINALL = $(BIN)
+
+.PHONY: all
+all: $(BIN)
+
+controller: main.go
+   go build -o $@ $<
+
+.PHONY: clean
+clean:
+   rm -f $(BINALL)
diff --git a/main.go b/main.go
new file mode 100644
index 000..6e90754
--- /dev/null
+++ b/main.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+   "fmt"
+   "os/exec"
+   "encoding/json"
+   "bufio"
+   "io"
+)
+
+type Worker struct {
+   c *exec.Cmd
+
+   stdout io.ReadCloser
+   
+   jsonStarted bool
+}
+
+type WorkerReport struct {
+   Now int
+   Mops int
+   MaxDelta int
+}
+
+func (w *Worker) Start() (err error) {
+   w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
+   
+
+   w.stdout, err = w.c.StdoutPipe()
+   if err != nil {
+   fmt.Print("Conneting to stdout: ", err)
+   return
+   }
+
+   w.c.Start()
+
+   b, err := json.Marshal(WorkerReport{5,6,7})
+   fmt.Print("Example json: ", string(b))
+   
+   return
+}
+
+func (w *Worker) Wait() {
+   w.c.Wait()
+}
+
+func (w *Worker) Process() {
+   scanner := bufio.NewScanner(w.stdout)
+
+   for scanner.Scan() {
+   s := scanner.Text()
+   
+   fmt.Println("Got these bytes: ", s);
+
+   if w.jsonStarted {
+   var r WorkerReport
+   
+   json.Unmarshal([]byte(s), &r)
+   fmt.Println(r)
+   } else {
+   if s == "START JSON" {
+   fmt.Println("Got token to start parsing json")
+   w.jsonStarted = true
+   }
+   }
+   }
+}
+
+func main() {
+
+   w:=Worker{}
+   
+   w.Start()
+
+   w.Process()
+
+   w.Wait()
+}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 02/59] controller: Revamp communication structure

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Two general-purporse channels rather than one per worker.

Set up two workers, gather and collate the information at the central
station.

Have the worker print out a report at start-of-day, so we get timing
information for the first actual report.

Catch SIGINT as a shorthand testing way of managing tear-down
gracefully.

Signed-off-by: George Dunlap 
---
 main.go | 96 -
 1 file changed, 78 insertions(+), 18 deletions(-)

diff --git a/main.go b/main.go
index 6e90754..0cb9f51 100644
--- a/main.go
+++ b/main.go
@@ -2,13 +2,18 @@ package main
 
 import (
"fmt"
+   "os"
"os/exec"
+   "os/signal"
"encoding/json"
"bufio"
"io"
+   
 )
 
 type Worker struct {
+   Id int
+   
c *exec.Cmd
 
stdout io.ReadCloser
@@ -17,14 +22,14 @@ type Worker struct {
 }
 
 type WorkerReport struct {
+   Id int
Now int
Mops int
MaxDelta int
 }
 
-func (w *Worker) Start() (err error) {
+func (w *Worker) Init() (err error) {
w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
-   
 
w.stdout, err = w.c.StdoutPipe()
if err != nil {
@@ -32,47 +37,102 @@ func (w *Worker) Start() (err error) {
return
}
 
-   w.c.Start()
-
-   b, err := json.Marshal(WorkerReport{5,6,7})
-   fmt.Print("Example json: ", string(b))
-   
return
 }
 
-func (w *Worker) Wait() {
-   w.c.Wait()
+func (w *Worker) Shutdown() {
+   w.c.Process.Kill()
 }
 
-func (w *Worker) Process() {
+func (w *Worker) Process(report chan WorkerReport, done chan bool) {
+   w.c.Start()
+
scanner := bufio.NewScanner(w.stdout)
 
for scanner.Scan() {
s := scanner.Text()

-   fmt.Println("Got these bytes: ", s);
+   //fmt.Println("Got these bytes: ", s);
 
if w.jsonStarted {
var r WorkerReport
-   
json.Unmarshal([]byte(s), &r)
-   fmt.Println(r)
+   r.Id = w.Id
+   report <- r
} else {
if s == "START JSON" {
-   fmt.Println("Got token to start parsing json")
+   //fmt.Println("Got token to start parsing json")
w.jsonStarted = true
}
}
}
+
+   done <- true
+
+   w.c.Wait()
+}
+
+const (
+   USEC = 1000
+   MSEC = USEC * 1000
+   SEC = MSEC * 1000
+)
+
+type WorkerState struct {
+   Worker
+   LastReport WorkerReport
+}
+
+func Report(ws *WorkerState, r WorkerReport) {
+   //fmt.Println(r)
+
+   lr := ws.LastReport
+
+   if (lr.Now > 0) {
+   time := float64(r.Now - lr.Now) / SEC
+   mops := r.Mops - lr.Mops
+
+   tput := float64(mops) / time
+
+   fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
+   }
+
+   ws.LastReport = r
 }
 
 func main() {
+   count := 2
+   
+   report := make(chan WorkerReport)
+   done := make(chan bool)
+   signals := make(chan os.Signal, 1)
 
-   w:=Worker{}
+   signal.Notify(signals, os.Interrupt)

-   w.Start()
+   i := 0
 
-   w.Process()
+   Workers := make([]WorkerState, count)
+   
+   for i = 0; i< count; i++ {
+   Workers[i].Id = i
+   
+   Workers[i].Init()
+   
+   go Workers[i].Process(report, done)
+   }
 
-   w.Wait()
+   for i > 0 {
+   select {
+   case r := <-report:
+   Report(&Workers[r.Id], r)
+   case <-done:
+   i--;
+   fmt.Println(i, "workers left");
+   case <-signals:
+   fmt.Println("SIGINT receieved, shutting down workers")
+   for j := range Workers {
+   Workers[j].Shutdown()
+   }
+   }
+   }
 }
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 05/59] controller: Add WorkerParams argument to Init in Worker interface

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

For now just make it a plain []string; later make it more abstrcted.

Signed-off-by: George Dunlap 
---
 main.go  | 22 +-
 processworker.go |  4 ++--
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/main.go b/main.go
index a4986cf..90388dd 100644
--- a/main.go
+++ b/main.go
@@ -14,9 +14,13 @@ type WorkerReport struct {
MaxDelta int
 }
 
+type WorkerParams struct {
+   Args []string
+}
+
 type Worker interface {
SetId(int)
-   Init() error
+   Init(WorkerParams) error
Shutdown()
Process(chan WorkerReport, chan bool)
 }
@@ -49,6 +53,14 @@ func Report(ws *WorkerState, r WorkerReport) {
ws.LastReport = r
 }
 
+type WorkerList []WorkerState
+
+func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) {
+   for i := range *ws {
+   go (*ws)[i].w.Process(report, done)
+   }
+}
+
 func main() {
count := 2

@@ -60,17 +72,17 @@ func main() {

i := 0
 
-   Workers := make([]WorkerState, count)
+   Workers := WorkerList(make([]WorkerState, count))

for i = 0; i< count; i++ {
Workers[i].w = &ProcessWorker{}
Workers[i].w.SetId(i)

-   Workers[i].w.Init()
-   
-   go Workers[i].w.Process(report, done)
+   Workers[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
}
 
+   Workers.Start(report, done)
+
for i > 0 {
select {
case r := <-report:
diff --git a/processworker.go b/processworker.go
index c1d1fd5..806e4d7 100644
--- a/processworker.go
+++ b/processworker.go
@@ -20,8 +20,8 @@ func (w *ProcessWorker) SetId(i int) {
w.id = i
 }
 
-func (w *ProcessWorker) Init() (err error) {
-   w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
+func (w *ProcessWorker) Init(p WorkerParams) (err error) {
+   w.c = exec.Command("../worker/worker-proc", p.Args...)
 
w.stdout, err = w.c.StdoutPipe()
if err != nil {
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 04/59] Controller: Move process worker into its own file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Also fix Makefile rule to use correct automatic variable.

Signed-off-by: George Dunlap 
---
 Makefile |  4 ++--
 main.go  | 59 --
 processworker.go | 66 
 3 files changed, 68 insertions(+), 61 deletions(-)
 create mode 100644 processworker.go

diff --git a/Makefile b/Makefile
index 736d959..00f732a 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-controller: main.go
-   go build -o $@ $<
+controller: main.go processworker.go
+   go build -o $@ $^
 
 .PHONY: clean
 clean:
diff --git a/main.go b/main.go
index 034e2f2..a4986cf 100644
--- a/main.go
+++ b/main.go
@@ -3,11 +3,7 @@ package main
 import (
"fmt"
"os"
-   "os/exec"
"os/signal"
-   "encoding/json"
-   "bufio"
-   "io"

 )
 
@@ -25,61 +21,6 @@ type Worker interface {
Process(chan WorkerReport, chan bool)
 }
 
-type ProcessWorker struct {
-   id int
-   c *exec.Cmd
-   stdout io.ReadCloser
-   jsonStarted bool
-}
-
-func (w *ProcessWorker) SetId(i int) {
-   w.id = i
-}
-
-func (w *ProcessWorker) Init() (err error) {
-   w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
-
-   w.stdout, err = w.c.StdoutPipe()
-   if err != nil {
-   fmt.Print("Conneting to stdout: ", err)
-   return
-   }
-
-   return
-}
-
-func (w *ProcessWorker) Shutdown() {
-   w.c.Process.Kill()
-}
-
-func (w *ProcessWorker) Process(report chan WorkerReport, done chan bool) {
-   w.c.Start()
-
-   scanner := bufio.NewScanner(w.stdout)
-
-   for scanner.Scan() {
-   s := scanner.Text()
-   
-   //fmt.Println("Got these bytes: ", s);
-
-   if w.jsonStarted {
-   var r WorkerReport
-   json.Unmarshal([]byte(s), &r)
-   r.Id = w.id
-   report <- r
-   } else {
-   if s == "START JSON" {
-   //fmt.Println("Got token to start parsing json")
-   w.jsonStarted = true
-   }
-   }
-   }
-
-   done <- true
-
-   w.c.Wait()
-}
-
 const (
USEC = 1000
MSEC = USEC * 1000
diff --git a/processworker.go b/processworker.go
new file mode 100644
index 000..c1d1fd5
--- /dev/null
+++ b/processworker.go
@@ -0,0 +1,66 @@
+package main
+
+import (
+   "fmt"
+   "os/exec"
+   "encoding/json"
+   "bufio"
+   "io"
+   
+)
+
+type ProcessWorker struct {
+   id int
+   c *exec.Cmd
+   stdout io.ReadCloser
+   jsonStarted bool
+}
+
+func (w *ProcessWorker) SetId(i int) {
+   w.id = i
+}
+
+func (w *ProcessWorker) Init() (err error) {
+   w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
+
+   w.stdout, err = w.c.StdoutPipe()
+   if err != nil {
+   fmt.Print("Conneting to stdout: ", err)
+   return
+   }
+
+   return
+}
+
+func (w *ProcessWorker) Shutdown() {
+   w.c.Process.Kill()
+}
+
+func (w *ProcessWorker) Process(report chan WorkerReport, done chan bool) {
+   w.c.Start()
+
+   scanner := bufio.NewScanner(w.stdout)
+
+   for scanner.Scan() {
+   s := scanner.Text()
+   
+   //fmt.Println("Got these bytes: ", s);
+
+   if w.jsonStarted {
+   var r WorkerReport
+   json.Unmarshal([]byte(s), &r)
+   r.Id = w.id
+   report <- r
+   } else {
+   if s == "START JSON" {
+   //fmt.Println("Got token to start parsing json")
+   w.jsonStarted = true
+   }
+   }
+   }
+
+   done <- true
+
+   w.c.Wait()
+}
+
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 08/59] controller: Exit after second SIGINT

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Otherwise you have to kill -9 the process.

Signed-off-by: George Dunlap 
---
 main.go | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/main.go b/main.go
index 04c8467..dbd6276 100644
--- a/main.go
+++ b/main.go
@@ -62,6 +62,8 @@ func (ws *WorkerList) Start(report chan WorkerReport, done 
chan bool) {
 }
 
 func main() {
+   killed := false
+   
count := 2

report := make(chan WorkerReport)
@@ -92,9 +94,15 @@ func main() {
i--;
fmt.Println(i, "workers left");
case <-signals:
-   fmt.Println("SIGINT receieved, shutting down workers")
-   for j := range Workers {
-   Workers[j].w.Shutdown()
+   if ! killed {
+   fmt.Println("SIGINT receieved, shutting down 
workers")
+   for j := range Workers {
+   Workers[j].w.Shutdown()
+   }
+   killed = true
+   } else {
+   fmt.Println("Second SIGINT received, exiting 
without cleaning up")
+   os.Exit(1)
}
}
}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 06/59] Reorganize to enable "Dist" directory

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Make a toplevel Makefile which defaults to 'make dist'.  Add "make
dist" targets in all subdirs, which copy the distribution files into
$PWD/dist.

Modify processworker.go such that it looks for worker-proc in the same
directory.

Signed-off-by: George Dunlap 
---
 Makefile | 4 
 processworker.go | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 00f732a..332c8d9 100644
--- a/Makefile
+++ b/Makefile
@@ -10,3 +10,7 @@ controller: main.go processworker.go
 .PHONY: clean
 clean:
rm -f $(BINALL)
+
+.PHONY: dist
+dist:
+   cp $(BIN) $(DISTDIR)
diff --git a/processworker.go b/processworker.go
index 806e4d7..cca6c3b 100644
--- a/processworker.go
+++ b/processworker.go
@@ -21,7 +21,7 @@ func (w *ProcessWorker) SetId(i int) {
 }
 
 func (w *ProcessWorker) Init(p WorkerParams) (err error) {
-   w.c = exec.Command("../worker/worker-proc", p.Args...)
+   w.c = exec.Command("./worker-proc", p.Args...)
 
w.stdout, err = w.c.StdoutPipe()
if err != nil {
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 07/59] controller: Introduce basic Xen functionality

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Rough-and-ready execution of xl commands, but they work, amazingly.

Signed-off-by: George Dunlap 
---
 Makefile |   2 +-
 main.go  |   3 +-
 xenworker.go | 231 +++
 3 files changed, 234 insertions(+), 2 deletions(-)
 create mode 100644 xenworker.go

diff --git a/Makefile b/Makefile
index 332c8d9..16af528 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-controller: main.go processworker.go
+controller: main.go processworker.go xenworker.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/main.go b/main.go
index 90388dd..04c8467 100644
--- a/main.go
+++ b/main.go
@@ -75,7 +75,8 @@ func main() {
Workers := WorkerList(make([]WorkerState, count))

for i = 0; i< count; i++ {
-   Workers[i].w = &ProcessWorker{}
+   //Workers[i].w = &ProcessWorker{}
+   Workers[i].w = &XenWorker{}
Workers[i].w.SetId(i)

Workers[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
diff --git a/xenworker.go b/xenworker.go
new file mode 100644
index 000..6023c50
--- /dev/null
+++ b/xenworker.go
@@ -0,0 +1,231 @@
+package main
+
+import (
+   "fmt"
+   "os"
+   "os/exec"
+   "encoding/json"
+   "bufio"
+   "io"
+)
+
+type XenWorker struct {
+   id int
+   vmname string
+   domid int
+   consoleCmd *exec.Cmd
+   console io.ReadCloser
+   jsonStarted bool
+}
+
+// We have to capitalize the element names so that the json class can
+// get access to it; so annotate the elements so they come out lower
+// case
+type RumpRunConfigBlk struct {
+   Source string `json:"source"`
+   Path string   `json:"path"`
+   Fstype string `json:"fstype"` 
+   Mountpoint string `json:"mountpoint"`
+}
+
+type RumpRunConfig struct {
+   Blk RumpRunConfigBlk `json:"blk"`
+   Cmdline string   `json:"cmdline"`
+   Hostname string  `json:"hostname"`
+}
+
+func (w *XenWorker) SetId(i int) {
+   w.id = i
+   w.vmname = fmt.Sprintf("worker-%d", i)
+   w.domid = -1 // INVALID DOMID
+}
+
+func (w *XenWorker) Init(p WorkerParams) (err error) {
+   mock := false
+   
+   // Make xl config file
+   //  name=worker-$(id)
+
+   cfgName := os.TempDir()+"/schedbench-"+w.vmname+".cfg"
+
+   cfg, err := os.Create(cfgName)
+   //defer os.Remove(cfgName)
+
+   if err != nil {
+   fmt.Printf("Error creating configfile %s: %v\n", cfgName, err)
+   return
+   }
+
+   fmt.Fprintf(cfg, "name = '%s'\n", w.vmname)
+   fmt.Fprintf(cfg, "kernel = 'worker-xen.img'\n")
+   fmt.Fprintf(cfg, "memory = 32\n")
+   fmt.Fprintf(cfg, "vcpus = 1\n")
+   fmt.Fprintf(cfg, "on_crash = 'destroy'\n")
+
+   
+   // xl create -p [filename]
+   {
+   args := []string{"xl", "create", "-p", cfgName}
+   if mock {
+   args = append([]string{"echo"}, args...)
+   }
+   e := exec.Command(args[0], args[1:]...)
+   
+   e.Stdout = os.Stdout
+   e.Stderr = os.Stderr
+
+   err = e.Run()
+   if err != nil {
+   fmt.Printf("Error creating domain: %v\n", err)
+   return
+   }
+   }
+
+   // Get domid
+   {
+   var domidString []byte
+   var args []string
+   
+   if mock {
+   args = []string{"echo", "232"}
+   } else {
+   args = []string{"xl", "domid", w.vmname}
+   }
+   e := exec.Command(args[0], args[1:]...)
+
+   domidString, err = e.Output()
+   if err != nil {
+   fmt.Printf("Error getting domid: %v\n", err)
+   return
+   }
+
+   _, err = fmt.Sscanf(string(domidString), "%d\n", &w.domid)
+   if err != nil {
+   fmt.Printf("Error converting domid: %v\n", err)
+   return
+   }
+
+   fmt.Printf(" %s domid %d\n", w.vmname, w.domid)
+   }
+   
+   // Set xenstore config
+   {
+   rcfg := RumpRunConfig{
+   Blk:RumpRunConfigBlk{Source:"dev",
+   Path:"virtual",
+   Fstype:"kernfs",
+   Mountpoint:"/kern"},
+   Hostname:w.vmname}
+   
+   rcfg.Cmdline = "worker-xen.img"
+   for _, a := range p.Args {
+   rcfg.Cmdline += fmt.Sprintf(" %s", a)
+   }
+
+   var rcfgBytes []byte
+   
+   rcfgBytes, err = json.Marshal(rcfg)
+   if err 

[Xen-devel] [PATCH RFC 25/59] main: Change default workload to something a bit more extreme

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 main.go | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/main.go b/main.go
index bb46dbc..61d3949 100644
--- a/main.go
+++ b/main.go
@@ -29,15 +29,15 @@ func main() {
 
switch(os.Args[1]) {
case "plan":
-   workerA := []string{"burnwait", "20", "2000"}
+   workerA := []string{"burnwait", "1", "2000"}
//workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "1", "2000",
-   "burnwait", "2", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "3", "2000",
+   workerB := []string{"burnwait", "1", "3000",
+   "burnwait", "2", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "3", "3000",
}
 
 
@@ -58,7 +58,6 @@ func main() {
RuntimeSeconds:10,},
}}
 
-
for i := 1; i <= 16 ; i *= 2 {
label := fmt.Sprintf("%da+%db", i, i)
run := BenchmarkRun{
@@ -98,7 +97,7 @@ func main() {
os.Exit(1)
}

-   err = plan.TextReport(2)
+   err = plan.TextReport(0)
if err != nil {
fmt.Println("Running benchmark run:", err)
os.Exit(1)
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 10/59] controller: First cut at BenchmarkParams

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Struct for configurable worker sets, as well as a set runtime.

Signed-off-by: George Dunlap 
---
 main.go | 75 ++---
 1 file changed, 53 insertions(+), 22 deletions(-)

diff --git a/main.go b/main.go
index 89e9cf3..7fbb60a 100644
--- a/main.go
+++ b/main.go
@@ -4,7 +4,7 @@ import (
"fmt"
"os"
"os/signal"
-   
+   "time"
 )
 
 type WorkerReport struct {
@@ -18,6 +18,16 @@ type WorkerParams struct {
Args []string
 }
 
+type WorkerSet struct {
+   Params WorkerParams
+   Count int
+}
+
+type BenchmarkParams struct {
+   Workers []WorkerSet
+   RuntimeSeconds int
+}
+
 type Worker interface {
SetId(int)
Init(WorkerParams) error
@@ -75,29 +85,53 @@ const (
WorkerXen = iota
 )
 
-func NewWorkerList(count int, workerType int) (ws WorkerList, err error) {
+func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
+   count := 0
+
+   // wsi: WorkerSet index
+   for wsi := range workers {
+   count += workers[wsi].Count
+   }
+
+   fmt.Println("Making ", count, " total workers")
ws = WorkerList(make([]WorkerState, count))
 
-   for i := 0; i< count; i++ {
-   switch workerType {
-   case WorkerProcess:
-   ws[i].w = &ProcessWorker{}
-   case WorkerXen:
-   ws[i].w = &XenWorker{}
-   default:
-   err = fmt.Errorf("Unknown type: %d", workerType)
-   }
-   ws[i].w.SetId(i)
+   // wli: WorkerList index
+   wli := 0
+   for wsi := range workers {
+   for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+   switch workerType {
+   case WorkerProcess:
+   ws[wli].w = &ProcessWorker{}
+   case WorkerXen:
+   ws[wli].w = &XenWorker{}
+   default:
+   err = fmt.Errorf("Unknown type: %d", workerType)
+   }
+   ws[wli].w.SetId(wli)

-   ws[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
+   ws[wli].w.Init(workers[wsi].Params)
+   }
}
return
 }
 
 func main() {
-   killed := false
-   
-   count := 2
+   bp :=  BenchmarkParams{
+   Workers:[]WorkerSet{
+   {Params:WorkerParams{[]string{"burnwait", "20", 
"2000"}},
+   Count:2},
+   {Params:WorkerParams{[]string{"burnwait", "10", 
"3000"}},
+   Count:3},
+   },
+   RuntimeSeconds:5,
+   }
+
+   Workers, err := NewWorkerList(bp.Workers, WorkerProcess)
+   if err != nil {
+   fmt.Println("Error creating workers: %v", err)
+   return
+   }

report := make(chan WorkerReport)
done := make(chan bool)
@@ -105,14 +139,10 @@ func main() {
 
signal.Notify(signals, os.Interrupt)

-   Workers, err := NewWorkerList(count, WorkerProcess)
-   if err != nil {
-   fmt.Println("Error creating workers: %v", err)
-   return
-   }
-   
i := Workers.Start(report, done)
 
+   timeout := time.After(time.Duration(bp.RuntimeSeconds) * time.Second);
+   killed := false
for i > 0 {
select {
case r := <-report:
@@ -121,6 +151,7 @@ func main() {
i--;
fmt.Println(i, "workers left");
case <-signals:
+   case <-timeout:
if ! killed {
fmt.Println("SIGINT receieved, shutting down 
workers")
Workers.Stop()
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 20/59] xenworker: Use libxl_domain_unpause rather than forking xl

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Unpause is a time-sensitive operation; use libxl to unpause directly
rather than forking and execing xl for each VM.

Signed-off-by: George Dunlap 
---
 libxl.go | 14 ++
 xenworker.go | 12 ++--
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/libxl.go b/libxl.go
index 39e47ab..415de7f 100644
--- a/libxl.go
+++ b/libxl.go
@@ -114,3 +114,17 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err 
error) {
di.Domain_type = int32(cdi.domain_type)
return
 }
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   return
+   }
+
+   ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
+
+   if ret != 0 {
+   err = fmt.Errorf("libxl_domain_unpause failed: %d", ret)
+   }
+   return
+}
diff --git a/xenworker.go b/xenworker.go
index 31af35f..4077e77 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -232,16 +232,8 @@ func (w *XenWorker) Shutdown() {
 
 // FIXME: Return an error
 func (w *XenWorker) Process(report chan WorkerReport, done chan bool) {
-   mock := false
-   
-   // xl unpause [vmname]
-   args := []string{"xl", "unpause", w.vmname}
-   if mock {
-   args = append([]string{"echo"}, args...)
-   }
-   e := exec.Command(args[0], args[1:]...)
-
-   err := e.Run()
+   // // xl unpause [vmname]
+   err := xg.Ctx.DomainUnpause(Domid(w.domid))
if err != nil {
fmt.Printf("Error unpausing domain: %v\n", err)
return
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 15/59] controller: Move "running" code to a separate file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 Makefile |   2 +-
 benchmark.go | 153 --
 run.go   | 178 +++
 3 files changed, 179 insertions(+), 154 deletions(-)
 create mode 100644 run.go

diff --git a/Makefile b/Makefile
index 7a33cfb..2e06f87 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
index 4354a47..2e03fe5 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -21,8 +21,6 @@ package main
 import (
"fmt"
"os"
-   "os/signal"
-   "time"
"io/ioutil"
"encoding/json"
 )
@@ -71,11 +69,6 @@ const (
SEC = MSEC * 1000
 )
 
-type WorkerState struct {
-   w Worker
-   LastReport WorkerReport
-}
-
 func Throughput(lt int, lm int, t int, m int) (tput float64) {
time := float64(t - lt) / SEC
mops := m - lm
@@ -84,80 +77,6 @@ func Throughput(lt int, lm int, t int, m int) (tput float64) 
{
return
 }
 
-func Report(ws *WorkerState, r WorkerReport) {
-   //fmt.Println(r)
-
-   lr := ws.LastReport
-
-   if (lr.Now > 0) {
-   time := float64(r.Now - lr.Now) / SEC
-   mops := r.Mops - lr.Mops
-
-   tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)
-   
-   fmt.Printf("%v Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
-   }
-
-   ws.LastReport = r
-}
-
-type WorkerList map[WorkerId]*WorkerState
-
-func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
-   i = 0
-   for j := range *ws {
-   go (*ws)[j].w.Process(report, done)
-   i++
-   }
-   return
-}
-
-func (ws *WorkerList) Stop() {
-   for i := range *ws {
-   (*ws)[i].w.Shutdown()
-   }
-}
-
-const (
-   WorkerProcess = iota
-   WorkerXen = iota
-)
-
-func NewWorkerList(workers []WorkerSet, workerType int) (wl WorkerList, err 
error) {
-   wl = WorkerList(make(map[WorkerId]*WorkerState))
-
-   for wsi := range workers {
-   for i := 0; i < workers[wsi].Count; i = i+1 {
-   Id := WorkerId{Set:wsi,Id:i}
-
-   ws := wl[Id]
-
-   if ws != nil {
-   panic("Duplicate worker for id!")
-   }
-   
-   ws = &WorkerState{}
-   
-   switch workerType {
-   case WorkerProcess:
-   ws.w = &ProcessWorker{}
-   case WorkerXen:
-   ws.w = &XenWorker{}
-   default:
-   err = fmt.Errorf("Unknown type: %d", workerType)
-   return
-   }
-   
-   ws.w.SetId(Id)
-   
-   ws.w.Init(workers[wsi].Params)
-
-   wl[Id] = ws
-   }
-   }
-   return
-}
-
 type BenchmarkRunData struct {
Raw []WorkerReport   `json:",omitempty"`
Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
@@ -171,59 +90,6 @@ type BenchmarkRun struct {
Results BenchmarkRunData 
 }
 
-func (run *BenchmarkRun) Run() (err error) {
-   Workers, err := NewWorkerList(run.Workers, WorkerXen)
-   if err != nil {
-   fmt.Println("Error creating workers: %v", err)
-   return
-   }
-   
-   report := make(chan WorkerReport)
-   done := make(chan bool)
-   signals := make(chan os.Signal, 1)
-
-   signal.Notify(signals, os.Interrupt)
-   
-   i := Workers.Start(report, done)
-
-   // FIXME:
-   // 1. Make a zero timeout mean "never"
-   // 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
-   timeout := time.After(time.Duration(run.RuntimeSeconds) * time.Second);
-   stopped := false
-   for i > 0 {
-   select {
-   case r := <-report:
-   run.Results.Raw = append(run.Results.Raw, r)
-   Report(Workers[r.Id], r)
-   case <-done:
-   i--;
-   fmt.Println(i, "workers left");
-   case <-timeout:
-   if ! stopped {
-   Workers.Stop()
-   stopped = true
-   run.Completed = true
-   }
-   case <-signals:
-   if ! stopped {
-   f

[Xen-devel] [PATCH RFC 45/59] libxl: Implement Destroy, Add/Remove operations

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Also:

* Implement useful Bitmap operations: SetRange(), ClearRange(),
IsEmpty(), and And().

* Normalize CpupoolInfo element naming.

* Implement CpupoolMakeFree, which will scan through cpupools freeing
  the cpus in the map.

Signed-off-by: George Dunlap 
---
 libxl.go | 187 ++-
 1 file changed, 150 insertions(+), 37 deletions(-)

diff --git a/libxl.go b/libxl.go
index 6e17b53..92064ca 100644
--- a/libxl.go
+++ b/libxl.go
@@ -226,6 +226,12 @@ func (bm *Bitmap) Set(bit int) {
bm.bitmap[ibit] |= 1 << (uint(bit) & 7)
 }
 
+func (bm *Bitmap) SetRange(start int, end int) {
+   for i := start; i <= end; i++ {
+   bm.Set(i)
+   }
+}
+
 func (bm *Bitmap) Clear(bit int) {
ubit := uint(bit)
if (bit > bm.Max()) {
@@ -235,10 +241,42 @@ func (bm *Bitmap) Clear(bit int) {
bm.bitmap[bit / 8] &= ^(1 << (ubit & 7))
 }
 
+func (bm *Bitmap) ClearRange(start int, end int) {
+   for i := start; i <= end; i++ {
+   bm.Clear(i)
+   }
+}
+
 func (bm *Bitmap) Max() (int) {
return len(bm.bitmap) * 8
 }
 
+func (bm *Bitmap) IsEmpty() (bool) {
+   for i:=0; i len(b.bitmap) {
+   max = len(a.bitmap)
+   min = len(b.bitmap)
+   } else {
+   max = len(b.bitmap)
+   min = len(a.bitmap)
+   }
+   c.bitmap = make([]C.uint8_t, max)
+
+   for i := 0; i < min; i++ {
+   c.bitmap[i] = a.bitmap[i] & b.bitmap[i]
+   }
+   return
+}
+
 // # Consistent with values defined in domctl.h
 // # Except unknown which we have made up
 // libxl_scheduler = Enumeration("scheduler", [
@@ -294,11 +332,11 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
 // ], dir=DIR_OUT)
 
 type CpupoolInfo struct {
-   PoolId uint32
+   Poolid uint32
PoolName string
Scheduler Scheduler
DomainCount int
-   CpuMap Bitmap
+   Cpumap Bitmap
 }
 
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
@@ -320,11 +358,11 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
for i := range cpupoolListSlice {
var info CpupoolInfo

-   info.PoolId = uint32(cpupoolListSlice[i].poolid)
+   info.Poolid = uint32(cpupoolListSlice[i].poolid)
info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
info.DomainCount = int(cpupoolListSlice[i].n_dom)
-   info.CpuMap = bitmapCToGo(&cpupoolListSlice[i].cpumap)
+   info.Cpumap = bitmapCToGo(&cpupoolListSlice[i].cpumap)
 
list = append(list, info)
}
@@ -365,15 +403,78 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler 
Scheduler, Cpumap Bitma
 }
 
 // int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
-// int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid);
+func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
+   ret := C.libxl_cpupool_destroy(Ctx.ctx, C.uint32_t(Poolid))
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_destroy failed: %d", ret)
+   return
+   }
+
+   return
+}
+
 // int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
-// int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
+   ret := C.libxl_cpupool_cpuadd(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_cpuadd failed: %d", ret)
+   return
+   }
+
+   return
+}
+
 // int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
 // const libxl_bitmap *cpumap);
+func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
+   var cbm C.libxl_bitmap
+   bitmapGotoC(Cpumap, &cbm)
+   defer C.libxl_bitmap_dispose(&cbm)
+   
+   ret := C.libxl_cpupool_cpuadd_cpumap(Ctx.ctx, C.uint32_t(Poolid), &cbm)
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_cpuadd_cpumap failed: %d", ret)
+   return
+   }
+
+   return
+}
+
 // int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
-// int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
+   ret := C.libxl_cpupool_cpuremove(Ctx.ctx, C.uint32_t(Poolid), 
C.int(Cpu))
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_cpuremove failed: %d", ret)
+   return
+   }
+
+   return
+}
+
 // int libxl_

[Xen-devel] [PATCH RFC 17/59] controller: Collect and display statistics on WorkerSets

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Introduce WorkerSetSummary, to contain WorkerSummary's and collect
data for the set.

For now "if false"-out reporting of individual worker averages; we can
add this back in as an option later.

Signed-off-by: George Dunlap 
---
 benchmark.go | 156 +--
 1 file changed, 121 insertions(+), 35 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index aaa4c98..4cc9d61 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -23,14 +23,9 @@ import (
"os"
"io/ioutil"
"encoding/json"
+   "math"
 )
 
-type WorkerSummary struct {
-   MaxTput float64
-   AvgTput float64
-   MinTput float64
-}
-
 type WorkerId struct {
Set int
Id int
@@ -77,9 +72,26 @@ func Throughput(lt int, lm int, t int, m int) (tput float64) 
{
return
 }
 
+type WorkerSummary struct {
+   MaxTput float64
+   AvgTput float64
+   MinTput float64
+}
+
+type WorkerSetSummary struct {
+   Workers[]WorkerSummary
+   TotalTput float64
+   MaxTput   float64
+   AvgAvgTputfloat64
+   AvgStdDevTput float64
+   AvgMaxTputfloat64
+   AvgMinTputfloat64
+   MinTput   float64
+}
+
 type BenchmarkRunData struct {
Raw []WorkerReport   `json:",omitempty"`
-   Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
+   Summary []WorkerSetSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
@@ -90,6 +102,12 @@ type BenchmarkRun struct {
Results BenchmarkRunData 
 }
 
+type BenchmarkPlan struct {
+   filename string
+   WorkerType int
+   Runs []BenchmarkRun
+}
+
 func (run *BenchmarkRun) checkSummary() (done bool, err error) {
if run.Results.Summary != nil {
done = true
@@ -105,7 +123,7 @@ func (run *BenchmarkRun) Process() (err error) {
return
}
 
-   run.Results.Summary = make(map[WorkerId]*WorkerSummary)
+   run.Results.Summary = make([]WorkerSetSummary, len(run.WorkerSets))
 
type Data struct{
startTime int
@@ -118,18 +136,32 @@ func (run *BenchmarkRun) Process() (err error) {
// FIXME: Filter out results which started before all have started
for i := range run.Results.Raw {
e := run.Results.Raw[i]
+
+   if e.Id.Set > len(run.Results.Summary) {
+   return fmt.Errorf("Internal error: e.Id.Set %d > 
len(Results.Summary) %d\n",
+   e.Id.Set, len(run.Results.Summary))
+   }

+   if run.Results.Summary[e.Id.Set].Workers == nil {
+   run.Results.Summary[e.Id.Set].Workers = 
make([]WorkerSummary,
+   run.WorkerSets[e.Id.Set].Count)
+   }
+
+   ws := &run.Results.Summary[e.Id.Set]
+   
+   if e.Id.Id > len(ws.Workers) {
+   return fmt.Errorf("Internal error: e.Id.Id %d > 
len(Results.Summary[].Workers) %d\n",
+   e.Id.Id, len(ws.Workers))
+   }
+
+   s := &ws.Workers[e.Id.Id]
+
d := data[e.Id]
if d == nil {
d = &Data{}
data[e.Id] = d
}
-   s := run.Results.Summary[e.Id]
-   if s == nil {
-   s = &WorkerSummary{}
-   run.Results.Summary[e.Id] = s
-   }
-
+   
if d.startTime == 0 {
d.startTime = e.Now
} else {
@@ -141,16 +173,63 @@ func (run *BenchmarkRun) Process() (err error) {
if tput < s.MinTput || s.MinTput == 0 {
s.MinTput = tput
}
+   if tput > ws.MaxTput {
+   ws.MaxTput = tput
+   }
+   if tput < ws.MinTput || ws.MinTput == 0 {
+   ws.MinTput = tput
+   }
}
d.lastTime = e.Now
d.lastMops = e.Mops
}
 
-   for Id := range data {
-   run.Results.Summary[Id].AvgTput = Throughput(data[Id].startTime,
-   0, data[Id].lastTime, data[Id].lastMops)
+   for Id, d := range data {
+   ws := &run.Results.Summary[Id.Set]
+   s := &ws.Workers[Id.Id]
+
+   s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
+   if s.AvgTput > ws.AvgMaxTput {
+   ws.AvgMaxTput = s.AvgTput
+   }
+   if s.AvgTput < ws.AvgMinTput || ws.AvgMinTput == 0 {
+   ws.AvgMinTput = s.AvgTput
+   }
+   
}
-   
+
+   // Calculate the average-of-averages for each set
+   for

[Xen-devel] [PATCH RFC 03/59] controller: Initial attempt to generalize process / vm creation

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Create a "Worker" interface, and have ProcessWorker implement that
interface.

Rename "Worker" to "WorkerReport" to make room for the interface.

Signed-off-by: George Dunlap 
---
 main.go | 45 +++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/main.go b/main.go
index 0cb9f51..034e2f2 100644
--- a/main.go
+++ b/main.go
@@ -11,24 +11,32 @@ import (

 )
 
-type Worker struct {
+type WorkerReport struct {
Id int
-   
-   c *exec.Cmd
+   Now int
+   Mops int
+   MaxDelta int
+}
+
+type Worker interface {
+   SetId(int)
+   Init() error
+   Shutdown()
+   Process(chan WorkerReport, chan bool)
+}
 
+type ProcessWorker struct {
+   id int
+   c *exec.Cmd
stdout io.ReadCloser
-   
jsonStarted bool
 }
 
-type WorkerReport struct {
-   Id int
-   Now int
-   Mops int
-   MaxDelta int
+func (w *ProcessWorker) SetId(i int) {
+   w.id = i
 }
 
-func (w *Worker) Init() (err error) {
+func (w *ProcessWorker) Init() (err error) {
w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
 
w.stdout, err = w.c.StdoutPipe()
@@ -40,11 +48,11 @@ func (w *Worker) Init() (err error) {
return
 }
 
-func (w *Worker) Shutdown() {
+func (w *ProcessWorker) Shutdown() {
w.c.Process.Kill()
 }
 
-func (w *Worker) Process(report chan WorkerReport, done chan bool) {
+func (w *ProcessWorker) Process(report chan WorkerReport, done chan bool) {
w.c.Start()
 
scanner := bufio.NewScanner(w.stdout)
@@ -57,7 +65,7 @@ func (w *Worker) Process(report chan WorkerReport, done chan 
bool) {
if w.jsonStarted {
var r WorkerReport
json.Unmarshal([]byte(s), &r)
-   r.Id = w.Id
+   r.Id = w.id
report <- r
} else {
if s == "START JSON" {
@@ -79,7 +87,7 @@ const (
 )
 
 type WorkerState struct {
-   Worker
+   w Worker
LastReport WorkerReport
 }
 
@@ -114,11 +122,12 @@ func main() {
Workers := make([]WorkerState, count)

for i = 0; i< count; i++ {
-   Workers[i].Id = i
+   Workers[i].w = &ProcessWorker{}
+   Workers[i].w.SetId(i)

-   Workers[i].Init()
+   Workers[i].w.Init()

-   go Workers[i].Process(report, done)
+   go Workers[i].w.Process(report, done)
}
 
for i > 0 {
@@ -131,7 +140,7 @@ func main() {
case <-signals:
fmt.Println("SIGINT receieved, shutting down workers")
for j := range Workers {
-   Workers[j].Shutdown()
+   Workers[j].w.Shutdown()
}
}
}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 19/59] Add basic libxl framework, get domain cpu_time

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Introduce libxl "Context" class with open, close, and dominfo.

Create a global variable in xenworker.go to hold the context; open on
first worker creation, close on last worker destruction.

Add a new element to WorkerReport, Cputime, and print it out.

For now, include hard-coded link to local Xen libraries.  This should
be sorted out at some point.

Signed-off-by: George Dunlap 
---
 Makefile |  13 +--
 benchmark.go |   2 ++
 libxl.go | 116 +++
 run.go   |   2 +-
 xenworker.go |  26 ++
 5 files changed, 156 insertions(+), 3 deletions(-)
 create mode 100644 libxl.go

diff --git a/Makefile b/Makefile
index 2e06f87..54f2ce8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,17 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go
-   go build -o $@ $^
+
+
+CGO_CFLAGS = -I/build/hg/xen.git/dist/install/usr/local/include
+CGO_LIBS = -lyajl -lxenlight
+
+# FIXME
+XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
+CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
+
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go
+   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 .PHONY: clean
 clean:
diff --git a/benchmark.go b/benchmark.go
index 7fa83d2..4b2d805 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -24,6 +24,7 @@ import (
"io/ioutil"
"encoding/json"
"math"
+   "time"
 )
 
 type WorkerId struct {
@@ -40,6 +41,7 @@ type WorkerReport struct {
Now int
Mops int
MaxDelta int
+   Cputime time.Duration
 }
 
 type WorkerParams struct {
diff --git a/libxl.go b/libxl.go
new file mode 100644
index 000..39e47ab
--- /dev/null
+++ b/libxl.go
@@ -0,0 +1,116 @@
+package main
+
+/*
+#include 
+*/
+import "C"
+
+import (
+   "unsafe"
+   "fmt"
+   "time"
+)
+
+type Context struct {
+   ctx *C.libxl_ctx
+}
+
+func NewContext() (Ctx *Context, err error) {
+   Ctx = &Context{}
+   
+   err = Ctx.Open()
+
+   return
+}
+
+func (Ctx *Context) IsOpen() bool {
+   return Ctx.ctx != nil
+}
+
+func (Ctx *Context) Open() (err error) {
+   ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
+
+   if ret != 0 {
+   err = fmt.Errorf("Allocating libxl context: %d", ret)
+   }
+   return
+}
+
+func (Ctx *Context) Close() (err error) {
+   ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+   Ctx.ctx = nil
+
+   if ret != 0 {
+   err = fmt.Errorf("Freeing libxl context: %d", ret)
+   }
+   return
+}
+
+type Domid uint32
+
+type MemKB uint64
+
+// FIXME: Use the idl to generate types
+type Dominfo struct {
+   // FIXME: uuid
+   Domid Domid
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   Never_stopbool
+   
+   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
+   Outstanding_memkb MemKB
+   Current_memkb MemKB
+   Shared_memkb  MemKB
+   Paged_memkb   MemKB
+   Max_memkb MemKB
+   Cpu_time  time.Duration
+   Vcpu_max_id   uint32
+   Vcpu_online   uint32
+   Cpupool   uint32
+   Domain_type   int32 //FIXME libxl_domain_type enumeration
+
+}
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   return
+   }
+
+   
+   var cdi C.libxl_dominfo
+
+   ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(&cdi), 
C.uint32_t(Id))
+
+   // FIXME: IsDomainNotPresentError
+   if ret != 0 {
+   err = fmt.Errorf("libxl_domain_info failed: %d", ret)
+   return
+   }
+
+   // FIXME -- use introspection to make this more robust
+   di = &Dominfo{}
+   di.Domid = Domid(cdi.domid)
+   di.Running = bool(cdi.running)
+   di.Blocked = bool(cdi.blocked)
+   di.Paused = bool(cdi.paused)
+   di.Shutdown = bool(cdi.shutdown)
+   di.Dying = bool(cdi.dying)
+   di.Never_stop = bool(cdi.never_stop)
+   di.Shutdown_reason = int32(cdi.shutdown_reason)
+   di.Outstanding_memkb = MemKB(cdi.outstanding_memkb)
+   di.Current_memkb = MemKB(cdi.current_memkb)
+   di.Shared_memkb = MemKB(cdi.shared_memkb)
+   di.Paged_memkb = MemKB(cdi.paged_memkb)
+   di.Max_memkb = MemKB(cdi.max_memkb)
+   di.Cpu_time = time.Duration(cdi.cpu_time)
+   di.Vcpu_max_id = uint32(cdi.vcpu_max_id)
+   di.Vcpu_online = uint32(cdi.vcpu_online)
+   di.Cpupool = uint32(cdi.cpupool)
+   di.Domain_type = int32(cdi.domain_type)
+   return
+}
diff --git a/run.go b/run.go
i

[Xen-devel] [PATCH RFC 26/59] Use kops rather than mops

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

1 million operations on my test box takes about 3ms -- meaning the
minimum granularity for how long to burn cpu is far longer than
typical.  Make this kops instead, giving us a minimum granularity of 3us.

Update most of the default workers to have similar patterns but on a
1/100 (nb not 1/1000) scale; with the exception of worker A (1/1000
scale) and the first worker in worker B (1/10 scale).

Also, actually fix the name of the scheduler in the README.

Signed-off-by: George Dunlap 
---
 benchmark.go | 18 +-
 main.go  | 16 
 run.go   |  8 
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 73c5441..ffecb82 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -39,7 +39,7 @@ func (wid WorkerId) String() (string) {
 type WorkerReport struct {
Id WorkerId
Now int
-   Mops int
+   Kops int
MaxDelta int
Cputime time.Duration
 }
@@ -89,9 +89,9 @@ const (
 
 func Throughput(lt int, lm int, t int, m int) (tput float64) {
time := float64(t - lt) / SEC
-   mops := m - lm
+   kops := m - lm

-   tput = float64(mops) / time
+   tput = float64(kops) / time
return
 }
 
@@ -184,7 +184,7 @@ func (run *BenchmarkRun) Process() (err error) {
startTime int
startCputime time.Duration
lastTime int
-   lastMops int
+   lastKops int
lastCputime time.Duration
}

@@ -225,7 +225,7 @@ func (run *BenchmarkRun) Process() (err error) {
d.startTime = e.Now
d.startCputime = e.Cputime
} else {
-   tput := Throughput(d.lastTime, d.lastMops, e.Now, 
e.Mops)
+   tput := Throughput(d.lastTime, d.lastKops, e.Now, 
e.Kops)
util := Utilization(d.lastTime, d.lastCputime, e.Now, 
e.Cputime)
 
s.MinMaxTput.Update(tput)
@@ -234,7 +234,7 @@ func (run *BenchmarkRun) Process() (err error) {
ws.MinMaxUtil.Update(util)
}
d.lastTime = e.Now
-   d.lastMops = e.Mops
+   d.lastKops = e.Kops
d.lastCputime = e.Cputime
}
 
@@ -242,11 +242,11 @@ func (run *BenchmarkRun) Process() (err error) {
ws := &run.Results.Summary[Id.Set]
s := &ws.Workers[Id.Id]
 
-   s.TotalTput = d.lastMops
+   s.TotalTput = d.lastKops
s.TotalTime = time.Duration(d.lastTime - d.startTime)
s.TotalCputime = d.lastCputime - d.startCputime

-   s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
+   s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastKops)
s.AvgUtil = Utilization(d.startTime, d.startCputime, 
d.lastTime, d.lastCputime)
 
ws.MinMaxAvgTput.Update(s.AvgTput)
@@ -345,7 +345,7 @@ func (run *BenchmarkRun) TextReport(level int) (err error) {
for _, e := range s.Raw {
time := float64(e.Now) / SEC
fmt.Printf ("   [%8.3f] %8.3f 
%8d %12d\n", time,
-   e.Cputime.Seconds(), 
e.Mops, e.MaxDelta)
+   e.Cputime.Seconds(), 
e.Kops, e.MaxDelta)
}
}
 
diff --git a/main.go b/main.go
index 61d3949..6eaa39e 100644
--- a/main.go
+++ b/main.go
@@ -29,15 +29,15 @@ func main() {
 
switch(os.Args[1]) {
case "plan":
-   workerA := []string{"burnwait", "1", "2000"}
+   workerA := []string{"burnwait", "7", "2"}
//workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "1", "3000",
-   "burnwait", "2", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "3", "3000",
+   workerB := []string{"burnwait", "100", "300",
+   "burnwait", "20", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "30", "30",
}
 
 
diff --git a/run.go b/run.go
index 259f427..ed1957b 100644
--- a/run.go
+++ b/run.go
@@ -41,15 +41,15 @@ func Report(ws *WorkerState, r WorkerReport) {
if (lr.Now > 0) {
   

[Xen-devel] [PATCH RFC 24/59] report: Lots of changes

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Store raw worker reports in the worker summary for easy printing.

Add "level" argument to textreport to easly switch between different
levels of granularity.

Report total throughput, time, and cputime for workers.

When running, print plain time and aggregate cputime in addition to
deltas.

Signed-off-by: George Dunlap 
---
 benchmark.go | 34 +++---
 main.go  |  2 +-
 run.go   |  7 +--
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 7ea9aaa..73c5441 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -115,8 +115,12 @@ func (mm *MinMax) Update(x float64) {
 }
 
 type WorkerSummary struct {
+   Raw []WorkerReport
MinMaxTput MinMax
MinMaxUtil MinMax
+   TotalTput int
+   TotalTime time.Duration
+   TotalCputime time.Duration
AvgTput float64
AvgUtil float64
 }
@@ -201,7 +205,7 @@ func (run *BenchmarkRun) Process() (err error) {
}
 
ws := &run.Results.Summary[e.Id.Set]
-   
+
if e.Id.Id > len(ws.Workers) {
return fmt.Errorf("Internal error: e.Id.Id %d > 
len(Results.Summary[].Workers) %d\n",
e.Id.Id, len(ws.Workers))
@@ -209,6 +213,8 @@ func (run *BenchmarkRun) Process() (err error) {
 
s := &ws.Workers[e.Id.Id]
 
+   s.Raw = append(s.Raw, e)
+   
d := data[e.Id]
if d == nil {
d = &Data{}
@@ -236,6 +242,10 @@ func (run *BenchmarkRun) Process() (err error) {
ws := &run.Results.Summary[Id.Set]
s := &ws.Workers[Id.Id]
 
+   s.TotalTput = d.lastMops
+   s.TotalTime = time.Duration(d.lastTime - d.startTime)
+   s.TotalCputime = d.lastCputime - d.startCputime
+   
s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
s.AvgUtil = Utilization(d.startTime, d.startCputime, 
d.lastTime, d.lastCputime)
 
@@ -287,7 +297,7 @@ func (run *BenchmarkRun) Process() (err error) {
return
 }
 
-func (run *BenchmarkRun) TextReport() (err error) {
+func (run *BenchmarkRun) TextReport(level int) (err error) {
var done bool
done, err = run.checkSummary()
if err != nil {
@@ -320,15 +330,25 @@ func (run *BenchmarkRun) TextReport() (err error) {
ws.MinMaxAvgUtil.Min, ws.MinMaxUtil.Max, 
ws.MinMaxUtil.Min)
}
 
-   if true {
-   fmt.Printf("\n%8s %8s %8s %8s %8s %8s %8s\n", "workerid", 
"tavg", "tmin", "tmax", "uavg", "umin", "umax")
+   if level >= 1 {
+   fmt.Printf("\n%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", 
"workerid", "toput", "time", "cpu", "tavg", "tmin", "tmax", "uavg", "umin", 
"umax")
for set := range run.Results.Summary {
for id := range run.Results.Summary[set].Workers {
s := run.Results.Summary[set].Workers[id]
-   fmt.Printf("%2d:%2d%8.2f %8.2f %8.2f %8.2f 
%8.2f %8.2f\n",
+   fmt.Printf("%2d:%2d%10d %8.2f %8.2f %8.2f 
%8.2f %8.2f %8.2f %8.2f %8.2f\n",
set, id,
+   s.TotalTput, s.TotalTime.Seconds(), 
s.TotalCputime.Seconds(),
s.AvgTput, s.MinMaxTput.Min, 
s.MinMaxTput.Max,
s.AvgUtil, s.MinMaxUtil.Min, 
s.MinMaxUtil.Max)
+
+   if level >= 2 {
+   for _, e := range s.Raw {
+   time := float64(e.Now) / SEC
+   fmt.Printf ("   [%8.3f] %8.3f 
%8d %12d\n", time,
+   e.Cputime.Seconds(), 
e.Mops, e.MaxDelta)
+   }
+   }
+
}
}
}
@@ -391,7 +411,7 @@ func (plan *BenchmarkPlan) Save() (err error) {
return
 }
 
-func (plan *BenchmarkPlan) TextReport() (err error) {
+func (plan *BenchmarkPlan) TextReport(level int) (err error) {
for i := range plan.Runs {
r := &plan.Runs[i]
if ! r.Completed {
@@ -404,7 +424,7 @@ func (plan *BenchmarkPlan) TextReport() (err error) {
return
}
 
-   err = r.TextReport()
+   err = r.TextReport(level)
if err != nil {
return
}
diff --git a/main.go b/main.go
index a931567..bb46dbc 100644
--- a/main.go
+++ b/main.go
@@ -98,7 +98,7 @@ func main() {
os.Exit(1)
}

-   err = plan.TextReport()
+   err = pl

[Xen-devel] [PATCH RFC 23/59] run: Don't collect results reported after command to stop guests is issued

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Particularly on heavily-loaded systems, this can lead to skew as some
guests have already stopped processing.

Signed-off-by: George Dunlap 
---
 run.go | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/run.go b/run.go
index 4222001..41408dd 100644
--- a/run.go
+++ b/run.go
@@ -172,9 +172,14 @@ func (run *BenchmarkRun) Run() (err error) {
for i > 0 {
select {
case r := <-report:
-   run.Results.Raw = append(run.Results.Raw, r)
-   Report(Workers[r.Id], r)
+   if ! stopped {
+   run.Results.Raw = append(run.Results.Raw, r)
+   Report(Workers[r.Id], r)
+   }
case <-done:
+   if ! stopped {
+   fmt.Println("WARNING: Worker left early")
+   }
i--;
fmt.Println(i, "workers left");
case <-timeout:
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 18/59] controller: Add cpupool global config

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Define WorkerConfig for worker configuration, add "Pool" as a pool in
which to place the worker (currently implemented in Xen only).

Add WorkerConfig options at the WorkerSet, BenchmarkRun, and
BenchmarkPlan levels; allow local levels to "override" global config
options.

The cpupool must already be defined.

Signed-off-by: George Dunlap 
---
 benchmark.go | 19 ++-
 main.go  |  1 +
 processworker.go |  2 +-
 run.go   | 16 +++-
 xenworker.go |  6 +-
 5 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 4cc9d61..7fa83d2 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -46,14 +46,27 @@ type WorkerParams struct {
Args []string
 }
 
+type WorkerConfig struct {
+   Pool string
+}
+
+// Propagate unset values from a higher level
+func (l *WorkerConfig) PropagateFrom(g WorkerConfig) {
+   if l.Pool == "" {
+   l.Pool = g.Pool
+   }
+}
+
+
 type WorkerSet struct {
Params WorkerParams
+   Config WorkerConfig
Count int
 }
 
 type Worker interface {
SetId(WorkerId)
-   Init(WorkerParams) error
+   Init(WorkerParams, WorkerConfig) error
Shutdown()
Process(chan WorkerReport, chan bool)
 }
@@ -97,6 +110,7 @@ type BenchmarkRunData struct {
 type BenchmarkRun struct {
Label string
WorkerSets []WorkerSet
+   WorkerConfig
RuntimeSeconds int
Completed bool
Results BenchmarkRunData 
@@ -105,6 +119,9 @@ type BenchmarkRun struct {
 type BenchmarkPlan struct {
filename string
WorkerType int
+   // Global options for workers that will be over-ridden by Run
+   // and WorkerSet config options
+   WorkerConfig
Runs []BenchmarkRun
 }
 
diff --git a/main.go b/main.go
index f58068f..a931567 100644
--- a/main.go
+++ b/main.go
@@ -43,6 +43,7 @@ func main() {
 
plan :=  BenchmarkPlan{
WorkerType:WorkerXen,
+   WorkerConfig:WorkerConfig{Pool:"schedbench"},
filename:filename,
Runs:[]BenchmarkRun{
{Label:"baseline-a",
diff --git a/processworker.go b/processworker.go
index 5e26d81..f517321 100644
--- a/processworker.go
+++ b/processworker.go
@@ -38,7 +38,7 @@ func (w *ProcessWorker) SetId(i WorkerId) {
w.id = i
 }
 
-func (w *ProcessWorker) Init(p WorkerParams) (err error) {
+func (w *ProcessWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
w.c = exec.Command("./worker-proc", p.Args...)
 
w.stdout, err = w.c.StdoutPipe()
diff --git a/run.go b/run.go
index 762b408..9f1edcf 100644
--- a/run.go
+++ b/run.go
@@ -96,7 +96,7 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e

ws.w.SetId(Id)

-   ws.w.Init(WorkerSets[wsi].Params)
+   ws.w.Init(WorkerSets[wsi].Params, 
WorkerSets[wsi].Config)
 
wl[Id] = ws
}
@@ -105,6 +105,10 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e
 }
 
 func (run *BenchmarkRun) Run() (err error) {
+   for wsi := range run.WorkerSets {
+   run.WorkerSets[wsi].Config.PropagateFrom(run.WorkerConfig)
+   }
+   
Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
if err != nil {
fmt.Println("Error creating workers: %v", err)
@@ -159,14 +163,16 @@ func (run *BenchmarkRun) Run() (err error) {
 
 func (plan *BenchmarkPlan) Run() (err error) {
for i := range plan.Runs {
-   if ! plan.Runs[i].Completed {
-   fmt.Printf("Running test [%d] %s\n", i, 
plan.Runs[i].Label)
-   err = plan.Runs[i].Run()
+   r := &plan.Runs[i];
+   if ! r.Completed {
+   r.WorkerConfig.PropagateFrom(plan.WorkerConfig)
+   fmt.Printf("Running test [%d] %s\n", i, r.Label)
+   err = r.Run()
if err != nil {
return
}
}
-   fmt.Printf("Test [%d] %s completed\n", i, plan.Runs[i].Label)
+   fmt.Printf("Test [%d] %s completed\n", i, r.Label)
err = plan.Save()
if err != nil {
fmt.Println("Error saving: ", err)
diff --git a/xenworker.go b/xenworker.go
index e14676c..4d42e5e 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -58,7 +58,7 @@ func (w *XenWorker) SetId(i WorkerId) {
w.domid = -1 // INVALID DOMID
 }
 
-func (w *XenWorker) Init(p WorkerParams) (err error) {
+func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
mock := false

// Make xl config file
@@ -80,6 +80,10 @@ func (w *Xen

[Xen-devel] [PATCH RFC 44/59] libxl: Implement CpupoolCreate

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Implement CpupoolCreate.

For now, follow the lead of "xl cpupool-create", by automatically
generating a new uuid each time a new cpupool is created, and by not
allowing the user to attempt to set the poolid.

This requires us to implement bytmapGotoC, which C-allocates the
appropriate array and copies the Go byte map into it.  This must be
C-allocated because the runtime restricts how Go-allocated structures
can be passed into C function calls.

While we're here, reorganize functions slightly, and change the Bitmap
implementation to automatically extend the array if the size of the
byte array is too small.

Signed-off-by: George Dunlap 
---
 libxl.go | 119 +--
 1 file changed, 85 insertions(+), 34 deletions(-)

diff --git a/libxl.go b/libxl.go
index 3f6ba01..6e17b53 100644
--- a/libxl.go
+++ b/libxl.go
@@ -176,20 +176,38 @@ func (bm *Bitmap) Alloc(max int) {
 }
 
 // Return a Go bitmap which is a copy of the referred C bitmap.
-func bitmapCToGo(cbm *C.libxl_bitmap) (bm Bitmap) {
+func bitmapCToGo(cbm *C.libxl_bitmap) (gbm Bitmap) {
// Alloc a Go slice for the bytes
size := int(cbm.size)
-   bm.Alloc(size*8)
+   gbm.Alloc(size*8)
 
// Make a slice pointing to the C array
mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
 
// And copy the C array into the Go array
-   copy(bm.bitmap, mapslice)
+   copy(gbm.bitmap, mapslice)
 
return
 }
 
+// Must be C.libxl_bitmap_dispose'd of afterwards
+func bitmapGotoC(gbm Bitmap, cbm *C.libxl_bitmap) {
+   C.libxl_bitmap_init(cbm)
+
+   size := len(gbm.bitmap)
+   cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
+   cbm.size = C.uint32_t(size)
+   if cbm._map == nil {
+   panic("C.calloc failed!")
+   }
+
+   // Make a slice pointing to the C array
+   mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+   // And copy the Go array into the C array
+   copy(mapslice, gbm.bitmap)
+}
+
 func (bm *Bitmap) Test(bit int) (bool) {
ubit := uint(bit)
if (bit > bm.Max()) {
@@ -199,14 +217,13 @@ func (bm *Bitmap) Test(bit int) (bool) {
return (bm.bitmap[bit / 8] & (1 << (ubit & 7))) != 0
 }
 
-// FIXME: Do we really just want to silently fail here?
 func (bm *Bitmap) Set(bit int) {
-   ubit := uint(bit)
-   if (bit > bm.Max()) {
-   return
+   ibit := bit / 8;
+   if (ibit + 1 > len(bm.bitmap)) {
+   bm.bitmap = append(bm.bitmap, make([]C.uint8_t, 
ibit+1-len(bm.bitmap))...)
}

-   bm.bitmap[bit / 8] |= 1 << (ubit & 7)
+   bm.bitmap[ibit] |= 1 << (uint(bit) & 7)
 }
 
 func (bm *Bitmap) Clear(bit int) {
@@ -234,12 +251,12 @@ func (bm *Bitmap) Max() (int) {
 // ])
 type Scheduler int
 var (
-   SchedulerUnknown  Scheduler = 0
-   SchedulerSedf Scheduler = 4
-   SchedulerCredit   Scheduler = 5
-   SchedulerCredit2  Scheduler = 6
-   SchedulerArinc653 Scheduler = 7
-   SchedulerRTDS Scheduler = 8
+   SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
+   SchedulerSedf Scheduler = C.LIBXL_SCHEDULER_SEDF
+   SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
+   SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
+   SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
+   SchedulerRTDS Scheduler = C.LIBXL_SCHEDULER_RTDS
 )
 
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
@@ -315,23 +332,38 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
return
 }
 
-func (Ctx *Context) CpupoolFindByName(name string) (info CpupoolInfo, found 
bool) {
-   plist := Ctx.ListCpupool()
+// int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
+//  libxl_scheduler sched,
+//  libxl_bitmap cpumap, libxl_uuid *uuid,
+//  uint32_t *poolid);
+// FIXME: uuid
+// FIXME: Setting poolid
+func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap 
Bitmap) (err error, Poolid uint32) {
+   poolid := C.uint32_t(0)
+   name := C.CString(Name)
+   defer C.free(unsafe.Pointer(name))
+   
+   // For now, just do what xl does, and make a new uuid every time we 
create the pool
+   var uuid C.libxl_uuid
+   C.libxl_uuid_generate(&uuid)
 
-   for i := range plist {
-   if plist[i].PoolName == name {
-   found = true
-   info = plist[i]
-   return
-   }
+   var cbm C.libxl_bitmap
+   bitmapGotoC(Cpumap, &cbm)
+   defer C.libxl_bitmap_dispose(&cbm)
+   
+   ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+   cbm, &uuid, &poolid)
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libx

[Xen-devel] [PATCH RFC 57/59] tools/blktap2: remove unused inclusion of sys/sysctl.l

2016-12-28 Thread Ronald Rojas
From: Alistair Francis 

That header file is not used. Removing it would avoid build error with
musl libc, which doesn't have that header file.

Signed-off-by: Alistair Francis 
Reviewed-by: Doug Goldstein 
[ wei: rewrote commit message ]
Acked-by: Wei Liu 
---
 tools/blktap2/drivers/block-remus.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/blktap2/drivers/block-remus.c 
b/tools/blktap2/drivers/block-remus.c
index 079588d..7401800 100644
--- a/tools/blktap2/drivers/block-remus.c
+++ b/tools/blktap2/drivers/block-remus.c
@@ -54,7 +54,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 52/59] libxl: Implement Bitmap.String()

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Implement Bitmap.String, which will convert a bitmap into a string
parse-able by libxl.

Signed-off-by: George Dunlap 
---
 libxl.go | 59 ++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/libxl.go b/libxl.go
index bfcaf0d..aa5c01c 100644
--- a/libxl.go
+++ b/libxl.go
@@ -337,6 +337,51 @@ func (a Bitmap) And(b Bitmap) (c Bitmap) {
return
 }
 
+func (bm Bitmap) String() (s string) {
+   lastOnline := false
+   crange := false
+   printed := false
+   var i int
+   /// --x-x-x -> 2,4-8,10
+   /// --x-xxx -> 2,4-10
+   for i = 0; i <= bm.Max(); i++ {
+   if bm.Test(i) {
+   if !lastOnline {
+   // Switching offline -> online, print this cpu
+   if printed {
+   s += ","
+   }
+   s += fmt.Sprintf("%d", i)
+   printed = true
+   } else if !crange {
+   // last was online, but we're not in a range; 
print -
+   crange = true
+   s += "-"
+   } else {
+   // last was online, we're in a range,  nothing 
else to do
+   }
+   lastOnline = true
+   } else {
+   if lastOnline {
+   // Switching online->offline; do we need to end 
a range?
+   if crange {
+   s += fmt.Sprintf("%d", i-1)
+   }
+   }
+   lastOnline = false
+   crange = false
+   }
+   }
+   if lastOnline {
+   // Switching online->offline; do we need to end a range?
+   if crange {
+   s += fmt.Sprintf("%d", i-1)
+   }
+   }
+
+   return
+}
+
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
 func (s Scheduler) String() (string) {
cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
@@ -608,6 +653,18 @@ func (Ctx *Context) CpupoolMakeFree(Cpumap Bitmap) (err 
error) {
 }
 
 func XlTest(Args []string) {
+   var Cpumap Bitmap
+
+   Cpumap.Set(2)
+   Cpumap.SetRange(4, 8)
+   Cpumap.Set(10)
+
+   fmt.Printf("Cpumap: %v\n", Cpumap)
+
+   Cpumap.Set(9)
+
+   fmt.Printf("Cpumap: %v\n", Cpumap)
+
var Ctx Context
 
err := Ctx.Open()
@@ -635,7 +692,7 @@ func XlTest(Args []string) {
}
}
 
-   var Cpumap Bitmap
+   Cpumap = Bitmap{}
 
Cpumap.SetRange(12, 15)
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 11/59] Refactor to move towards benchmark "plans" and data analysis

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

A bit of a roll-up of lots of bits.

Signed-off-by: George Dunlap 
---
 Makefile |   4 +-
 benchmark.go | 256 +++
 main.go  | 197 ++---
 3 files changed, 302 insertions(+), 155 deletions(-)
 create mode 100644 benchmark.go

diff --git a/Makefile b/Makefile
index 16af528..7a33cfb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
-BIN = controller
+BIN = schedbench
 BINALL = $(BIN)
 
 .PHONY: all
 all: $(BIN)
 
-controller: main.go processworker.go xenworker.go
+schedbench: main.go processworker.go xenworker.go benchmark.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
new file mode 100644
index 000..b2b2399
--- /dev/null
+++ b/benchmark.go
@@ -0,0 +1,256 @@
+package main
+
+import (
+   "fmt"
+   "os"
+   "os/signal"
+   "time"
+   "io/ioutil"
+   "encoding/json"
+)
+
+type WorkerReport struct {
+   Id int
+   Now int
+   Mops int
+   MaxDelta int
+}
+
+type WorkerParams struct {
+   Args []string
+}
+
+type WorkerSet struct {
+   Params WorkerParams
+   Count int
+}
+
+type Worker interface {
+   SetId(int)
+   Init(WorkerParams) error
+   Shutdown()
+   Process(chan WorkerReport, chan bool)
+}
+
+const (
+   USEC = 1000
+   MSEC = USEC * 1000
+   SEC = MSEC * 1000
+)
+
+type WorkerState struct {
+   w Worker
+   LastReport WorkerReport
+}
+
+func Report(ws *WorkerState, r WorkerReport) {
+   //fmt.Println(r)
+
+   lr := ws.LastReport
+
+   if (lr.Now > 0) {
+   time := float64(r.Now - lr.Now) / SEC
+   mops := r.Mops - lr.Mops
+
+   tput := float64(mops) / time
+
+   fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
+   }
+
+   ws.LastReport = r
+}
+
+type WorkerList []WorkerState
+
+func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
+   i = 0
+   for j := range *ws {
+   go (*ws)[j].w.Process(report, done)
+   i++
+   }
+   return
+}
+
+func (ws *WorkerList) Stop() {
+   for i := range *ws {
+   (*ws)[i].w.Shutdown()
+   }
+}
+
+const (
+   WorkerProcess = iota
+   WorkerXen = iota
+)
+
+func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
+   count := 0
+
+   // wsi: WorkerSet index
+   for wsi := range workers {
+   count += workers[wsi].Count
+   }
+
+   fmt.Println("Making ", count, " total workers")
+   ws = WorkerList(make([]WorkerState, count))
+
+   // wli: WorkerList index
+   wli := 0
+   for wsi := range workers {
+   for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+   switch workerType {
+   case WorkerProcess:
+   ws[wli].w = &ProcessWorker{}
+   case WorkerXen:
+   ws[wli].w = &XenWorker{}
+   default:
+   err = fmt.Errorf("Unknown type: %d", workerType)
+   }
+   ws[wli].w.SetId(wli)
+   
+   ws[wli].w.Init(workers[wsi].Params)
+   }
+   }
+   return
+}
+
+type BenchmarkRunData struct {
+   Raw []WorkerReport
+}
+
+type BenchmarkRun struct {
+   Completed bool
+   Label string
+   Workers []WorkerSet
+   RuntimeSeconds int
+   Results BenchmarkRunData 
+}
+
+func (run *BenchmarkRun) Run() (err error) {
+   Workers, err := NewWorkerList(run.Workers, WorkerProcess)
+   if err != nil {
+   fmt.Println("Error creating workers: %v", err)
+   return
+   }
+   
+   report := make(chan WorkerReport)
+   done := make(chan bool)
+   signals := make(chan os.Signal, 1)
+
+   signal.Notify(signals, os.Interrupt)
+   
+   i := Workers.Start(report, done)
+
+   // FIXME:
+   // 1. Make a zero timeout mean "never"
+   // 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
+   timeout := time.After(time.Duration(run.RuntimeSeconds) * time.Second);
+   stopped := false
+   for i > 0 {
+   select {
+   case r := <-report:
+   run.Results.Raw = append(run.Results.Raw, r)
+   Report(&Workers[r.Id], r)
+   case <-done:
+   i--;
+   fmt.Println(i, "workers left");
+   case <-timeout:
+   if ! stopped {
+   Workers.Stop()
+   stopped = true
+   run.Completed = true
+   }
+   case <-signals:
+  

[Xen-devel] [PATCH RFC 12/59] Basic 'report' functionality

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Go through the raw data and re-calculate throughput for each
timeframe.  Record for each worker the min and max of these; then take
an average over the whole run.

Have the report go through each and show the worker setup, as well as
the avg, min, and max for each worker.

Also default to running Xen again (rather than processes), and clean
up some chattiness wrt starting Xen processes.

Finally, make the "plan" slightly more programmatic, and test a more
"pipelined" testcase.

Signed-off-by: George Dunlap 
---
 benchmark.go | 163 +--
 main.go  |  56 
 xenworker.go |   4 +-
 3 files changed, 205 insertions(+), 18 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index b2b2399..ec62c3d 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -9,6 +9,12 @@ import (
"encoding/json"
 )
 
+type WorkerSummary struct {
+   MaxTput float64
+   AvgTput float64
+   MinTput float64
+}
+
 type WorkerReport struct {
Id int
Now int
@@ -43,6 +49,14 @@ type WorkerState struct {
LastReport WorkerReport
 }
 
+func Throughput(lt int, lm int, t int, m int) (tput float64) {
+   time := float64(t - lt) / SEC
+   mops := m - lm
+   
+   tput = float64(mops) / time
+   return
+}
+
 func Report(ws *WorkerState, r WorkerReport) {
//fmt.Println(r)
 
@@ -52,8 +66,8 @@ func Report(ws *WorkerState, r WorkerReport) {
time := float64(r.Now - lr.Now) / SEC
mops := r.Mops - lr.Mops
 
-   tput := float64(mops) / time
-
+   tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)
+   
fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
}
 
@@ -114,19 +128,21 @@ func NewWorkerList(workers []WorkerSet, workerType int) 
(ws WorkerList, err erro
 }
 
 type BenchmarkRunData struct {
-   Raw []WorkerReport
+   WorkerCount int
+   Raw []WorkerReport   `json:",omitempty"`
+   Summary []WorkerSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
-   Completed bool
Label string
Workers []WorkerSet
RuntimeSeconds int
+   Completed bool
Results BenchmarkRunData 
 }
 
 func (run *BenchmarkRun) Run() (err error) {
-   Workers, err := NewWorkerList(run.Workers, WorkerProcess)
+   Workers, err := NewWorkerList(run.Workers, WorkerXen)
if err != nil {
fmt.Println("Error creating workers: %v", err)
return
@@ -140,6 +156,8 @@ func (run *BenchmarkRun) Run() (err error) {

i := Workers.Start(report, done)
 
+   run.Results.WorkerCount = i
+
// FIXME:
// 1. Make a zero timeout mean "never"
// 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
@@ -178,8 +196,121 @@ func (run *BenchmarkRun) Run() (err error) {
return
 }
 
+func (run *BenchmarkRun) checkSummary() (done bool, err error) {
+   if run.Results.WorkerCount == 0 {
+   err = fmt.Errorf("Internal error: WorkerCount 0!")
+   return
+   }
+   
+   if len(run.Results.Summary) == run.Results.WorkerCount {
+   done = true
+   return 
+   }
+   
+   if len(run.Results.Summary) != 0 {
+   err = fmt.Errorf("Internal error: len(Summary) %d, len(Workers) 
%d!\n",
+   len(run.Results.Summary), run.Results.WorkerCount)
+   return
+   }
+
+   return
+}
+
+func (run *BenchmarkRun) Process() (err error) {
+   done, err := run.checkSummary()
+   if done || err != nil {
+   return
+   }
+   
+   wcount := run.Results.WorkerCount
+
+   if len(run.Results.Summary) != 0 {
+   err = fmt.Errorf("Internal error: len(Summary) %d, len(Workers) 
%d!\n",
+   len(run.Results.Summary), wcount)
+   return
+   }
+
+   run.Results.Summary = make([]WorkerSummary, wcount)
+
+   // FIXME: Filter out results which started before all have started
+   
+   data := make([]struct{
+   startTime int
+   lastTime int
+   lastMops int}, wcount)
+
+   for i := range run.Results.Raw {
+   e := run.Results.Raw[i]
+   if e.Id > wcount {
+   err = fmt.Errorf("Internal error: id %d > wcount %d", 
e.Id, wcount)
+   return
+   }
+   
+   d := &data[e.Id]
+   s := &run.Results.Summary[e.Id]
+
+   if d.startTime == 0 {
+   d.startTime = e.Now
+   } else {
+   tput := Throughput(d.lastTime, d.lastMops, e.Now, 
e.Mops)
+   
+   if tput > s.MaxTput {
+   s.MaxTput = tput
+ 

[Xen-devel] [PATCH RFC 21/59] Report utilization statistics

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Refactor the min/max into a separate type.

Signed-off-by: George Dunlap 
---
 benchmark.go | 119 +--
 run.go   |   4 +-
 2 files changed, 78 insertions(+), 45 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 4b2d805..b0b55c7 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -87,21 +87,45 @@ func Throughput(lt int, lm int, t int, m int) (tput 
float64) {
return
 }
 
+func Utilization(lt int, lct time.Duration, t int, ct time.Duration) (util 
float64) {
+   util = float64(ct - lct) / float64(t - lt)
+   return
+}
+
+type MinMax struct {
+   Min float64
+   Max float64
+}
+
+func (mm *MinMax) Update(x float64) {
+   if x > mm.Max {
+   mm.Max = x
+   }
+   if x < mm.Min || mm.Min == 0 {
+   mm.Min = x
+   }
+}
+
 type WorkerSummary struct {
-   MaxTput float64
+   MinMaxTput MinMax
+   MinMaxUtil MinMax
AvgTput float64
-   MinTput float64
+   AvgUtil float64
 }
 
 type WorkerSetSummary struct {
Workers[]WorkerSummary
TotalTput float64
-   MaxTput   float64
AvgAvgTputfloat64
+   MinMaxTputMinMax
+   MinMaxAvgTput MinMax
AvgStdDevTput float64
-   AvgMaxTputfloat64
-   AvgMinTputfloat64
-   MinTput   float64
+
+   TotalUtil float64
+   MinMaxUtilMinMax
+   MinMaxAvgUtil MinMax
+   AvgAvgUtilfloat64
+   AvgStdDevUtil float64
 }
 
 type BenchmarkRunData struct {
@@ -146,8 +170,10 @@ func (run *BenchmarkRun) Process() (err error) {
 
type Data struct{
startTime int
+   startCputime time.Duration
lastTime int
lastMops int
+   lastCputime time.Duration
}

data := make(map[WorkerId]*Data)
@@ -183,24 +209,19 @@ func (run *BenchmarkRun) Process() (err error) {

if d.startTime == 0 {
d.startTime = e.Now
+   d.startCputime = e.Cputime
} else {
tput := Throughput(d.lastTime, d.lastMops, e.Now, 
e.Mops)
-   
-   if tput > s.MaxTput {
-   s.MaxTput = tput
-   }
-   if tput < s.MinTput || s.MinTput == 0 {
-   s.MinTput = tput
-   }
-   if tput > ws.MaxTput {
-   ws.MaxTput = tput
-   }
-   if tput < ws.MinTput || ws.MinTput == 0 {
-   ws.MinTput = tput
-   }
+   util := Utilization(d.lastTime, d.lastCputime, e.Now, 
e.Cputime)
+
+   s.MinMaxTput.Update(tput)
+   s.MinMaxUtil.Update(util)
+   ws.MinMaxTput.Update(tput)
+   ws.MinMaxUtil.Update(util)
}
d.lastTime = e.Now
d.lastMops = e.Mops
+   d.lastCputime = e.Cputime
}
 
for Id, d := range data {
@@ -208,45 +229,51 @@ func (run *BenchmarkRun) Process() (err error) {
s := &ws.Workers[Id.Id]
 
s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
-   if s.AvgTput > ws.AvgMaxTput {
-   ws.AvgMaxTput = s.AvgTput
-   }
-   if s.AvgTput < ws.AvgMinTput || ws.AvgMinTput == 0 {
-   ws.AvgMinTput = s.AvgTput
-   }
-   
+   s.AvgUtil = Utilization(d.startTime, d.startCputime, 
d.lastTime, d.lastCputime)
+
+   ws.MinMaxAvgTput.Update(s.AvgTput)
+   ws.MinMaxAvgUtil.Update(s.AvgUtil)
}
 
// Calculate the average-of-averages for each set
for set := range run.Results.Summary {
ws := &run.Results.Summary[set]

-   var total float64
+   var totalTput float64
+   var totalUtil float64
var count int
for id := range ws.Workers {
-   total += ws.Workers[id].AvgTput
+   totalTput += ws.Workers[id].AvgTput
+   totalUtil += ws.Workers[id].AvgUtil
count++
}
 
// FIXME -- Is this legit?
-   ws.TotalTput = total
-   ws.AvgAvgTput = total / float64(count)
+   ws.TotalTput = totalTput
+   ws.TotalUtil = totalUtil
+   ws.AvgAvgTput = totalTput / float64(count)
+   ws.AvgAvgUtil = totalUtil / float64(count)
}
 
// Then calculate the standard deviation
for set := range run.Results.Summary {
ws := &run.Results.Sum

[Xen-devel] [PATCH RFC 22/59] Use tsc for time rather than rumpkernel clock_gettime()

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

The rumpkernel clock_gettime() drifts drastically when the system is
overloaded.  Switch to using a TSC timesource instead:

* Use tsc_mode='native' in guest config
* Read the host tsc from /proc/cpuinfo when starting a run
* Pass it as an argument to the worker
* Implement now() with rdtsc

The results appear to continue to be accurate even with heavy
overcommitment.

Signed-off-by: George Dunlap 
---
 benchmark.go |  8 
 run.go   | 45 +
 xenworker.go |  1 +
 3 files changed, 54 insertions(+)

diff --git a/benchmark.go b/benchmark.go
index b0b55c7..7ea9aaa 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -48,6 +48,14 @@ type WorkerParams struct {
Args []string
 }
 
+func (l *WorkerParams) SetkHZ(kHZ uint64) {
+   if l.Args[0] == "kHZ" {
+   l.Args[1] = fmt.Sprintf("%d", kHZ)
+   } else {
+   l.Args = append([]string{"kHZ", fmt.Sprintf("%d", kHZ)}, 
l.Args...)
+   }
+}
+
 type WorkerConfig struct {
Pool string
 }
diff --git a/run.go b/run.go
index 2a93405..4222001 100644
--- a/run.go
+++ b/run.go
@@ -23,6 +23,9 @@ import (
"os"
"os/signal"
"time"
+   "regexp"
+   "strconv"
+   "bufio"
 )
 
 type WorkerState struct {
@@ -106,9 +109,45 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e
return
 }
 
+var CpukHZ uint64
+
+func getCpuHz() (err error) {
+   if CpukHZ == 0 {
+   var cpuinfo *os.File
+   cpuinfo, err = os.Open("/proc/cpuinfo")
+   if err != nil {
+   return
+   }
+   re := regexp.MustCompile("^cpu MHz\\s*: ([0-9.]+)$")
+   scanner := bufio.NewScanner(cpuinfo)
+   for scanner.Scan() {
+   s := scanner.Text()
+   m := re.FindStringSubmatch(s)
+   if m != nil {
+   var MHZ float64
+   MHZ, err = strconv.ParseFloat(m[1], 64)
+   if err != nil {
+   return
+   }
+   CpukHZ = uint64(MHZ*1000)
+   break
+   }
+   }
+   if CpukHZ == 0 {
+   err = fmt.Errorf("Couldn't find cpu MHz")
+   return
+   } else {
+   fmt.Println("CpukHZ: ", CpukHZ)
+   
+   }
+   }
+   return
+}
+
 func (run *BenchmarkRun) Run() (err error) {
for wsi := range run.WorkerSets {
run.WorkerSets[wsi].Config.PropagateFrom(run.WorkerConfig)
+   run.WorkerSets[wsi].Params.SetkHZ(CpukHZ)
}

Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
@@ -164,6 +203,12 @@ func (run *BenchmarkRun) Run() (err error) {
 }
 
 func (plan *BenchmarkPlan) Run() (err error) {
+
+   err = getCpuHz()
+   if err != nil {
+   return
+   }
+   
for i := range plan.Runs {
r := &plan.Runs[i];
if ! r.Completed {
diff --git a/xenworker.go b/xenworker.go
index 4077e77..e98c970 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -95,6 +95,7 @@ func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err 
error) {
fmt.Fprintf(cfg, "memory = 32\n")
fmt.Fprintf(cfg, "vcpus = 1\n")
fmt.Fprintf(cfg, "on_crash = 'destroy'\n")
+   fmt.Fprintf(cfg, "tsc_mode = 'native'\n")
 
if g.Pool != "" {
fmt.Fprintf(cfg, "pool = '%s'\n", g.Pool)
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 13/59] Add GPL headers / COPYING file (v2 only)

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 benchmark.go | 18 ++
 main.go  | 19 +++
 processworker.go | 18 ++
 xenworker.go | 18 ++
 4 files changed, 73 insertions(+)

diff --git a/benchmark.go b/benchmark.go
index ec62c3d..2a78d26 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
diff --git a/main.go b/main.go
index 2696810..ebf990f 100644
--- a/main.go
+++ b/main.go
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
 package main
 
 import (
diff --git a/processworker.go b/processworker.go
index cca6c3b..6f70ce1 100644
--- a/processworker.go
+++ b/processworker.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
diff --git a/xenworker.go b/xenworker.go
index 1ed5cf0..7e85032 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 40/59] controller: Add / update GPL text

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Add it to files which are missing it; clarify the wording regarding
version 2 only in others.

Signed-off-by: George Dunlap 
---
 benchmark.go | 2 +-
 main.go  | 2 +-
 processworker.go | 2 +-
 xenworker.go | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index b77b66b..aecb574 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
diff --git a/main.go b/main.go
index 2f68969..8cbd708 100644
--- a/main.go
+++ b/main.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
diff --git a/processworker.go b/processworker.go
index 999e76a..8c27f15 100644
--- a/processworker.go
+++ b/processworker.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
diff --git a/xenworker.go b/xenworker.go
index 2649392..10817b5 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 38/59] controller: Allow multiple schedulers in the same benchmark file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

First, add a RunConfig element to BenchmarkRun, which contains a
(string) name of the scheduler for this run.

Add run.Ready(), which if RunConfig.Scheduler is non-null, will check
to see if the cpupool in which the VMs will run (either
WorkerConfig.Pool or PoolID 0) has the specified scheduler.

Finally, when expanding the SimpleMatrix plan, if
SimpleMatrix.Schedulers is non-emply, add it to the matrix of runs.
Put them next to each other so that it's easy to compare similar runs
on different schedulers.

Refactor schedbench.sh to account for this, and also update the
README.md.

Signed-off-by: George Dunlap 
---
 benchmark.go |  5 +
 plan.go  | 38 +++---
 run.go   | 59 +--
 3 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 31b3711..b77b66b 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -138,10 +138,15 @@ type BenchmarkRunData struct {
Summary []WorkerSetSummary  `json:",omitempty"`
 }
 
+type RunConfig struct {
+   Scheduler string
+}
+
 type BenchmarkRun struct {
Label string
WorkerSets []WorkerSet
WorkerConfig
+   RunConfig
RuntimeSeconds int
Completed bool
Results BenchmarkRunData 
diff --git a/plan.go b/plan.go
index 2983e78..24c6bd4 100644
--- a/plan.go
+++ b/plan.go
@@ -35,29 +35,42 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
WorkerPresets[k] = plan.Input.WorkerPresets[k];
}
 
+   // Use named schedulers, or default to "" (which will use the
+   // current one)
+   var schedulers []string
+   if plan.Input.SimpleMatrix.Schedulers != nil {
+   schedulers = plan.Input.SimpleMatrix.Schedulers
+   } else {
+   schedulers = append(schedulers, "")
+   }
+
// Always do the baselines
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]
-
+   
if wp.Args == nil {
err = fmt.Errorf("Invalid worker preset: %s", wn)
return
}
-
+   
run := BenchmarkRun{
-   Label:wn+" baseline",
WorkerSets:[]WorkerSet{{Params:wp, Count:1}},
RuntimeSeconds:10,
}
-
-   plan.Runs = append(plan.Runs, run)
+   
+   for _, s := range schedulers {
+   fmt.Printf("Making baseline %s run, sched %s\n", wn, s)
+   run.RunConfig.Scheduler = s
+   run.Label = wn+" baseline "+s
+   plan.Runs = append(plan.Runs, run)
+   }
}
-
+   
for _, c := range plan.Input.SimpleMatrix.Count {
run := BenchmarkRun{
RuntimeSeconds:10,
}
-
+   
var label string
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]
@@ -65,14 +78,17 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
if label != "" {
label = label+" + "
}
-   label = fmt.Sprintf("%s%s %d", label, wn, c)
+   label = fmt.Sprintf("%s%s %d ", label, wn, c)

ws := WorkerSet{Params:wp, Count:c}
run.WorkerSets = append(run.WorkerSets, ws)
}
-   run.Label = label
-
-   plan.Runs = append(plan.Runs, run)
+   for _, s := range schedulers {
+   fmt.Printf("Making count %d run, sched %s\n", c, s)
+   run.RunConfig.Scheduler = s
+   run.Label = label+s
+   plan.Runs = append(plan.Runs, run)
+   }
}
 
return
diff --git a/run.go b/run.go
index 08a43ff..1a753bc 100644
--- a/run.go
+++ b/run.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
@@ -156,6 +156,38 @@ func getCpuHz() (err error) {
return
 }
 
+func (run *BenchmarkRun) Ready() (ready bool, why string) {
+   // FIXME: Check WorkerType
+   // Skip this run if it's not the scheduler we want
+   if run.RunConfig.Scheduler != "" {
+   var pool CpupoolInfo
+   if run.WorkerConfig.Pool != "" {
+   var found bool
+   pool, found =

[Xen-devel] [PATCH RFC 09/59] controller: Refactor creation and stopping of workers into WorkerList methods

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 main.go | 59 ++-
 1 file changed, 42 insertions(+), 17 deletions(-)

diff --git a/main.go b/main.go
index dbd6276..89e9cf3 100644
--- a/main.go
+++ b/main.go
@@ -55,10 +55,43 @@ func Report(ws *WorkerState, r WorkerReport) {
 
 type WorkerList []WorkerState
 
-func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) {
+func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
+   i = 0
+   for j := range *ws {
+   go (*ws)[j].w.Process(report, done)
+   i++
+   }
+   return
+}
+
+func (ws *WorkerList) Stop() {
for i := range *ws {
-   go (*ws)[i].w.Process(report, done)
+   (*ws)[i].w.Shutdown()
+   }
+}
+
+const (
+   WorkerProcess = iota
+   WorkerXen = iota
+)
+
+func NewWorkerList(count int, workerType int) (ws WorkerList, err error) {
+   ws = WorkerList(make([]WorkerState, count))
+
+   for i := 0; i< count; i++ {
+   switch workerType {
+   case WorkerProcess:
+   ws[i].w = &ProcessWorker{}
+   case WorkerXen:
+   ws[i].w = &XenWorker{}
+   default:
+   err = fmt.Errorf("Unknown type: %d", workerType)
+   }
+   ws[i].w.SetId(i)
+   
+   ws[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
}
+   return
 }
 
 func main() {
@@ -72,19 +105,13 @@ func main() {
 
signal.Notify(signals, os.Interrupt)

-   i := 0
-
-   Workers := WorkerList(make([]WorkerState, count))
-   
-   for i = 0; i< count; i++ {
-   //Workers[i].w = &ProcessWorker{}
-   Workers[i].w = &XenWorker{}
-   Workers[i].w.SetId(i)
-   
-   Workers[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
+   Workers, err := NewWorkerList(count, WorkerProcess)
+   if err != nil {
+   fmt.Println("Error creating workers: %v", err)
+   return
}
-
-   Workers.Start(report, done)
+   
+   i := Workers.Start(report, done)
 
for i > 0 {
select {
@@ -96,9 +123,7 @@ func main() {
case <-signals:
if ! killed {
fmt.Println("SIGINT receieved, shutting down 
workers")
-   for j := range Workers {
-   Workers[j].w.Shutdown()
-   }
+   Workers.Stop()
killed = true
} else {
fmt.Println("Second SIGINT received, exiting 
without cleaning up")
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 53/59] controller: Add WorkerConfig.SoftAffinity

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

If the SoftAffinity is present, pass it as "cpus_soft = ..." in the
config file.

Signed-off-by: George Dunlap 
---
 benchmark.go | 1 +
 xenworker.go | 4 
 2 files changed, 5 insertions(+)

diff --git a/benchmark.go b/benchmark.go
index bd513fd..d5a0ac8 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -58,6 +58,7 @@ func (l *WorkerParams) SetkHZ(kHZ uint64) {
 
 type WorkerConfig struct {
Pool string
+   SoftAffinity string
 }
 
 // Propagate unset values from a higher level
diff --git a/xenworker.go b/xenworker.go
index 10817b5..f2f316f 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -91,6 +91,10 @@ func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) 
(err error) {
fmt.Fprintf(cfg, "pool = '%s'\n", g.Pool)
}
 
+   if g.SoftAffinity != "" {
+   fmt.Fprintf(cfg, "cpus_soft = '%s'\n", g.SoftAffinity)
+   }
+

// xl create -p [filename]
{
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 36/59] controller: Make 'dummy' at the level of 'run' rather than xenworker

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Get rid of xenworker_dummy.go and use stubs.go instead.  This is much
cleaner (as evidenced by the size of the file), and allows us to use
libxl-based things in run.go without having to make a load of dummy
libxl stub functions.

Signed-off-by: George Dunlap 
---
 Makefile   |  2 +-
 stubs.go   | 34 
 xenworker_dummy.go | 58 --
 3 files changed, 35 insertions(+), 59 deletions(-)
 create mode 100644 stubs.go
 delete mode 100644 xenworker_dummy.go

diff --git a/Makefile b/Makefile
index af55e0a..0e0b231 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ schedbench: main.go processworker.go xenworker.go 
benchmark.go run.go libxl.go h
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 # FIXME: Do with dlopen instead
-schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go plan.go
+schedbench-report: main.go benchmark.go stubs.go htmlreport.go plan.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/stubs.go b/stubs.go
new file mode 100644
index 000..78987ad
--- /dev/null
+++ b/stubs.go
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package main
+
+import (
+   "fmt"
+)
+
+func (plan *BenchmarkPlan) Run() (err error) {
+   err = fmt.Errorf("Not implemented")
+
+   return
+}
+
+func XlTest(Args []string) {
+   return
+}
+
diff --git a/xenworker_dummy.go b/xenworker_dummy.go
deleted file mode 100644
index e2dbdae..000
--- a/xenworker_dummy.go
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License only.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-package main
-
-import (
-   "fmt"
-   "io"
-)
-
-type XenWorker struct {
-}
-
-func XlTest(Args []string) {
-   return
-}
-
-func (w *XenWorker) SetId(i WorkerId) {
-}
-
-func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
-   err = fmt.Errorf("Xen functionality not implemented");
-   return
-}
-
-// FIXME: Return an error
-func (w *XenWorker) Shutdown() {
-   
-   return
-}
-
-func (w *XenWorker) DumpLog(f io.Writer) (err error) {
-   err = fmt.Errorf("Xen functionality not implemented");
-   return
-}
-
-
-
-// FIXME: Return an error
-func (w *XenWorker) Process(report chan WorkerReport, done chan WorkerId) {
-   return;
-}
-
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 33/59] controller: Add verbosity argument and update README with new instructions

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 main.go | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/main.go b/main.go
index ddb768c..2aa8bae 100644
--- a/main.go
+++ b/main.go
@@ -30,6 +30,7 @@ func main() {
 
Args = Args[1:]
filename := "test.bench"
+   verbosity := 0
 
for len(Args) > 0 {
switch(Args[0]) {
@@ -40,6 +41,13 @@ func main() {
}
filename = Args[1]
Args = Args[2:]
+   case "-v":
+   if len(Args) < 2 {
+   fmt.Println("Need arg for -v")
+   os.Exit(1)
+   }
+   verbosity, _ = strconv.Atoi(Args[1])
+   Args = Args[2:]
case "plan":
workerA := []string{"burnwait", "70", "20"}
//workerB := []string{"burnwait", "10", "2000"}
@@ -105,12 +113,7 @@ func main() {
Args = Args[1:]

case "report":
-   verbosity := 0
Args = Args[1:]
-   if len(Args) > 0 {
-   verbosity, _ = strconv.Atoi(os.Args[0])
-   Args = Args[1:]
-   }
plan, err := LoadBenchmark(filename)
if err != nil {
fmt.Println("Loading benchmark ", filename, " 
", err)
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 27/59] report: Allow report verbosity to be specified

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Take a third argument to control the level of verbosity.

Also add helpful deltas when reporting the raw results.

Signed-off-by: George Dunlap 
---
 benchmark.go | 17 +++--
 main.go  | 11 ---
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index ffecb82..5e35997 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -342,10 +342,23 @@ func (run *BenchmarkRun) TextReport(level int) (err 
error) {
s.AvgUtil, s.MinMaxUtil.Min, 
s.MinMaxUtil.Max)
 
if level >= 2 {
+   var le WorkerReport
for _, e := range s.Raw {
+   var dtime float64
+   var dCputime time.Duration
+   var dKops int
time := float64(e.Now) / SEC
-   fmt.Printf ("   [%8.3f] %8.3f 
%8d %12d\n", time,
-   e.Cputime.Seconds(), 
e.Kops, e.MaxDelta)
+   if e.Now > le.Now {
+   dtime = float64(e.Now - 
le.Now) / SEC
+   dCputime = e.Cputime - 
le.Cputime
+   dKops = e.Kops - le.Kops
+
+   }
+   fmt.Printf ("   [%8.3f] (%8.3f) 
%8.3f (%8.3f) %8d (%8d) %12d\n",
+   time, dtime,
+   e.Cputime.Seconds(), 
dCputime.Seconds(),
+   e.Kops, dKops, 
e.MaxDelta)
+   le = e
}
}
 
diff --git a/main.go b/main.go
index 6eaa39e..13230a7 100644
--- a/main.go
+++ b/main.go
@@ -22,6 +22,7 @@ package main
 import (
"fmt"
"os"
+   "strconv"
 )
 
 func main() {
@@ -29,9 +30,9 @@ func main() {
 
switch(os.Args[1]) {
case "plan":
-   workerA := []string{"burnwait", "7", "2"}
+   workerA := []string{"burnwait", "70", "20"}
//workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "100", "300",
+   workerB := []string{"burnwait", "10", "30",
"burnwait", "20", "30",
"burnwait", "10", "30",
"burnwait", "10", "30",
@@ -91,13 +92,17 @@ func main() {
}

case "report":
+   verbosity := 0
+   if len(os.Args) > 2 {
+   verbosity, _ = strconv.Atoi(os.Args[2])
+   }
plan, err := LoadBenchmark(filename)
if err != nil {
fmt.Println("Loading benchmark ", filename, " ", err)
os.Exit(1)
}

-   err = plan.TextReport(0)
+   err = plan.TextReport(verbosity)
if err != nil {
fmt.Println("Running benchmark run:", err)
os.Exit(1)
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 35/59] libxl: Add ListCpupool

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Add libxl bindings for libxl_list_cpupool().

Define the Scheduler type (based on libxl_schedler) with appropriate
constants and string functions.

Punt on the cpumap part of CpupoolInfo for now.

Also create "xltest" command for testing libxl bindings

Signed-off-by: George Dunlap 
---
 libxl.go   | 152 +
 main.go|   5 ++
 xenworker_dummy.go |   4 ++
 3 files changed, 161 insertions(+)

diff --git a/libxl.go b/libxl.go
index 415de7f..5bdabb1 100644
--- a/libxl.go
+++ b/libxl.go
@@ -2,6 +2,7 @@ package main
 
 /*
 #include 
+#include 
 */
 import "C"
 
@@ -128,3 +129,154 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
}
return
 }
+
+
+// typedef struct {
+// uint32_t size;  /* number of bytes in map */
+// uint8_t *map;
+// } libxl_bitmap;
+// void libxl_bitmap_init(libxl_bitmap *map);
+// void libxl_bitmap_dispose(libxl_bitmap *map);
+
+// # Consistent with values defined in domctl.h
+// # Except unknown which we have made up
+// libxl_scheduler = Enumeration("scheduler", [
+// (0, "unknown"),
+// (4, "sedf"),
+// (5, "credit"),
+// (6, "credit2"),
+// (7, "arinc653"),
+// (8, "rtds"),
+// ])
+type Scheduler int
+var (
+   SchedulerUnknown  Scheduler = 0
+   SchedulerSedf Scheduler = 4
+   SchedulerCredit   Scheduler = 5
+   SchedulerCredit2  Scheduler = 6
+   SchedulerArinc653 Scheduler = 7
+   SchedulerRTDS Scheduler = 8
+)
+
+// const char *libxl_scheduler_to_string(libxl_scheduler p);
+// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
+func (s Scheduler) String() (string) {
+   cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
+   // No need to free const return value
+
+   return C.GoString(cs)
+}
+
+func SchedulerFromString(name string) (s Scheduler, err error) {
+   cname := C.CString(name)
+   defer C.free(unsafe.Pointer(cname))
+
+   var cs C.libxl_scheduler
+
+   ret := C.libxl_scheduler_from_string(cname, &cs)
+   if ret != 0 {
+   err = fmt.Errorf("libxl_scheduler_from_string failed: %d", ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
+// libxl_cpupoolinfo = Struct("cpupoolinfo", [
+// ("poolid",  uint32),
+// ("pool_name",   string),
+// ("sched",   libxl_scheduler),
+// ("n_dom",   uint32),
+// ("cpumap",  libxl_bitmap)
+// ], dir=DIR_OUT)
+
+type CpupoolInfo struct {
+   PoolId uint32
+   PoolName string
+   Scheduler Scheduler
+   DomainCount int
+   // Punt on cpumap for now
+}
+
+// libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
+// void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
+func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
+   var nbPool C.int
+
+   c_cpupool_list := C.libxl_list_cpupool(Ctx.ctx, &nbPool)
+
+   defer C.libxl_cpupoolinfo_list_free(c_cpupool_list, nbPool)
+
+   if int(nbPool) == 0 {
+   return
+   }
+
+   // Magic
+   cpupoolListSlice := (*[1 << 
30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
+
+   for i := range cpupoolListSlice {
+   var info CpupoolInfo
+   
+   info.PoolId = uint32(cpupoolListSlice[i].poolid)
+   info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
+   info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
+   info.DomainCount = int(cpupoolListSlice[i].n_dom)
+
+   list = append(list, info)
+   }
+
+   return
+}
+
+func (Ctx *Context) CpupoolFindByName(name string) (info CpupoolInfo, found 
bool) {
+   plist := Ctx.ListCpupool()
+
+   for i := range plist {
+   if plist[i].PoolName == name {
+   found = true
+   info = plist[i]
+   return
+   }
+   }
+   return
+}
+
+func XlTest(Args []string) {
+   var Ctx Context
+
+   err := Ctx.Open()
+   if err != nil {
+   fmt.Printf("Opening context: %v\n", err)
+   return
+   }
+
+   pool, found := Ctx.CpupoolFindByName("schedbench")
+
+   if found {
+   fmt.Printf("%v\n", pool)
+
+   a := int(pool.Scheduler)
+   b := pool.Scheduler.String()
+   c, err  := SchedulerFromString(b)
+
+   if err != nil {
+   fmt.Printf("Error: %v\n", err)
+   }
+
+   fmt.Printf("a: %d b: %s c: %d\n", a, b, int(c)) 
+   } else {
+   fmt.Printf("schedbench not found")
+   }
+
+   pool, found = Ctx.CpupoolFindByName("schedbnch")
+
+   if found {
+   fmt.Printf("%v\n", pool)
+   } else {
+   fmt.Printf("schedbnch not found")
+   }
+
+   Ctx

[Xen-devel] [PATCH RFC 37/59] libxl.go: Provide a single global context by default

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Provide a single global context by default, Ctx.  Allow this to be
called with Ctx.Open() multiple times (but Close() only once).

Move xenworker.go to use this global context instead; and open it when
starting the benchmark (rather than opening and closing it for every
run, which is effectively what happens now).

Signed-off-by: George Dunlap 
---
 libxl.go | 12 +---
 run.go   |  7 +++
 xenworker.go | 25 +
 3 files changed, 17 insertions(+), 27 deletions(-)

diff --git a/libxl.go b/libxl.go
index 5bdabb1..9477bca 100644
--- a/libxl.go
+++ b/libxl.go
@@ -16,19 +16,17 @@ type Context struct {
ctx *C.libxl_ctx
 }
 
-func NewContext() (Ctx *Context, err error) {
-   Ctx = &Context{}
-   
-   err = Ctx.Open()
-
-   return
-}
+var Ctx Context
 
 func (Ctx *Context) IsOpen() bool {
return Ctx.ctx != nil
 }
 
 func (Ctx *Context) Open() (err error) {
+   if Ctx.ctx != nil {
+   return
+   }
+   
ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
 
if ret != 0 {
diff --git a/run.go b/run.go
index 1b39730..08a43ff 100644
--- a/run.go
+++ b/run.go
@@ -228,6 +228,13 @@ func (plan *BenchmarkPlan) Run() (err error) {
if err != nil {
return
}
+
+   if plan.WorkerType == WorkerXen {
+   err = Ctx.Open()
+   if err != nil {
+   return
+   }
+   }

for i := range plan.Runs {
r := &plan.Runs[i];
diff --git a/xenworker.go b/xenworker.go
index 45e0876..2649392 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -27,13 +27,6 @@ import (
"io"
 )
 
-type xenGlobal struct {
-   Ctx Context
-   count int
-}
-
-var xg xenGlobal
-
 type XenWorker struct {
id WorkerId
Ctx Context
@@ -68,13 +61,9 @@ func (w *XenWorker) SetId(i WorkerId) {
 }
 
 func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
-   if xg.count == 0 {
-   err = xg.Ctx.Open()
-   if err != nil {
-   return
-   }
+   if err != nil {
+   return
}
-   xg.count++

mock := false

@@ -220,11 +209,6 @@ func (w *XenWorker) Shutdown() {
e.Stdout = os.Stdout
e.Stderr = os.Stderr
 
-   xg.count--
-   if xg.count == 0 {
-   defer xg.Ctx.Close()
-   }
-
err := e.Run()
if err != nil {
fmt.Printf("Error destroying domain: %v\n", err)
@@ -249,7 +233,8 @@ func (w *XenWorker) DumpLog(f io.Writer) (err error) {
 // FIXME: Return an error
 func (w *XenWorker) Process(report chan WorkerReport, done chan WorkerId) {
// // xl unpause [vmname]
-   err := xg.Ctx.DomainUnpause(Domid(w.domid))
+   //err := xg.Ctx.DomainUnpause(Domid(w.domid))
+   err := Ctx.DomainUnpause(Domid(w.domid))
if err != nil {
fmt.Printf("Error unpausing domain: %v\n", err)
return
@@ -268,7 +253,7 @@ func (w *XenWorker) Process(report chan WorkerReport, done 
chan WorkerId) {
var r WorkerReport
json.Unmarshal([]byte(s), &r)
r.Id = w.id
-   di, err := xg.Ctx.DomainInfo(Domid(w.domid))
+   di, err := Ctx.DomainInfo(Domid(w.domid))
// Ignore errors for now
if err == nil {
r.Cputime = di.Cpu_time
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 16/59] controller: Rename an element in BenchmarkRun to be more accurate

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 benchmark.go | 6 +++---
 main.go  | 6 +++---
 run.go   | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 2e03fe5..aaa4c98 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -84,7 +84,7 @@ type BenchmarkRunData struct {
 
 type BenchmarkRun struct {
Label string
-   Workers []WorkerSet
+   WorkerSets []WorkerSet
RuntimeSeconds int
Completed bool
Results BenchmarkRunData 
@@ -168,8 +168,8 @@ func (run *BenchmarkRun) TextReport() (err error) {
fmt.Printf("== RUN %s ==", run.Label)
 
wStart := 0
-   for i := range run.Workers {
-   ws := &run.Workers[i]
+   for i := range run.WorkerSets {
+   ws := &run.WorkerSets[i]
n := ws.Count
params := ""
for _, s := range ws.Params.Args {
diff --git a/main.go b/main.go
index ebf990f..f58068f 100644
--- a/main.go
+++ b/main.go
@@ -46,12 +46,12 @@ func main() {
filename:filename,
Runs:[]BenchmarkRun{
{Label:"baseline-a",
-   Workers:[]WorkerSet{
+   WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerA},
Count:1}},
RuntimeSeconds:10,},
{Label:"baseline-b",
-   Workers:[]WorkerSet{
+   WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerB},
Count:1}},
RuntimeSeconds:10,},
@@ -62,7 +62,7 @@ func main() {
label := fmt.Sprintf("%da+%db", i, i)
run := BenchmarkRun{
Label:label,
-   Workers:[]WorkerSet{
+   WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerA},
Count:i},
{Params:WorkerParams{workerB},
diff --git a/run.go b/run.go
index 7b5ef0a..762b408 100644
--- a/run.go
+++ b/run.go
@@ -105,7 +105,7 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e
 }
 
 func (run *BenchmarkRun) Run() (err error) {
-   Workers, err := NewWorkerList(run.Workers, WorkerXen)
+   Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
if err != nil {
fmt.Println("Error creating workers: %v", err)
return
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 31/59] Make a binary that can run reports on a system without libxl

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

To simplify report-generation and iteration, make a binary that
doesn't link against libxl.  Create a "dummy" Xen library that just
returns errors and warnings.

A better way to do this is probably to do some dlopen hackery (so we
can use the same binary), but that's for another day.

Signed-off-by: George Dunlap 
---
 Makefile   |  6 +-
 xenworker_dummy.go | 54 ++
 2 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 xenworker_dummy.go

diff --git a/Makefile b/Makefile
index c1b9ee4..6dee499 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-BIN = schedbench
+BIN = schedbench schedbench-report
 BINALL = $(BIN)
 
 .PHONY: all
@@ -16,6 +16,10 @@ CGO_LDFLAGS = -L$(XENLIB_PATH) 
-Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
 schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
+# FIXME: Do with dlopen instead
+schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go
+   go build -o $@ $^
+
 .PHONY: clean
 clean:
rm -f $(BINALL)
diff --git a/xenworker_dummy.go b/xenworker_dummy.go
new file mode 100644
index 000..02e90ce
--- /dev/null
+++ b/xenworker_dummy.go
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package main
+
+import (
+   "fmt"
+   "io"
+)
+
+type XenWorker struct {
+}
+
+func (w *XenWorker) SetId(i WorkerId) {
+}
+
+func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
+   err = fmt.Errorf("Xen functionality not implemented");
+   return
+}
+
+// FIXME: Return an error
+func (w *XenWorker) Shutdown() {
+   
+   return
+}
+
+func (w *XenWorker) DumpLog(f io.Writer) (err error) {
+   err = fmt.Errorf("Xen functionality not implemented");
+   return
+}
+
+
+
+// FIXME: Return an error
+func (w *XenWorker) Process(report chan WorkerReport, done chan WorkerId) {
+   return;
+}
+
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 58/59] remove irrelevant files from old repository

2016-12-28 Thread Ronald Rojas
Signed-off-by: Ronald Rojas 
---
 Makefile   |  31 --
 benchmark.go   | 467 --
 htmlreport.go  | 238 --
 libxl.go   | 720 -
 main.go| 146 -
 plan.go| 157 -
 processworker.go   |  98 --
 run.go | 456 --
 stubs.go   |  34 --
 tools/golang/xenlight/libxl.go | 720 +
 xenworker.go   | 278 
 11 files changed, 720 insertions(+), 2625 deletions(-)
 delete mode 100644 Makefile
 delete mode 100644 benchmark.go
 delete mode 100644 htmlreport.go
 delete mode 100644 libxl.go
 delete mode 100644 main.go
 delete mode 100644 plan.go
 delete mode 100644 processworker.go
 delete mode 100644 run.go
 delete mode 100644 stubs.go
 create mode 100644 tools/golang/xenlight/libxl.go
 delete mode 100644 xenworker.go

diff --git a/Makefile b/Makefile
deleted file mode 100644
index 699cc53..000
--- a/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-BIN = schedbench
-BINALL = $(BIN)
-
-.PHONY: all
-all: $(BIN)
-
-
-
-CGO_CFLAGS = -I/build/hg/xen.git/dist/install/usr/local/include
-
-# FIXME
-XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
-CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) 
-
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
-   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build 
-ldflags '-linkmode external -extldflags "-static"' -o $@ $^
-
-# If we use a statically linked binary we don't need this; the same
-# binary can be used on any system.  Keep this version (without any
-# run support) support) around for now in case we want to go back to
-# it.
-schedbench-report: main.go benchmark.go stubs.go htmlreport.go plan.go
-   go build -o $@ $^
-
-.PHONY: clean
-clean:
-   rm -f $(BINALL)
-
-.PHONY: dist
-dist:
-   cp $(BIN) $(DISTDIR)
diff --git a/benchmark.go b/benchmark.go
deleted file mode 100644
index abe2dfb..000
--- a/benchmark.go
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of the
- * License only.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-package main
-
-import (
-   "fmt"
-   "os"
-   "io/ioutil"
-   "encoding/json"
-   "math"
-   "time"
-)
-
-type WorkerId struct {
-   Set int
-   Id int
-}
-
-func (wid WorkerId) String() (string) {
-   return fmt.Sprintf("%d:%d", wid.Set, wid.Id)
-}
-
-type WorkerReport struct {
-   Id WorkerId
-   Now int
-   Kops int
-   MaxDelta int
-   Cputime time.Duration
-}
-
-type WorkerParams struct {
-   Args []string
-}
-
-func (l *WorkerParams) SetkHZ(kHZ uint64) {
-   if l.Args[0] == "kHZ" {
-   l.Args[1] = fmt.Sprintf("%d", kHZ)
-   } else {
-   l.Args = append([]string{"kHZ", fmt.Sprintf("%d", kHZ)}, 
l.Args...)
-   }
-}
-
-type WorkerConfig struct {
-   Pool string
-   SoftAffinity string
-}
-
-// Propagate unset values from a higher level
-func (l *WorkerConfig) PropagateFrom(g WorkerConfig) {
-   if l.Pool == "" {
-   l.Pool = g.Pool
-   }
-}
-
-type WorkerSet struct {
-   Params WorkerParams
-   Config WorkerConfig
-   Count int
-}
-
-const (
-   USEC = 1000
-   MSEC = USEC * 1000
-   SEC = MSEC * 1000
-)
-
-func Throughput(lt int, lm int, t int, m int) (tput float64) {
-   time := float64(t - lt) / SEC
-   kops := m - lm
-   
-   tput = float64(kops) / time
-   return
-}
-
-func Utilization(lt int, lct time.Duration, t int, ct time.Duration) (util 
float64) {
-   util = float64(ct - lct) / float64(t - lt)
-   return
-}
-
-type MinMax struct {
-   Min float64
-   Max float64
-}
-
-func (mm *MinMax) Update(x float64) {
-   if x > mm.Max {
-   mm.Max = x
-   }
-   if x < mm.Min || mm.Min == 0 {
-   mm.Min = x
-   }
-}
-
-type Worke

[Xen-devel] [PATCH RFC 43/59] libxl: Add bitmap support

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Make the structure compatible so that we can just copy things out or
in.

Use it to complete the Cpupool structure.

Signed-off-by: George Dunlap 
---
 libxl.go | 104 +++
 1 file changed, 98 insertions(+), 6 deletions(-)

diff --git a/libxl.go b/libxl.go
index 27e7766..3f6ba01 100644
--- a/libxl.go
+++ b/libxl.go
@@ -20,8 +20,8 @@ package main
 
 /*
 #cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
-#include 
 #include 
+#include 
 */
 import "C"
 
@@ -72,6 +72,7 @@ func (Ctx *Context) Close() (err error) {
return
 }
 
+// Builtins
 type Domid uint32
 
 type MemKB uint64
@@ -160,8 +161,66 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
 // uint32_t size;  /* number of bytes in map */
 // uint8_t *map;
 // } libxl_bitmap;
-// void libxl_bitmap_init(libxl_bitmap *map);
-// void libxl_bitmap_dispose(libxl_bitmap *map);
+
+// Implement the Go bitmap type such that the underlying data can
+// easily be copied in and out.  NB that we still have to do copies
+// both directions, because cgo runtime restrictions forbid passing to
+// a C function a pointer to a Go-allocated structure which contains a
+// pointer.
+type Bitmap struct {
+   bitmap []C.uint8_t
+}
+
+func (bm *Bitmap) Alloc(max int) {
+   bm.bitmap = make([]C.uint8_t, (max + 7) / 8)
+}
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func bitmapCToGo(cbm *C.libxl_bitmap) (bm Bitmap) {
+   // Alloc a Go slice for the bytes
+   size := int(cbm.size)
+   bm.Alloc(size*8)
+
+   // Make a slice pointing to the C array
+   mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+   // And copy the C array into the Go array
+   copy(bm.bitmap, mapslice)
+
+   return
+}
+
+func (bm *Bitmap) Test(bit int) (bool) {
+   ubit := uint(bit)
+   if (bit > bm.Max()) {
+   return false
+   }
+   
+   return (bm.bitmap[bit / 8] & (1 << (ubit & 7))) != 0
+}
+
+// FIXME: Do we really just want to silently fail here?
+func (bm *Bitmap) Set(bit int) {
+   ubit := uint(bit)
+   if (bit > bm.Max()) {
+   return
+   }
+   
+   bm.bitmap[bit / 8] |= 1 << (ubit & 7)
+}
+
+func (bm *Bitmap) Clear(bit int) {
+   ubit := uint(bit)
+   if (bit > bm.Max()) {
+   return
+   }
+   
+   bm.bitmap[bit / 8] &= ^(1 << (ubit & 7))
+}
+
+func (bm *Bitmap) Max() (int) {
+   return len(bm.bitmap) * 8
+}
 
 // # Consistent with values defined in domctl.h
 // # Except unknown which we have made up
@@ -222,7 +281,7 @@ type CpupoolInfo struct {
PoolName string
Scheduler Scheduler
DomainCount int
-   // Punt on cpumap for now
+   CpuMap Bitmap
 }
 
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
@@ -248,6 +307,7 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
info.DomainCount = int(cpupoolListSlice[i].n_dom)
+   info.CpuMap = bitmapCToGo(&cpupoolListSlice[i].cpumap)
 
list = append(list, info)
}
@@ -268,6 +328,24 @@ func (Ctx *Context) CpupoolFindByName(name string) (info 
CpupoolInfo, found bool
return
 }
 
+// int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
+//  libxl_scheduler sched,
+//  libxl_bitmap cpumap, libxl_uuid *uuid,
+//  uint32_t *poolid);
+// int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
+// int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid);
+// int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
+// int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+// int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
+// const libxl_bitmap *cpumap);
+// int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
+// int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+// int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
+//const libxl_bitmap *cpumap);
+// int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t 
domid);
+// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
+
+   
 func XlTest(Args []string) {
var Ctx Context
 
@@ -290,7 +368,21 @@ func XlTest(Args []string) {
fmt.Printf("Error: %v\n", err)
}
 
-   fmt.Printf("a: %d b: %s c: %d\n", a, b, int(c)) 
+   fmt.Printf("a: %d b: 

[Xen-devel] [PATCH RFC 14/59] benchmark: Store data in terms of worker sets and worker ids

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

...rather than having a single global index, in preparation for
summarizing sets of workers as well as individual workers.

To do this:

- Define a WorkerId type which consists of the worker set + worker id
  within that set.  Pass this to the workers and use this in the
  report values.

- Use maps based on this WorkerId for currently running processes,
  accumulated data, and (for now) the results summary.

In a future patch, we'll break down the results summary by worker sets
as well.

Signed-off-by: George Dunlap 
---
 benchmark.go | 120 +++
 processworker.go |   4 +-
 xenworker.go |   6 +--
 3 files changed, 63 insertions(+), 67 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 2a78d26..4354a47 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -33,8 +33,17 @@ type WorkerSummary struct {
MinTput float64
 }
 
-type WorkerReport struct {
+type WorkerId struct {
+   Set int
Id int
+}
+
+func (wid WorkerId) String() (string) {
+   return fmt.Sprintf("%d:%d", wid.Set, wid.Id)
+}
+
+type WorkerReport struct {
+   Id WorkerId
Now int
Mops int
MaxDelta int
@@ -50,7 +59,7 @@ type WorkerSet struct {
 }
 
 type Worker interface {
-   SetId(int)
+   SetId(WorkerId)
Init(WorkerParams) error
Shutdown()
Process(chan WorkerReport, chan bool)
@@ -86,13 +95,13 @@ func Report(ws *WorkerState, r WorkerReport) {
 
tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)

-   fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
+   fmt.Printf("%v Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
}
 
ws.LastReport = r
 }
 
-type WorkerList []WorkerState
+type WorkerList map[WorkerId]*WorkerState
 
 func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
i = 0
@@ -114,41 +123,44 @@ const (
WorkerXen = iota
 )
 
-func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
-   count := 0
+func NewWorkerList(workers []WorkerSet, workerType int) (wl WorkerList, err 
error) {
+   wl = WorkerList(make(map[WorkerId]*WorkerState))
 
-   // wsi: WorkerSet index
for wsi := range workers {
-   count += workers[wsi].Count
-   }
+   for i := 0; i < workers[wsi].Count; i = i+1 {
+   Id := WorkerId{Set:wsi,Id:i}
 
-   fmt.Println("Making ", count, " total workers")
-   ws = WorkerList(make([]WorkerState, count))
+   ws := wl[Id]
 
-   // wli: WorkerList index
-   wli := 0
-   for wsi := range workers {
-   for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+   if ws != nil {
+   panic("Duplicate worker for id!")
+   }
+   
+   ws = &WorkerState{}
+   
switch workerType {
case WorkerProcess:
-   ws[wli].w = &ProcessWorker{}
+   ws.w = &ProcessWorker{}
case WorkerXen:
-   ws[wli].w = &XenWorker{}
+   ws.w = &XenWorker{}
default:
err = fmt.Errorf("Unknown type: %d", workerType)
+   return
}
-   ws[wli].w.SetId(wli)
+   
+   ws.w.SetId(Id)

-   ws[wli].w.Init(workers[wsi].Params)
+   ws.w.Init(workers[wsi].Params)
+
+   wl[Id] = ws
}
}
return
 }
 
 type BenchmarkRunData struct {
-   WorkerCount int
Raw []WorkerReport   `json:",omitempty"`
-   Summary []WorkerSummary  `json:",omitempty"`
+   Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
@@ -174,8 +186,6 @@ func (run *BenchmarkRun) Run() (err error) {

i := Workers.Start(report, done)
 
-   run.Results.WorkerCount = i
-
// FIXME:
// 1. Make a zero timeout mean "never"
// 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
@@ -185,7 +195,7 @@ func (run *BenchmarkRun) Run() (err error) {
select {
case r := <-report:
run.Results.Raw = append(run.Results.Raw, r)
-   Report(&Workers[r.Id], r)
+   Report(Workers[r.Id], r)
case <-done:
i--;
fmt.Println(i, "workers left");
@@ -215,22 +225,11 @@ func (run *BenchmarkRun) Run() (err error) {
 }
 
 func (ru

[Xen-devel] [PATCH RFC 51/59] controller: Make and/or modify cpupools when possible

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Make it possible for schedbench to modify cpupools in order to satisfy
run constraints.

Make a "RunConfig" option which contains the name of the pool, the
scheduler, and the number of cpus.  As with WorkerConfig, make these
automatically inherited from larger levels to smaller levels.  This
makes it straightforward to allow arbitrary pool configurations in the
same plan.

Modify sample.bench to have a RunConfig entry at the top level
(instead of the WorkerConfig option).  SimplePlan already sets
RunConfig.Scheduler, so the effect will be for each run to have all
three options set.  (Punt on SimplePlan generating more complex
options for now.)

Change BenchmarkRun.Ready() to BenchmarkRun.Prep(), which will cause
the configuration in RunConfig to become true if possible.  Empty
'Pool' element means the default pool (Pool-0).  Always create the
cpupool if it's non-pool-0, destroying the current one if it exists.

If it is pool 0, just check if it matches, and skip if not.

(We could in theory modify cpupool 0, but push that for future work.)

Signed-off-by: George Dunlap 
---
 benchmark.go |  17 +-
 run.go   | 176 +++
 2 files changed, 169 insertions(+), 24 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index aecb574..bd513fd 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -67,7 +67,6 @@ func (l *WorkerConfig) PropagateFrom(g WorkerConfig) {
}
 }
 
-
 type WorkerSet struct {
Params WorkerParams
Config WorkerConfig
@@ -140,6 +139,21 @@ type BenchmarkRunData struct {
 
 type RunConfig struct {
Scheduler string
+   Pool string
+   Cpus []int
+}
+
+// Propagate unset values from a higher level
+func (l *RunConfig) PropagateFrom(g RunConfig) {
+   if l.Pool == "" {
+   l.Pool = g.Pool
+   }
+   if l.Scheduler == "" {
+   l.Scheduler = g.Scheduler
+   }
+   if l.Cpus == nil {
+   l.Cpus = g.Cpus
+   }
 }
 
 type BenchmarkRun struct {
@@ -159,6 +173,7 @@ type BenchmarkPlan struct {
// Global options for workers that will be over-ridden by Run
// and WorkerSet config options
WorkerConfig `json:",omitempty"`
+   RunConfig RunConfig   `json:",omitempty"`
Runs []BenchmarkRun  `json:",omitempty"`
 }
 
diff --git a/run.go b/run.go
index 1a753bc..2d0db01 100644
--- a/run.go
+++ b/run.go
@@ -156,34 +156,158 @@ func getCpuHz() (err error) {
return
 }
 
-func (run *BenchmarkRun) Ready() (ready bool, why string) {
-   // FIXME: Check WorkerType
-   // Skip this run if it's not the scheduler we want
-   if run.RunConfig.Scheduler != "" {
-   var pool CpupoolInfo
-   if run.WorkerConfig.Pool != "" {
-   var found bool
-   pool, found = 
Ctx.CpupoolFindByName(run.WorkerConfig.Pool)
-   if !found {
-   why = "cpupool error"
-   return
-   }
-   } else {
-   // xl defaults to cpupool 0
-   plist := Ctx.ListCpupool()
-   if len(plist) > 0 {
-   pool = plist[0]
+// If the pool is specified, use that pool; otherwise assume pool 0.
+//
+// Unspecified schedulers match any pool; unspecifiend cpu lists match
+// any pool.
+//
+// If the pool exists and the scheduler and cpu lists match the pool,
+// carry on.  (This is running the VMs in a pre-configured pool.)
+//
+// If the pool exists and either the scheduler or the cpus don't match
+// the pool, and this is pool 0, skip.
+//
+// TODO: If the scheduler matches but the cpus don't, modify the pool
+// by adding or removing cpus.  (This can be done for Pool-0 as well.)
+//
+// If the pool is not Pool-0, and the scheduler doesn't match or the
+// pool doesn't exist, but there are no cpus, skip (because we don't
+// have enough information to create the pool).
+//
+// If the pool is not Pool-0, and either the scheduler or the cpus
+// don't match, and the cpus are specified, create the pool.
+func (run *BenchmarkRun) Prep() (ready bool, why string) {
+   var pool CpupoolInfo
+   poolPresent := false
+   
+   // Generate the requested cpumap
+   var Cpumap Bitmap
+   if run.RunConfig.Cpus != nil {
+   fmt.Print("Run.Prep: Cpus: ")
+   printed := false
+   for _, i := range run.RunConfig.Cpus {
+   if printed {
+   fmt.Printf(",%d", i)
} else {
-   why = "cpupool error"
-   return
+   printed = true
+   fmt.Printf("%d", i)
+   }   
+   Cpumap.Set(i)
+   }
+

[Xen-devel] [PATCH RFC 32/59] controller: Allow specification of an input file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

So that we can analyze data later if we want.

Signed-off-by: George Dunlap 
---
 main.go | 194 +++-
 1 file changed, 106 insertions(+), 88 deletions(-)

diff --git a/main.go b/main.go
index f8d77cf..ddb768c 100644
--- a/main.go
+++ b/main.go
@@ -26,101 +26,119 @@ import (
 )
 
 func main() {
-   filename := "test.bench"
-
-   switch(os.Args[1]) {
-   case "plan":
-   workerA := []string{"burnwait", "70", "20"}
-   //workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "10", "30",
-   "burnwait", "20", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "30", "30",
-   }
+   Args := os.Args
 
+   Args = Args[1:]
+   filename := "test.bench"
 
-   plan :=  BenchmarkPlan{
-   WorkerType:WorkerXen,
-   WorkerConfig:WorkerConfig{Pool:"schedbench"},
-   filename:filename,
-   Runs:[]BenchmarkRun{
-   {Label:"baseline-a",
+   for len(Args) > 0 {
+   switch(Args[0]) {
+   case "-f":
+   if len(Args) < 2 {
+   fmt.Println("Need arg for -f")
+   os.Exit(1)
+   }
+   filename = Args[1]
+   Args = Args[2:]
+   case "plan":
+   workerA := []string{"burnwait", "70", "20"}
+   //workerB := []string{"burnwait", "10", "2000"}
+   workerB := []string{"burnwait", "10", "30",
+   "burnwait", "20", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "30", "30",
+   }
+   
+   
+   plan :=  BenchmarkPlan{
+   WorkerType:WorkerXen,
+   WorkerConfig:WorkerConfig{Pool:"schedbench"},
+   filename:filename,
+   Runs:[]BenchmarkRun{
+   {Label:"baseline-a",
+   WorkerSets:[]WorkerSet{
+   
{Params:WorkerParams{workerA},
+   Count:1}},
+   RuntimeSeconds:10,},
+   {Label:"baseline-b",
+   WorkerSets:[]WorkerSet{
+   
{Params:WorkerParams{workerB},
+   Count:1}},
+   RuntimeSeconds:10,},
+   }}
+   
+   for i := 1; i <= 16 ; i *= 2 {
+   label := fmt.Sprintf("%da+%db", i, i)
+   run := BenchmarkRun{
+   Label:label,
WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerA},
-   Count:1}},
-   RuntimeSeconds:10,},
-   {Label:"baseline-b",
-   WorkerSets:[]WorkerSet{
+   Count:i},
{Params:WorkerParams{workerB},
-   Count:1}},
-   RuntimeSeconds:10,},
-   }}
-
-   for i := 1; i <= 16 ; i *= 2 {
-   label := fmt.Sprintf("%da+%db", i, i)
-   run := BenchmarkRun{
-   Label:label,
-   WorkerSets:[]WorkerSet{
-   {Params:WorkerParams{workerA},
-   Count:i},
-   {Params:WorkerParams{workerB},
-   Count:i}},
-   RuntimeSeconds:10}
-   plan.Runs = ap

[Xen-devel] [PATCH RFC 55/59] plan: Make the matrix generation more programmatic

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Rather than have nested loops, keep a running list of all the configs
we've created so far.  Then for each existing new element of the
matrix, combine it with all the existing columns.

Signed-off-by: George Dunlap 
---
 plan.go | 50 +++---
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/plan.go b/plan.go
index e535603..736d9f3 100644
--- a/plan.go
+++ b/plan.go
@@ -72,7 +72,9 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
schedulers = append(schedulers, "")
}
 
-   // Always do the baselines
+   // Start by making a slice with baselines and each of the counts
+   var a, b []BenchmarkRun
+   
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]

@@ -85,39 +87,49 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
WorkerSets:[]WorkerSet{{Params:wp, Count:1}},
RuntimeSeconds:10,
}
-   
-   for _, s := range schedulers {
-   fmt.Printf("Making baseline %s run, sched %s\n", wn, s)
-   run.RunConfig.Scheduler = s
-   run.Label = wn+" baseline "+s
-   plan.Runs = append(plan.Runs, run)
-   }
+
+   run.Label = wn+" baseline"
+   a = append(a, run)
}
-   
+
+
for _, c := range plan.Input.SimpleMatrix.Count {
run := BenchmarkRun{
RuntimeSeconds:10,
}

-   var label string
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]

-   if label != "" {
-   label = label+" + "
+   if run.Label != "" {
+   run.Label = run.Label+" + "
}
-   label = fmt.Sprintf("%s%s %d ", label, wn, c)
-   
+   run.Label = fmt.Sprintf("%s%s %d", run.Label, wn, c)
+
ws := WorkerSet{Params:wp, Count:c}
run.WorkerSets = append(run.WorkerSets, ws)
}
-   for _, s := range schedulers {
-   fmt.Printf("Making count %d run, sched %s\n", c, s)
-   run.RunConfig.Scheduler = s
-   run.Label = label+s
-   plan.Runs = append(plan.Runs, run)
+
+   a = append(a, run)
+   }
+
+   // ...then cross it by schedulers
+   if len(schedulers) > 0 {
+   for _, base := range a {
+   for _, s := range schedulers {
+   run := base
+   run.RunConfig.Scheduler = s
+   run.Label = run.Label+" "+s
+   b = append(b, run)
+   }
}
+   a = b
+   b = nil
}
 
+   for i := range a {
+   fmt.Printf("%s\n", a[i].Label)
+   }
+   plan.Runs = a;
return
 }
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 50/59] libxl: Fix Bitmap.Max(), make Test() / Clear() more robust

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Bitmap.Max() should return the largest currently addressable bit; at the
moment it returns the total number of bits (which is one greater than
the largest addressable bit).

This also implicitly fixes a bug in Test() and Clear() which would cause
an out-of-range error when testing a bit equal to Max().

While we're here, allow Test() and Clear() to handle null bitmaps, the
same way Set() can.

Signed-off-by: George Dunlap 
---
 libxl.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libxl.go b/libxl.go
index dfe4f40..bfcaf0d 100644
--- a/libxl.go
+++ b/libxl.go
@@ -270,7 +270,7 @@ func bitmapGotoC(gbm Bitmap) (cbm C.libxl_bitmap) {
 
 func (bm *Bitmap) Test(bit int) (bool) {
ubit := uint(bit)
-   if (bit > bm.Max()) {
+   if (bit > bm.Max() || bm.bitmap == nil) {
return false
}

@@ -294,7 +294,7 @@ func (bm *Bitmap) SetRange(start int, end int) {
 
 func (bm *Bitmap) Clear(bit int) {
ubit := uint(bit)
-   if (bit > bm.Max()) {
+   if (bit > bm.Max() || bm.bitmap == nil) {
return
}

@@ -308,7 +308,7 @@ func (bm *Bitmap) ClearRange(start int, end int) {
 }
 
 func (bm *Bitmap) Max() (int) {
-   return len(bm.bitmap) * 8
+   return len(bm.bitmap) * 8 - 1
 }
 
 func (bm *Bitmap) IsEmpty() (bool) {
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 30/59] htmlreport: Include utilization scatterplots

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Reformat RunRaw so that it's a more generic scatterplot, with the
caller specifying the javascript tag, title, and axes.  Keep them as a
straight list to be displayed rather than defining them on a per-run
basis.

Collect a slice of utilization points at the same time as collecting
the throughput metrics, add them both at the same time.

While we're here, add "omitempty" to some of the options so no json is
generated if nothing is specified.  Leave "MinValue" so that we are
able to specify a zero origin (which will also be the default).

Finally, don't bother finding minimum and maximum points; the chart
plotter will do that anyway.

Signed-off-by: George Dunlap 
---
 htmlreport.go | 89 +++
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/htmlreport.go b/htmlreport.go
index 6f61998..545582d 100644
--- a/htmlreport.go
+++ b/htmlreport.go
@@ -26,16 +26,17 @@ import (
 )
 
 type OptionAxis struct {
-   Title string `json:"title"`
+   Title string `json:"title,omitempty"`
+   // Always include this one so that we can start graphs at 0
MinValue float64 `json:"minValue"`
-   MaxValue float64 `json:"maxValue"`
+   MaxValue float64 `json:"maxValue,omitempty"`
 }
 
 type Options struct {
-   Title string `json:"title"`
+   Title string `json:"title,omitempty"`
HAxis OptionAxis `json:"hAxis"`
VAxis OptionAxis `json:"vAxis"`
-   Legend string`json:"legend"`
+   Legend string`json:"legend,omitempty"`
 }
 
 type Point struct {
@@ -44,18 +45,21 @@ type Point struct {
 }
 
 type RunRaw struct {
-   Label string
+   Tag string
+   Title string
+   hTitle string
+   vTitle string
Points [][]Point
 }
 
-func (options *Options) OutputJavascript(w io.Writer, id int) (err error) {
+func (options *Options) OutputJavascript(w io.Writer, tag string) (err error) {
var optionsJson []byte
optionsJson, err = json.Marshal(options)
if err != nil {
return
}
 
-   fmt.Fprintf(w, "var sp%dopt = ", id)
+   fmt.Fprintf(w, "var %sopt = ", tag)
fmt.Fprint(w, string(optionsJson))
fmt.Fprintln(w, ";")
 
@@ -75,41 +79,29 @@ func (p *Point) OutputJson(w io.Writer, id int, max int) 
(err error) {
return
 }
 
-func (d *RunRaw) OutputHTML(w io.Writer, run int) (err error) {
-   fmt.Fprintf(w, "\n", run)
+func (d *RunRaw) OutputHTML(w io.Writer) (err error) {
+   fmt.Fprintf(w, "\n", d.Tag)
return
 }
 
-func (d *RunRaw) OutputJavascript(w io.Writer, run int) (err error) {
+func (d *RunRaw) OutputJavascript(w io.Writer) (err error) {
var options Options
 
-   options.Title = fmt.Sprintf("Run %s (%d) Individual Throughput", 
d.Label, run)
-   options.HAxis.Title = "Time"
-   options.VAxis.Title = "Throughput"
+   options.Title = d.Title
+   options.HAxis.Title = d.hTitle
+   options.VAxis.Title = d.vTitle
 
-   var xmm MinMax
-   var ymm MinMax
-   for i := range d.Points {
-   for j := range d.Points[i] {
-   xmm.Update(d.Points[i][j].x)
-   ymm.Update(d.Points[i][j].y)
-   }
-   }
-
-   options.HAxis.MaxValue = xmm.Max
-   options.VAxis.MaxValue = ymm.Max
-
-   err = options.OutputJavascript(w, run)
+   err = options.OutputJavascript(w, d.Tag)
if err != nil {
return
}
 
-   fmt.Printf("var sp%ddata = new 
google.visualization.DataTable();\n", run)
-   fmt.Printf("sp%ddata.addColumn('number', 'Time');\n", run)
+   fmt.Printf("var %sdata = new 
google.visualization.DataTable();\n", d.Tag)
+   fmt.Printf("%sdata.addColumn('number', 'Time');\n", d.Tag)
for i := range d.Points {
-   fmt.Printf("sp%ddata.addColumn('number', 'Worker 
%d');\n", run, i)
+   fmt.Printf("%sdata.addColumn('number', 'Worker 
%d');\n", d.Tag, i)
}
-   fmt.Printf("sp%ddata.addRows([\n", run)
+   fmt.Printf("%sdata.addRows([\n", d.Tag)
 
// Can't use json here because we need to be able to use 'null' for 
non-existent values
for i := range d.Points {
@@ -122,8 +114,8 @@ func (d *RunRaw) OutputJavascript(w io.Writer, run int) 
(err error) {
}
fmt.Print("  ]);\n")

-   fmt.Printf("var sp%dchart = new 
google.visualization.ScatterChart(document.getElementById('scatterplot%d'));\n",
 run, run);
-   fmt.Printf("sp%dchart.draw(sp%ddata, sp%dopt);\n\n", run, run, 
run)
+   fmt.Printf("var %schart = new 
google.visualization.ScatterChart(document.getElementById('scatterplot%s'));\n",
 d.Tag, d.Tag);
+   fmt.Printf("%schart.draw(%sdata, %sopt);\n\n", d.Tag, d.Tag, 
d.Tag)

return
 }
@@ -

[Xen-devel] [PATCH RFC 47/59] libxl: Reorganize code

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Put all type and enumeration definitions at the top of the file,
separated into "builtins" and "idl-generated".

Also define Uuid as C.libxl_uud.  (Not sure if this gives us the
functionality we need without having to manually copy things in.)

Finally, get rid of Bitmap.Alloc().  It's redundant now that
Bitmap.Set() automatically extends the array.

Signed-off-by: George Dunlap 
---
 libxl.go | 189 ++-
 1 file changed, 102 insertions(+), 87 deletions(-)

diff --git a/libxl.go b/libxl.go
index 16f4645..e73c06b 100644
--- a/libxl.go
+++ b/libxl.go
@@ -39,10 +39,102 @@ import (
"time"
 )
 
+/*
+ * Types: Builtins
+ */
+
+type Domid uint32
+
+type MemKB uint64
+
+// typedef struct {
+// uint32_t size;  /* number of bytes in map */
+// uint8_t *map;
+// } libxl_bitmap;
+
+// Implement the Go bitmap type such that the underlying data can
+// easily be copied in and out.  NB that we still have to do copies
+// both directions, because cgo runtime restrictions forbid passing to
+// a C function a pointer to a Go-allocated structure which contains a
+// pointer.
+type Bitmap struct {
+   bitmap []C.uint8_t
+}
+
 type Context struct {
ctx *C.libxl_ctx
 }
 
+type Uuid C.libxl_uuid
+
+/*
+ * Types: IDL
+ * 
+ * FIXME: Generate these automatically from the IDL
+ */
+type Dominfo struct {
+   Uuid  Uuid
+   Domid Domid
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   Never_stopbool
+   
+   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
+   Outstanding_memkb MemKB
+   Current_memkb MemKB
+   Shared_memkb  MemKB
+   Paged_memkb   MemKB
+   Max_memkb MemKB
+   Cpu_time  time.Duration
+   Vcpu_max_id   uint32
+   Vcpu_online   uint32
+   Cpupool   uint32
+   Domain_type   int32 //FIXME libxl_domain_type enumeration
+
+}
+
+// # Consistent with values defined in domctl.h
+// # Except unknown which we have made up
+// libxl_scheduler = Enumeration("scheduler", [
+// (0, "unknown"),
+// (4, "sedf"),
+// (5, "credit"),
+// (6, "credit2"),
+// (7, "arinc653"),
+// (8, "rtds"),
+// ])
+type Scheduler int
+var (
+   SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
+   SchedulerSedf Scheduler = C.LIBXL_SCHEDULER_SEDF
+   SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
+   SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
+   SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
+   SchedulerRTDS Scheduler = C.LIBXL_SCHEDULER_RTDS
+)
+
+// libxl_cpupoolinfo = Struct("cpupoolinfo", [
+// ("poolid",  uint32),
+// ("pool_name",   string),
+// ("sched",   libxl_scheduler),
+// ("n_dom",   uint32),
+// ("cpumap",  libxl_bitmap)
+// ], dir=DIR_OUT)
+
+type CpupoolInfo struct {
+   Poolid uint32
+   PoolName string
+   Scheduler Scheduler
+   DomainCount int
+   Cpumap Bitmap
+}
+
+/*
+ * Context
+ */
 var Ctx Context
 
 func (Ctx *Context) IsOpen() bool {
@@ -72,43 +164,12 @@ func (Ctx *Context) Close() (err error) {
return
 }
 
-// Builtins
-type Domid uint32
-
-type MemKB uint64
-
-// FIXME: Use the idl to generate types
-type Dominfo struct {
-   // FIXME: uuid
-   Domid Domid
-   Running   bool
-   Blocked   bool
-   Pausedbool
-   Shutdown  bool
-   Dying bool
-   Never_stopbool
-   
-   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
-   Outstanding_memkb MemKB
-   Current_memkb MemKB
-   Shared_memkb  MemKB
-   Paged_memkb   MemKB
-   Max_memkb MemKB
-   Cpu_time  time.Duration
-   Vcpu_max_id   uint32
-   Vcpu_online   uint32
-   Cpupool   uint32
-   Domain_type   int32 //FIXME libxl_domain_type enumeration
-
-}
-
 func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
if Ctx.ctx == nil {
err = fmt.Errorf("Context not opened")
return
}
 
-   
var cdi C.libxl_dominfo
 
ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(&cdi), 
C.uint32_t(Id))
@@ -119,8 +180,12 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err 
error) {
return
}
 
-   // FIXME -- use introspection to make this more robust
+   // We could consider having this boilerplate generated by the
+   // idl, in a function like this:
+   //
+   // di = translateCdomaininfoToGoDomaininfo(cdi)
di = &Dominfo{}
+   di.Uuid = Uuid(cdi.uuid)
di.Domid = Domid(cdi.domid)
di.Running = b

[Xen-devel] [PATCH RFC 28/59] controller: Handle worker early death

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Log raw worker output.  In the event of an unexpected worker death,
dump the output and stop further processing.

Also fix an assert that caused workers to die if the timer was too
exact.

Signed-off-by: George Dunlap 
---
 benchmark.go |  7 ---
 processworker.go | 18 --
 run.go   | 24 ++--
 xenworker.go | 21 +++--
 4 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 5e35997..de1f650 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -74,13 +74,6 @@ type WorkerSet struct {
Count int
 }
 
-type Worker interface {
-   SetId(WorkerId)
-   Init(WorkerParams, WorkerConfig) error
-   Shutdown()
-   Process(chan WorkerReport, chan bool)
-}
-
 const (
USEC = 1000
MSEC = USEC * 1000
diff --git a/processworker.go b/processworker.go
index f517321..999e76a 100644
--- a/processworker.go
+++ b/processworker.go
@@ -32,6 +32,7 @@ type ProcessWorker struct {
c *exec.Cmd
stdout io.ReadCloser
jsonStarted bool
+   Log []string
 }
 
 func (w *ProcessWorker) SetId(i WorkerId) {
@@ -54,7 +55,19 @@ func (w *ProcessWorker) Shutdown() {
w.c.Process.Kill()
 }
 
-func (w *ProcessWorker) Process(report chan WorkerReport, done chan bool) {
+func (w *ProcessWorker) DumpLog(f io.Writer) (err error) {
+   b := bufio.NewWriter(f)
+   defer b.Flush()
+   for _, line := range w.Log {
+   _, err = fmt.Println(b, line)
+   if err != nil {
+   return
+   }
+   }
+   return
+}
+
+func (w *ProcessWorker) Process(report chan WorkerReport, done chan WorkerId) {
w.c.Start()
 
scanner := bufio.NewScanner(w.stdout)
@@ -63,6 +76,7 @@ func (w *ProcessWorker) Process(report chan WorkerReport, 
done chan bool) {
s := scanner.Text()

//fmt.Println("Got these bytes: ", s);
+   w.Log = append(w.Log, s)
 
if w.jsonStarted {
var r WorkerReport
@@ -77,7 +91,7 @@ func (w *ProcessWorker) Process(report chan WorkerReport, 
done chan bool) {
}
}
 
-   done <- true
+   done <- w.id
 
w.c.Wait()
 }
diff --git a/run.go b/run.go
index ed1957b..1b39730 100644
--- a/run.go
+++ b/run.go
@@ -26,6 +26,7 @@ import (
"regexp"
"strconv"
"bufio"
+   "io"
 )
 
 type WorkerState struct {
@@ -33,6 +34,14 @@ type WorkerState struct {
LastReport WorkerReport
 }
 
+type Worker interface {
+   SetId(WorkerId)
+   Init(WorkerParams, WorkerConfig) error
+   Shutdown()
+   Process(chan WorkerReport, chan WorkerId)
+   DumpLog(io.Writer) error
+}
+
 func Report(ws *WorkerState, r WorkerReport) {
//fmt.Println(r)
 
@@ -57,7 +66,7 @@ func Report(ws *WorkerState, r WorkerReport) {
 
 type WorkerList map[WorkerId]*WorkerState
 
-func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
+func (ws *WorkerList) Start(report chan WorkerReport, done chan WorkerId) (i 
int) {
i = 0
for j := range *ws {
go (*ws)[j].w.Process(report, done)
@@ -160,7 +169,7 @@ func (run *BenchmarkRun) Run() (err error) {
}

report := make(chan WorkerReport)
-   done := make(chan bool)
+   done := make(chan WorkerId)
signals := make(chan os.Signal, 1)
 
signal.Notify(signals, os.Interrupt)
@@ -179,12 +188,16 @@ func (run *BenchmarkRun) Run() (err error) {
run.Results.Raw = append(run.Results.Raw, r)
Report(Workers[r.Id], r)
}
-   case <-done:
+   case did := <-done:
if ! stopped {
-   fmt.Println("WARNING: Worker left early")
+   fmt.Println("WARNING: Worker", did, "left 
early, shutting down workers")
+   Workers.Stop()
+   stopped = true
+   err = fmt.Errorf("Worker %v exited early", did)
+   Workers[did].w.DumpLog(os.Stdout)
}
i--;
-   fmt.Println(i, "workers left");
+   fmt.Printf("Worker %v exited; %d workers left\n", did, 
i);
case <-timeout:
if ! stopped {
Workers.Stop()
@@ -201,7 +214,6 @@ func (run *BenchmarkRun) Run() (err error) {
}
err = fmt.Errorf("Interrupted")
} else {
-   err = fmt.Errorf("Interrupted")
fmt.Println("SIGINT received after stop, 
exiting without cleaning up")
 

[Xen-devel] [PATCH RFC 29/59] report: Add basic html report

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Use Google's chartapi to create a (mostly) self-contained html file.
Start with just scatterplots of the raw data for proof-of-concept.

Signed-off-by: George Dunlap 
---
 Makefile  |   2 +-
 benchmark.go  |   1 +
 htmlreport.go | 233 ++
 main.go   |  12 +++
 4 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 htmlreport.go

diff --git a/Makefile b/Makefile
index 54f2ce8..c1b9ee4 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ CGO_LIBS = -lyajl -lxenlight
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
 CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
index de1f650..8be00a0 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -438,3 +438,4 @@ func (plan *BenchmarkPlan) TextReport(level int) (err 
error) {
 
return
 }
+
diff --git a/htmlreport.go b/htmlreport.go
new file mode 100644
index 000..6f61998
--- /dev/null
+++ b/htmlreport.go
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package main
+
+import (
+   "fmt"
+   "os"
+   "io"
+   "encoding/json"
+)
+
+type OptionAxis struct {
+   Title string `json:"title"`
+   MinValue float64 `json:"minValue"`
+   MaxValue float64 `json:"maxValue"`
+}
+
+type Options struct {
+   Title string `json:"title"`
+   HAxis OptionAxis `json:"hAxis"`
+   VAxis OptionAxis `json:"vAxis"`
+   Legend string`json:"legend"`
+}
+
+type Point struct {
+   x float64
+   y float64
+}
+
+type RunRaw struct {
+   Label string
+   Points [][]Point
+}
+
+func (options *Options) OutputJavascript(w io.Writer, id int) (err error) {
+   var optionsJson []byte
+   optionsJson, err = json.Marshal(options)
+   if err != nil {
+   return
+   }
+
+   fmt.Fprintf(w, "var sp%dopt = ", id)
+   fmt.Fprint(w, string(optionsJson))
+   fmt.Fprintln(w, ";")
+
+   return
+}
+
+func (p *Point) OutputJson(w io.Writer, id int, max int) (err error) {
+   fmt.Fprintf(w, "[%f", p.x)
+   for i := 0; i < max; i++ {
+   if i == id {
+   fmt.Fprintf(w, ", %f", p.y)
+   } else {
+   fmt.Fprintf(w, ", null")
+   }
+   }
+   fmt.Fprint(w, "],\n")
+   return
+}
+
+func (d *RunRaw) OutputHTML(w io.Writer, run int) (err error) {
+   fmt.Fprintf(w, "\n", run)
+   return
+}
+
+func (d *RunRaw) OutputJavascript(w io.Writer, run int) (err error) {
+   var options Options
+
+   options.Title = fmt.Sprintf("Run %s (%d) Individual Throughput", 
d.Label, run)
+   options.HAxis.Title = "Time"
+   options.VAxis.Title = "Throughput"
+
+   var xmm MinMax
+   var ymm MinMax
+   for i := range d.Points {
+   for j := range d.Points[i] {
+   xmm.Update(d.Points[i][j].x)
+   ymm.Update(d.Points[i][j].y)
+   }
+   }
+
+   options.HAxis.MaxValue = xmm.Max
+   options.VAxis.MaxValue = ymm.Max
+
+   err = options.OutputJavascript(w, run)
+   if err != nil {
+   return
+   }
+
+   fmt.Printf("var sp%ddata = new 
google.visualization.DataTable();\n", run)
+   fmt.Printf("sp%ddata.addColumn('number', 'Time');\n", run)
+   for i := range d.Points {
+   fmt.Printf("sp%ddata.addColumn('number', 'Worker 
%d');\n", run, i)
+   }
+   fmt.Printf("sp%ddata.addRows([\n", run)
+
+   // Can't use json here because we need to be able to use 'null' for 
non-existent values
+   for i := range d.Points {
+   for j := range d.Points[i] {
+   err = d.Points[i][j].OutputJson(w, i, len(d.Points))
+   if err != nil {
+   return
+   }
+   

[Xen-devel] [PATCH RFC 41/59] libxl.go: Link statically rather than dynamically

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Link statically rather than dynamically, because Go prefers that.

This also gets rid of the need for schedbench-report, so disable that
from the build (although keep the rule and the dummy file around just
in case.

Also update README.md.

Signed-off-by: George Dunlap 
---
 Makefile | 11 +++
 libxl.go | 10 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 0265dc8..699cc53 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-BIN = schedbench schedbench-report
+BIN = schedbench
 BINALL = $(BIN)
 
 .PHONY: all
@@ -10,12 +10,15 @@ CGO_CFLAGS = 
-I/build/hg/xen.git/dist/install/usr/local/include
 
 # FIXME
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
-CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH)
+CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) 
 
 schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
-   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
+   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build 
-ldflags '-linkmode external -extldflags "-static"' -o $@ $^
 
-# FIXME: Do with dlopen instead
+# If we use a statically linked binary we don't need this; the same
+# binary can be used on any system.  Keep this version (without any
+# run support) support) around for now in case we want to go back to
+# it.
 schedbench-report: main.go benchmark.go stubs.go htmlreport.go plan.go
go build -o $@ $^
 
diff --git a/libxl.go b/libxl.go
index 6621974..27e7766 100644
--- a/libxl.go
+++ b/libxl.go
@@ -19,12 +19,20 @@
 package main
 
 /*
-#cgo LDFLAGS: -lyajl -lxenlight
+#cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
 #include 
 #include 
 */
 import "C"
 
+/*
+ * Other flags that may be needed at some point: 
+ *  -lnl-route-3 -lnl-3
+ *
+ * To get back to simple dynamic linking:
+#cgo LDFLAGS: -lxenlight -lyajl
+*/
+
 import (
"unsafe"
"fmt"
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 34/59] controller: Make a useful config file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Allow a simple "skeleton" config file which can be adapted for the
particular use case.  Have 'plan' expand this with the real benchmark
plan.

Include "sample.bench" as a template to modify.  Also update the
README.md accordingly.

Signed-off-by: George Dunlap 
---
 Makefile |  4 +--
 benchmark.go |  9 ---
 main.go  | 48 ++--
 plan.go  | 79 
 4 files changed, 93 insertions(+), 47 deletions(-)
 create mode 100644 plan.go

diff --git a/Makefile b/Makefile
index 6dee499..af55e0a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,11 +13,11 @@ CGO_LIBS = -lyajl -lxenlight
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
 CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 # FIXME: Do with dlopen instead
-schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go
+schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go plan.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
index 8be00a0..31b3711 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -148,12 +148,13 @@ type BenchmarkRun struct {
 }
 
 type BenchmarkPlan struct {
-   filename string
-   WorkerType int
+   Input *PlanInput `json:",omitempty"`
+   filename string  `json:",omitempty"`
+   WorkerType int   `json:",omitempty"`
// Global options for workers that will be over-ridden by Run
// and WorkerSet config options
-   WorkerConfig
-   Runs []BenchmarkRun
+   WorkerConfig `json:",omitempty"`
+   Runs []BenchmarkRun  `json:",omitempty"`
 }
 
 func (run *BenchmarkRun) checkSummary() (done bool, err error) {
diff --git a/main.go b/main.go
index 2aa8bae..059a54a 100644
--- a/main.go
+++ b/main.go
@@ -49,49 +49,15 @@ func main() {
verbosity, _ = strconv.Atoi(Args[1])
Args = Args[2:]
case "plan":
-   workerA := []string{"burnwait", "70", "20"}
-   //workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "10", "30",
-   "burnwait", "20", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "30", "30",
-   }
-   
-   
-   plan :=  BenchmarkPlan{
-   WorkerType:WorkerXen,
-   WorkerConfig:WorkerConfig{Pool:"schedbench"},
-   filename:filename,
-   Runs:[]BenchmarkRun{
-   {Label:"baseline-a",
-   WorkerSets:[]WorkerSet{
-   
{Params:WorkerParams{workerA},
-   Count:1}},
-   RuntimeSeconds:10,},
-   {Label:"baseline-b",
-   WorkerSets:[]WorkerSet{
-   
{Params:WorkerParams{workerB},
-   Count:1}},
-   RuntimeSeconds:10,},
-   }}
-   
-   for i := 1; i <= 16 ; i *= 2 {
-   label := fmt.Sprintf("%da+%db", i, i)
-   run := BenchmarkRun{
-   Label:label,
-   WorkerSets:[]WorkerSet{
-   {Params:WorkerParams{workerA},
-   Count:i},
-   {Params:WorkerParams{workerB},
-   Count:i}},
-   RuntimeSeconds:10}
-   plan.Runs = append(plan.Runs, run)
+   plan, err := LoadBenchmark(filename)
+   if err != nil {
+   fmt.Println("Loading benchmark ", filename, " 
", err)

[Xen-devel] [PATCH RFC 42/59] plan: Allow "templating" from other runs

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Allow 'plan' to use an existing run as a "template": load the template,
discard the runs, and save the result in the new file.

Use like this:

./schedbench -t 18.bench -f 20.bench plan

This will make 20 with an empty plan identical to that in 18.

Signed-off-by: George Dunlap 
---
 main.go | 38 +-
 plan.go | 32 ++--
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/main.go b/main.go
index 8cbd708..ead6ab0 100644
--- a/main.go
+++ b/main.go
@@ -30,6 +30,7 @@ func main() {
 
Args = Args[1:]
filename := "test.bench"
+   template := ""
verbosity := 0
 
for len(Args) > 0 {
@@ -41,6 +42,13 @@ func main() {
}
filename = Args[1]
Args = Args[2:]
+   case "-t":
+   if len(Args) < 2 {
+   fmt.Println("Need arg for -t")
+   os.Exit(1)
+   }
+   template = Args[1]
+   Args = Args[2:]
case "-v":
if len(Args) < 2 {
fmt.Println("Need arg for -v")
@@ -49,20 +57,40 @@ func main() {
verbosity, _ = strconv.Atoi(Args[1])
Args = Args[2:]
case "plan":
-   plan, err := LoadBenchmark(filename)
+   // Load either the template benchmark or the filename
+   loadfile := filename
+   if template != "" {
+   loadfile = template
+   }
+   plan, err := LoadBenchmark(loadfile)
if err != nil {
-   fmt.Println("Loading benchmark ", filename, " 
", err)
+   fmt.Printf("Loading benchmark %s: %v\n",
+   loadfile, err)
os.Exit(1)
}
+
+   if template != "" {
+   plan.filename = filename
+   err = plan.ClearRuns()
+   if err != nil {
+   fmt.Printf("Clearing runs: %v\n",
+   err)
+   os.Exit(1)
+   }
+   }

-   plan.ExpandInput()
+   err = plan.ExpandInput()
+   if err != nil {
+   fmt.Printf("Expanding plan: %v\n", err)
+   os.Exit(1)
+   }
 
err = plan.Save()
if err != nil {
-   fmt.Println("Saving plan ", filename, " ", err)
+   fmt.Printf("Saving plan %s: %v\n", filename, 
err)
os.Exit(1)
}
-   fmt.Println("Created plan in ", filename)
+   fmt.Printf("Created plan in %s\n", filename)
Args = Args[1:]
case "run":
plan, err := LoadBenchmark(filename)
diff --git a/plan.go b/plan.go
index 24c6bd4..e535603 100644
--- a/plan.go
+++ b/plan.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
@@ -19,15 +37,25 @@ var WorkerPresets = map[string]WorkerParams{
"P001":WorkerParams{[]string{"burnwait", "70", "20"}},
 }
 
+func (plan *BenchmarkPlan) ClearRuns() (err error) {
+   plan.Runs = nil
+
+   return
+}
 
 func (plan *BenchmarkPlan) ExpandInput() (err error) {
if plan.Runs != nil {
-   fmt.Printf("plan.Expand: Runs non-empty, not doing anything\n");
+   err = fmt.Errorf("Runs non-empty, not doing anything\n");
+   return
+   }
+
+   if plan.Input == nil {
+   err = fmt.Errorf("Input nil, nothing to do")
return
}
   

[Xen-devel] [PATCH RFC 46/59] libxl: Reorganize bitmapGotoC

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

No need to "allocate" the structure elsewhere; passing as a return
value makes usage a lot cleaner.

Signed-off-by: George Dunlap 
---
 libxl.go | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/libxl.go b/libxl.go
index 92064ca..16f4645 100644
--- a/libxl.go
+++ b/libxl.go
@@ -191,8 +191,8 @@ func bitmapCToGo(cbm *C.libxl_bitmap) (gbm Bitmap) {
 }
 
 // Must be C.libxl_bitmap_dispose'd of afterwards
-func bitmapGotoC(gbm Bitmap, cbm *C.libxl_bitmap) {
-   C.libxl_bitmap_init(cbm)
+func bitmapGotoC(gbm Bitmap) (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init(&cbm)
 
size := len(gbm.bitmap)
cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
@@ -206,6 +206,8 @@ func bitmapGotoC(gbm Bitmap, cbm *C.libxl_bitmap) {
 
// And copy the Go array into the C array
copy(mapslice, gbm.bitmap)
+
+   return
 }
 
 func (bm *Bitmap) Test(bit int) (bool) {
@@ -385,8 +387,7 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler 
Scheduler, Cpumap Bitma
var uuid C.libxl_uuid
C.libxl_uuid_generate(&uuid)
 
-   var cbm C.libxl_bitmap
-   bitmapGotoC(Cpumap, &cbm)
+   cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose(&cbm)

ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
@@ -429,8 +430,7 @@ func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) 
(err error) {
 // int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
 // const libxl_bitmap *cpumap);
 func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
-   var cbm C.libxl_bitmap
-   bitmapGotoC(Cpumap, &cbm)
+   cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose(&cbm)

ret := C.libxl_cpupool_cpuadd_cpumap(Ctx.ctx, C.uint32_t(Poolid), &cbm)
@@ -458,8 +458,7 @@ func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu 
int) (err error) {
 // int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
 //const libxl_bitmap *cpumap);
 func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
-   var cbm C.libxl_bitmap
-   bitmapGotoC(Cpumap, &cbm)
+   cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose(&cbm)

ret := C.libxl_cpupool_cpuremove_cpumap(Ctx.ctx, C.uint32_t(Poolid), 
&cbm)
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 48/59] libxl: Add Ctx.CheckOpen

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

To standardize the error in the case that Ctx isn't open.  Add checks to all 
functions
which call libxl functions directly.

Signed-off-by: George Dunlap 
---
 libxl.go | 48 +---
 1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/libxl.go b/libxl.go
index e73c06b..8f16b1d 100644
--- a/libxl.go
+++ b/libxl.go
@@ -164,9 +164,16 @@ func (Ctx *Context) Close() (err error) {
return
 }
 
-func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+func (Ctx *Context) CheckOpen() (err error) {
if Ctx.ctx == nil {
err = fmt.Errorf("Context not opened")
+   }
+   return
+}
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
return
}
 
@@ -209,8 +216,8 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err 
error) {
 }
 
 func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
-   if Ctx.ctx == nil {
-   err = fmt.Errorf("Context not opened")
+   err = Ctx.CheckOpen()
+   if err != nil {
return
}
 
@@ -359,6 +366,11 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
 // void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
 func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
+   err := Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
var nbPool C.int
 
c_cpupool_list := C.libxl_list_cpupool(Ctx.ctx, &nbPool)
@@ -394,6 +406,11 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
 // FIXME: uuid
 // FIXME: Setting poolid
 func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap 
Bitmap) (err error, Poolid uint32) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
poolid := C.uint32_t(0)
name := C.CString(Name)
defer C.free(unsafe.Pointer(name))
@@ -420,6 +437,11 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler 
Scheduler, Cpumap Bitma
 
 // int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
 func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
ret := C.libxl_cpupool_destroy(Ctx.ctx, C.uint32_t(Poolid))
// FIXME: Proper error
if ret != 0 {
@@ -432,6 +454,11 @@ func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err 
error) {
 
 // int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
 func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
ret := C.libxl_cpupool_cpuadd(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
// FIXME: Proper error
if ret != 0 {
@@ -445,6 +472,11 @@ func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) 
(err error) {
 // int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
 // const libxl_bitmap *cpumap);
 func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose(&cbm)

@@ -460,6 +492,11 @@ func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, 
Cpumap Bitmap) (err error
 
 // int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
 func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
ret := C.libxl_cpupool_cpuremove(Ctx.ctx, C.uint32_t(Poolid), 
C.int(Cpu))
// FIXME: Proper error
if ret != 0 {
@@ -473,6 +510,11 @@ func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu 
int) (err error) {
 // int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
 //const libxl_bitmap *cpumap);
 func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose(&cbm)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 39/59] libxl.go: Put common link flags in libxl.go

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

...so that the only things added in the makefile are extra flags
required when linking against non-installed builds.

Add in the text of the GPL while we're at it.

Signed-off-by: George Dunlap 
---
 Makefile |  3 +--
 libxl.go | 19 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 0e0b231..0265dc8 100644
--- a/Makefile
+++ b/Makefile
@@ -7,11 +7,10 @@ all: $(BIN)
 
 
 CGO_CFLAGS = -I/build/hg/xen.git/dist/install/usr/local/include
-CGO_LIBS = -lyajl -lxenlight
 
 # FIXME
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
-CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
+CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH)
 
 schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
diff --git a/libxl.go b/libxl.go
index 9477bca..6621974 100644
--- a/libxl.go
+++ b/libxl.go
@@ -1,6 +1,25 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 /*
+#cgo LDFLAGS: -lyajl -lxenlight
 #include 
 #include 
 */
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 49/59] libxl: Implement libxl_cpupool_info and Scheduler.FromString()

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Unify the libxl_cpupoolinfo -> CpupoolInfo translation in a function.

Also make bitmapCToGo pass-by-value rather than pass-by-reference,
since it only has two elements and doesn't need to be modified.

Signed-off-by: George Dunlap 
---
 libxl.go | 64 ++--
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/libxl.go b/libxl.go
index 8f16b1d..dfe4f40 100644
--- a/libxl.go
+++ b/libxl.go
@@ -234,7 +234,7 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
  */
 
 // Return a Go bitmap which is a copy of the referred C bitmap.
-func bitmapCToGo(cbm *C.libxl_bitmap) (gbm Bitmap) {
+func bitmapCToGo(cbm C.libxl_bitmap) (gbm Bitmap) {
// Alloc a Go slice for the bytes
size := int(cbm.size)
gbm.bitmap = make([]C.uint8_t, size)
@@ -338,7 +338,6 @@ func (a Bitmap) And(b Bitmap) (c Bitmap) {
 }
 
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
-// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
 func (s Scheduler) String() (string) {
cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
// No need to free const return value
@@ -346,6 +345,32 @@ func (s Scheduler) String() (string) {
return C.GoString(cs)
 }
 
+// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
+func (s *Scheduler) FromString(gstr string) (err error) {
+   cstr := C.CString(gstr)
+   defer C.free(unsafe.Pointer(cstr))
+
+   var cs C.libxl_scheduler
+   ret := C.libxl_scheduler_from_string(cstr, &cs)
+   if ret != 0 {
+   err = fmt.Errorf("libxl_scheduler_from_string: %d\n", ret)
+   return
+   }
+
+   *s = Scheduler(cs)
+   return
+}
+
+func translateCpupoolInfoCToGo(cci C.libxl_cpupoolinfo) (gci CpupoolInfo) {
+   gci.Poolid = uint32(cci.poolid)
+   gci.PoolName = C.GoString(cci.pool_name)
+   gci.Scheduler = Scheduler(cci.sched)
+   gci.DomainCount = int(cci.n_dom)
+   gci.Cpumap = bitmapCToGo(cci.cpumap)
+
+   return
+}
+
 func SchedulerFromString(name string) (s Scheduler, err error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
@@ -385,20 +410,37 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
cpupoolListSlice := (*[1 << 
30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
 
for i := range cpupoolListSlice {
-   var info CpupoolInfo
+   info := translateCpupoolInfoCToGo(cpupoolListSlice[i])

-   info.Poolid = uint32(cpupoolListSlice[i].poolid)
-   info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
-   info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
-   info.DomainCount = int(cpupoolListSlice[i].n_dom)
-   info.Cpumap = bitmapCToGo(&cpupoolListSlice[i].cpumap)
-
list = append(list, info)
}
 
return
 }
 
+// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
+func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool CpupoolInfo) {
+   err := Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var c_cpupool C.libxl_cpupoolinfo
+   
+   ret := C.libxl_cpupool_info(Ctx.ctx, &c_cpupool, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_info failed: %d", ret)
+   return
+   }
+   defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
+
+   pool = translateCpupoolInfoCToGo(c_cpupool)
+
+   return
+}
+
+
+
 // int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
 //  libxl_scheduler sched,
 //  libxl_bitmap cpumap, libxl_uuid *uuid,
@@ -532,7 +574,6 @@ func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, 
Cpumap Bitmap) (err er
 // int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
 // int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
 // int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t 
domid);
-// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
 
 //
 // Utility functions
@@ -615,5 +656,8 @@ func XlTest(Args []string) {
fmt.Printf("Pool id: %d\n", Poolid)
}
 
+   pool = Ctx.CpupoolInfo(0)
+   fmt.Printf("Cpupool 0 info: %v\n", pool)
+   
Ctx.Close()
 }
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 54/59] controller/run: Add RunConfig.NumaDisable

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

If RunConfig.NumaDisable is set, get each worker's
WorkerConfig.SoftAffinity to the cpumap of the cpupool the VM is going
to be running in.

Signed-off-by: George Dunlap 
---
 benchmark.go |  4 
 run.go   | 35 ---
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index d5a0ac8..abe2dfb 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -142,6 +142,7 @@ type RunConfig struct {
Scheduler string
Pool string
Cpus []int
+   NumaDisable *bool `json:",omitempty"`
 }
 
 // Propagate unset values from a higher level
@@ -155,6 +156,9 @@ func (l *RunConfig) PropagateFrom(g RunConfig) {
if l.Cpus == nil {
l.Cpus = g.Cpus
}
+   if l.NumaDisable == nil {
+   l.NumaDisable = g.NumaDisable
+   }
 }
 
 type BenchmarkRun struct {
diff --git a/run.go b/run.go
index 2d0db01..d1c5d95 100644
--- a/run.go
+++ b/run.go
@@ -312,14 +312,43 @@ func (run *BenchmarkRun) Prep() (ready bool, why string) {
return 
 }
 
+func (run *BenchmarkRun) GetCpumap() (Cpumap Bitmap) {
+   if run.RunConfig.Pool == "" {
+   fmt.Printf("Run.Prep: No pool set, using 0\n")
+   pool := Ctx.CpupoolInfo(0)
+   Cpumap = pool.Cpumap
+   } else {
+   pool, poolPresent := Ctx.CpupoolFindByName(run.RunConfig.Pool)
+   if poolPresent {
+   Cpumap = pool.Cpumap
+   } else {
+   panic("run.GetCpumap(): Pool "+run.RunConfig.Pool+" not 
found!")
+   }
+   }
+   return
+}
+
 func (run *BenchmarkRun) Run() (err error) {
for wsi := range run.WorkerSets {
-   run.WorkerSets[wsi].Config.PropagateFrom(run.WorkerConfig)
-   if run.WorkerSets[wsi].Config.Pool == "" {
-   run.WorkerSets[wsi].Config.Pool = run.RunConfig.Pool
+   conf := &run.WorkerSets[wsi].Config
+   
+   conf.PropagateFrom(run.WorkerConfig)
+   if conf.Pool == "" {
+   conf.Pool = run.RunConfig.Pool
}
run.WorkerSets[wsi].Params.SetkHZ(CpukHZ)

+   if *run.RunConfig.NumaDisable {
+   if conf.SoftAffinity != "" {
+   err = fmt.Errorf("Cannot disable Numa if 
SoftAffinity is set!")
+   return
+   }
+   // Disable libxl NUMA by setting the soft
+   // affinity to the set of cpus in the cpupool
+   conf.SoftAffinity = run.GetCpumap().String()
+   fmt.Printf("Setting SoftAffinity to %s to disable NUMA 
placement\n",
+   conf.SoftAffinity)
+   }
}

Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RFC 59/59] tools/xenlight: Create interface for xenlight info

2016-12-28 Thread Ronald Rojas
Create interface to interact with libxl_verions_info
and libxl_physinfo. Also introduce proper error
handling.

Signed-off-by: Ronald Rojas 
---
 tools/golang/xenlight/libxl.go|  720 --
 tools/golang/xenlight/xenlight.go | 1000 +
 2 files changed, 1000 insertions(+), 720 deletions(-)
 delete mode 100644 tools/golang/xenlight/libxl.go
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/golang/xenlight/libxl.go b/tools/golang/xenlight/libxl.go
deleted file mode 100644
index aa5c01c..000
--- a/tools/golang/xenlight/libxl.go
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of the
- * License only.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-package main
-
-/*
-#cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
-#include 
-#include 
-*/
-import "C"
-
-/*
- * Other flags that may be needed at some point: 
- *  -lnl-route-3 -lnl-3
- *
- * To get back to simple dynamic linking:
-#cgo LDFLAGS: -lxenlight -lyajl
-*/
-
-import (
-   "unsafe"
-   "fmt"
-   "time"
-)
-
-/*
- * Types: Builtins
- */
-
-type Domid uint32
-
-type MemKB uint64
-
-// typedef struct {
-// uint32_t size;  /* number of bytes in map */
-// uint8_t *map;
-// } libxl_bitmap;
-
-// Implement the Go bitmap type such that the underlying data can
-// easily be copied in and out.  NB that we still have to do copies
-// both directions, because cgo runtime restrictions forbid passing to
-// a C function a pointer to a Go-allocated structure which contains a
-// pointer.
-type Bitmap struct {
-   bitmap []C.uint8_t
-}
-
-type Context struct {
-   ctx *C.libxl_ctx
-}
-
-type Uuid C.libxl_uuid
-
-/*
- * Types: IDL
- * 
- * FIXME: Generate these automatically from the IDL
- */
-type Dominfo struct {
-   Uuid  Uuid
-   Domid Domid
-   Running   bool
-   Blocked   bool
-   Pausedbool
-   Shutdown  bool
-   Dying bool
-   Never_stopbool
-   
-   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
-   Outstanding_memkb MemKB
-   Current_memkb MemKB
-   Shared_memkb  MemKB
-   Paged_memkb   MemKB
-   Max_memkb MemKB
-   Cpu_time  time.Duration
-   Vcpu_max_id   uint32
-   Vcpu_online   uint32
-   Cpupool   uint32
-   Domain_type   int32 //FIXME libxl_domain_type enumeration
-
-}
-
-// # Consistent with values defined in domctl.h
-// # Except unknown which we have made up
-// libxl_scheduler = Enumeration("scheduler", [
-// (0, "unknown"),
-// (4, "sedf"),
-// (5, "credit"),
-// (6, "credit2"),
-// (7, "arinc653"),
-// (8, "rtds"),
-// ])
-type Scheduler int
-var (
-   SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
-   SchedulerSedf Scheduler = C.LIBXL_SCHEDULER_SEDF
-   SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
-   SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
-   SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
-   SchedulerRTDS Scheduler = C.LIBXL_SCHEDULER_RTDS
-)
-
-// libxl_cpupoolinfo = Struct("cpupoolinfo", [
-// ("poolid",  uint32),
-// ("pool_name",   string),
-// ("sched",   libxl_scheduler),
-// ("n_dom",   uint32),
-// ("cpumap",  libxl_bitmap)
-// ], dir=DIR_OUT)
-
-type CpupoolInfo struct {
-   Poolid uint32
-   PoolName string
-   Scheduler Scheduler
-   DomainCount int
-   Cpumap Bitmap
-}
-
-/*
- * Context
- */
-var Ctx Context
-
-func (Ctx *Context) IsOpen() bool {
-   return Ctx.ctx != nil
-}
-
-func (Ctx *Context) Open() (err error) {
-   if Ctx.ctx != nil {
-   return
-   }
-   
-   ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
-
-   if ret != 0 {
-   err = fmt.Errorf("Allocating libxl context: %d&q

[Xen-devel] [PATCH RFC 56/59] controller/plan: Add NumaDisable to SimpleMatrix

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 plan.go | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/plan.go b/plan.go
index 736d9f3..b8e0c6b 100644
--- a/plan.go
+++ b/plan.go
@@ -26,6 +26,7 @@ type PlanSimpleMatrix struct {
Schedulers []string
Workers []string
Count []int
+   NumaDisable []bool
 }
 
 type PlanInput struct {
@@ -127,6 +128,27 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
b = nil
}
 
+   // ...and NumaDisable
+   if len(plan.Input.SimpleMatrix.NumaDisable) > 0 {
+   for _, base := range a {
+   for _, d := range plan.Input.SimpleMatrix.NumaDisable {
+   run := base
+   // Need to make a copy of this so that
+   // we have a pointer to use as a tristate
+   run.RunConfig.NumaDisable = new(bool)
+   *run.RunConfig.NumaDisable = d
+   if d {
+   run.Label = run.Label+" NumaOff"
+   } else {
+   run.Label = run.Label+" NumaOn "
+   }
+   b = append(b, run)
+   }
+   }
+   a = b
+   b = nil
+   }
+
for i := range a {
fmt.Printf("%s\n", a[i].Label)
}
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC 59/59] tools/xenlight: Create interface for xenlight info

2016-12-29 Thread Ronald Rojas
On Thu, Dec 29, 2016 at 10:52:42AM +, Wei Liu wrote:
> On Thu, Dec 29, 2016 at 10:34:34AM +, George Dunlap wrote:
> > On 29/12/16 01:14, Ronald Rojas wrote:
> > > Create interface to interact with libxl_verions_info
> > > and libxl_physinfo. Also introduce proper error
> > > handling.
> > > 
> > > Signed-off-by: Ronald Rojas 
> > 
> > Hey Ronald,
> > 
> > When you send a series to a public open-source project, you want it to
> > be a sort of idealized set of changes that make it easy to "see the
> > forest for the trees", as it were, not the actual local development
> > path.  We don't need the full development history of libxl.go -- a
> > simple dump will be fine; and we definitely don't need all the other
> > stuff from schedbench in the xen.git history. :-)
> > 
> > All you needed to do to "import" my existing libxl code from schedbench was:
> > 
> > $ cd xen.git
> > $ cp ../schedbench.git/controller/libxl.go tools/golang/xenlight/xenlight.go
> > $ git add tools/golang/xenlight/xenlight.go

This is much easier then what I was doing. I did it another way 
because I thought you would have wanted to keep the git commit 
history. I can resubmit the patch into 2 commits so it'll be 
easier to read. 1 for importing the code from schedbench and 
then the changes that I made afterward. How does that sound?
> > 
> 
> +1 for this.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v4 01/14] golang/xenlight: Create stub package

2017-03-23 Thread Ronald Rojas
On Mon, Mar 20, 2017 at 02:45:30PM +, George Dunlap wrote:
> On Thu, Mar 16, 2017 at 7:08 PM, Ronald Rojas  wrote:
> > Create a basic Makefile to build and install libxenlight Golang
> > bindings. Also add a stub package which only opens libxl context.
> >
> > Include a global xenlight.Ctx variable which can be used as the
> > default context by the entire program if desired.
> >
> > For now, return simple errors. Proper error handling will be
> > added in next patch.
> >
> > Signed-off-by: Ronald Rojas 
> > Signed-off-by: George Dunlap 
> 
> Almost there.  One comment on one of the last changes...
> 
 
 [snip]

> I think we want xenlight.Ctx to contain all the information needed to
> open and close it; as long as we're creating a logger automatically,
> we should store the pointer to the logger in the Ctx struct.
> 
> We should also set the pointer to nil after calling
> xtl_logger_destroy() to prevent use-after-free bugs.
> 
> (Yay lack of garbage collection again.)

Makes sense. I'll put the logger inside the Ctx struct.

Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v4 01/14] golang/xenlight: Create stub package

2017-03-23 Thread Ronald Rojas
On Mon, Mar 20, 2017 at 05:51:03PM +, George Dunlap wrote:
> On Thu, Mar 16, 2017 at 7:08 PM, Ronald Rojas  wrote:
> > Create a basic Makefile to build and install libxenlight Golang
> > bindings. Also add a stub package which only opens libxl context.
> >
> > Include a global xenlight.Ctx variable which can be used as the
> > default context by the entire program if desired.
> >
> > For now, return simple errors. Proper error handling will be
> > added in next patch.
> >
> > Signed-off-by: Ronald Rojas 
> > Signed-off-by: George Dunlap 
> > ---
> >
> > Changes:
> >
> > - Added global logger variable and destroyed the logger instance
> > when closing the context.
> >
> > - Whitespace fixes
> >
> > - Commented out CONFIG_GOLANG
> 
> > +# Go will do its own dependency checking, and not actuall go through
> > +# with the build if none of the input files have changed.
> > +#
> > +# NB that because the users of this library need to be able to
> > +# recompile the library from source, it needs to include '-lxenlight'
> > +# in the LDFLAGS; and thus we need to add -L$(XEN_XENLIGHT) here
> > +# so that it can find the actual library.
> > +.PHONY: build
> > +build: package
> > +   CGO_CFLAGS="$(CFLAGS_libxenlight) $(CFLAGS_libxentoollog)" 
> > CGO_LDFLAGS="$(LDLIBS_libxenlight) $(LDLIBS_libxentoollog)-L$(XEN_XENLIGHT) 
> > -L$(XEN_LIBXENTOOLLOG)" GOPATH=$(XEN_GOPATH) $(GO) install -x 
> > $(XEN_GOCODE_URL)/xenlight
> 
> Also, you're missing a space between `$(LDLIBS_libxentoollog)` and
> `-L$(XEN_XENLIGHT)`.  In the future please at least compile-test your
> code.
> 

Sorry! I rushed this patch, I'll fix this in the next iteration.

Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2 2/5] golang/xenlight: Add error constants and standard handling

2017-03-02 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas 
---
Changes since last patch:

- Whitespace fixes

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 81 +--
 1 file changed, 77 insertions(+), 4 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 0a0cea2..cbd3527 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -29,17 +29,79 @@ import "C"
  *
  * To get back to static linking:
  * #cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
-*/
+ */
 
 import (
"fmt"
"unsafe"
 )
 
+/*
+ * Errors
+ */
+
+type Error int
+
+const (
+   ErrorNonspecific  = Error(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Error(-C.ERROR_VERSION)
+   ErrorFail = Error(-C.ERROR_FAIL)
+   ErrorNi   = Error(-C.ERROR_NI)
+   ErrorNomem= Error(-C.ERROR_NOMEM)
+   ErrorInval= Error(-C.ERROR_INVAL)
+   ErrorBadfail  = Error(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Error(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Error(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Error(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Error(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Error(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Error(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Error(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Error(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Error(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Error(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Error(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Error(-C.ERROR_ABORTED)
+   ErrorNotfound = Error(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Error(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Error(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific:  "Non-specific error",
+   ErrorVersion:  "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi:   "Not Implemented",
+   ErrorNomem:"No memory",
+   ErrorInval:"Invalid argument",
+   ErrorBadfail:  "Bad Fail",
+   ErrorGuestTimedout:"Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt:   "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail:   "OS event registration failed",
+   ErrorBufferfull:   "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty:  "JSON config empty",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
+   ErrorDomainNotfound:   "Domain not found",
+   ErrorAborted:  "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed:  "Domain destroyed",
+   ErrorFeatureRemoved:   "Feature removed",
+}
 
 /*
  * Types: Builtins
  */
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -49,6 +111,17 @@ type Context struct {
  */
 var Ctx Context
 
+func (e Error) Error() string {
+   if 0 < int(e) && int(e) < len(errors) {
+   s := errors[e]
+   if s != "&quo

[Xen-devel] [PATCH v2 1/5] golang/xenlight: Create stub package

2017-03-02 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas 
Signed-off-by: George Dunlap 
---

Changes:
- Changed GPL Lisense to LGPL Lisense

- Initialized xentoollog_logger for storing error messages

- Moved manual-enable config option to tools/Rules.mk, use
  CONFIG_GOLANG in tools/Makefile

- Added XEN_GOPATH, pointing to tools/golang

- Modified tools/golang/xenlight makefile to construct necessary $GOPATH

- Added tools/golang/Makefile, so we don't need special rules in tools
  to make tools/golang/xenlight; and so we have a single place to remove the
  $GOPATH build side-effects ($GOPATH/src and $GOPATH/pkg)

- Build of tools/golang/xenlight sets $GOPATH and does a 'go install'

- Use tree-provided CFLAGS_libxenlight and LDLIBS_libxenlight, rather
  than hard-coding our own

- Made a PKGSOURCES variable to track dependencies of all target files
  which need to be part of the output package (i.e., what's put in
  $GOPATH/src).  At the moment this is one file, but it will probably
  be more once we start using the IDL.

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/Makefile|  1 +
 tools/Rules.mk|  6 +++
 tools/golang/Makefile | 27 +
 tools/golang/xenlight/Makefile| 49 ++
 tools/golang/xenlight/xenlight.go | 85 +++
 5 files changed, 168 insertions(+)
 create mode 100644 tools/golang/Makefile
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..df1fda1 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,6 +31,7 @@ endif
 
 SUBDIRS-y += xenpmd
 SUBDIRS-y += libxl
+SUBDIRS-$(CONFIG_GOLANG) += golang
 SUBDIRS-y += helpers
 SUBDIRS-$(CONFIG_X86) += xenpaging
 SUBDIRS-$(CONFIG_X86) += debugger/gdbsx
diff --git a/tools/Rules.mk b/tools/Rules.mk
index b35999b..24e5220 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -30,6 +30,12 @@ XENSTORE_XENSTORED ?= y
 debug ?= y
 debug_symbols ?= $(debug)
 
+# Uncomment to compile with Go
+CONFIG_GOLANG ?= y
+ifeq ($(CONFIG_GOLANG),y)
+XEN_GOPATH= $(XEN_ROOT)/tools/golang
+endif
+
 ifeq ($(debug_symbols),y)
 CFLAGS += -g3
 endif
diff --git a/tools/golang/Makefile b/tools/golang/Makefile
new file mode 100644
index 000..47a9235
--- /dev/null
+++ b/tools/golang/Makefile
@@ -0,0 +1,27 @@
+XEN_ROOT=$(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# In order to link against a package in Go, the package must live in a
+# directory tree in the way that Go expects.  To make this possible,
+# there must be a directory such that we can set GOPATH=${dir}, and
+# the package will be under $GOPATH/src/${full-package-path}.
+
+# So we set XEN_GOPATH to $XEN_ROOT/tools/golang.  The xenlight
+# "package build" directory ($PWD/xenlight) will create the "package
+# source" directory in the proper place.  Go programs can use this
+# package by setting GOPATH=$(XEN_GOPATH).
+
+SUBDIRS-y = xenlight
+
+.PHONY: build all
+all build: subdirs-all
+
+.PHONY: install
+install: subdirs-install
+
+.PHONY: clean
+clean: subdirs-clean
+   $(RM) -r src pkg
+
+.PHONY: distclean
+distclean: clean
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..5d578f3
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,49 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# Standing boldly against convention, we insist on installing the
+# package source under $(prefix)/share/gocode
+GOCODE_DIR ?= $(prefix)/share/gocode/
+GOXL_PKG_DIR = /src/xenproject.org/xenlight/
+GOXL_INSTALL_DIR = $(GOCODE_DIR)$(GOXL_PKG_DIR)
+
+# PKGSOURCES: Files which comprise the distributed source package
+PKGSOURCES = xenlight.go
+
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: package
+package: $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES)
+
+$(XEN_GOPATH)/src/xenproject.org/xenlight/$(PKGSOURCES): $(PKGSOURCES)
+   $(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+   $(INSTALL_DATA) $(PKGSOURCES) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+
+# Go will do its own dependency checking, and not actuall go through
+# with the build if none of the input files have changed.
+#
+# NB that because the users of this library need to be able to
+# recompile the library from source, it needs to include '-lxenlight'
+# in the LDFLAGS; and thus we need to add -L$(XEN_XENLIGHT) here
+# so that it can find the actual library.
+.PHONY: build
+build: package
+   CGO_CFLAGS="$(CFLA

[Xen-devel] [PATCH v2 4/5] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-03-02 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap 
Signed-off-by: Ronald Rojas 
---
Changes since last version
- Created type and enumeration of DomainType and ShutdownReason

- Created String() method for DomainType and ShutdownReason

- Refactored creating DomainInfo from c type into seperate
toGo() function

- Applied libxl_domain_info_init/dispose()

- whitespace fixes

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com

---
---
 tools/golang/xenlight/xenlight.go | 132 ++
 1 file changed, 132 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 63cc805..18dedcb 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -34,6 +34,7 @@ import "C"
 import (
"fmt"
"unsafe"
+   "time"
 )
 
 /*
@@ -102,6 +103,12 @@ var errors = [...]string{
  * Types: Builtins
  */
 
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -203,6 +210,95 @@ func (cinfo *C.libxl_version_info) toGo() (info 
*VersionInfo) {
return
 }
 
+type ShutdownReason int32
+
+const(
+   ShutdownReasonUnknown = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_UNKNOWN)
+   ShutdownReasonPoweroff = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_POWEROFF)
+   ShutdownReasonReboot = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_REBOOT)
+   ShutdownReasonSuspend = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SUSPEND)
+   ShutdownReasonCrash = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_CRASH)
+   ShutdownReasonWatchdog = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_WATCHDOG)
+   ShutdownReasonSoftReset = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SOFT_RESET)
+
+)
+
+func (sr ShutdownReason) String()(str string){
+   cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type DomainType int32
+
+const(
+   DomainTypeInvalid = DomainType(C.LIBXL_DOMAIN_TYPE_INVALID)
+   DomainTypeHvm = DomainType(C.LIBXL_DOMAIN_TYPE_HVM)
+   DomainTypePv = DomainType(C.LIBXL_DOMAIN_TYPE_PV)
+)
+
+func (dt DomainType) String()(str string){
+   cstr := C.libxl_domain_type_to_string(C.libxl_domain_type(dt))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type Dominfo struct {
+   Uuid   Uuid
+   Domid  Domid
+   Ssidref uint32
+   SsidLabel string
+   Runningbool
+   Blockedbool
+   Paused bool
+   Shutdown   bool
+   Dying  bool
+   NeverStop bool
+
+   ShutdownReason   int32
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxId   uint32
+   VcpuOnline   uint32
+   Cpupool   uint32
+   DomainType   int32
+
+}
+
+func (cdi *C.libxl_dominfo) toGo()(di *Dominfo){
+
+   di = &Dominfo{}
+   di.Uuid = Uuid(cdi.uuid)
+   di.Domid = Domid(cdi.domid)
+   di.Ssidref = uint32(cdi.ssidref)
+   di.SsidLabel = C.GoString(cdi.ssid_label)
+   di.Running = bool(cdi.running)
+   di.Blocked = bool(cdi.blocked)
+   di.Paused = bool(cdi.paused)
+   di.Shutdown = bool(cdi.shutdown)
+   di.Dying = bool(cdi.dying)
+   di.NeverStop= bool(cdi.never_stop)
+   di.ShutdownReason= int32(cdi.shutdown_reason)
+   di.OutstandingMemkb= MemKB(cdi.outstanding_memkb)
+   di.CurrentMemkb = MemKB(cdi.current_memkb)
+   di.SharedMemkb = MemKB(cdi.shared_memkb)
+   di.PagedMemkb = MemKB(cdi.paged_memkb)
+   di.MaxMemkb= MemKB(cdi.max_memkb)
+   di.CpuTime= time.Duration(cdi.cpu_time)
+   di.VcpuMaxId = uint32(cdi.vcpu_max_id)
+   di.VcpuOnline = uint32(cdi.vcpu_online)
+   di.Cpupool = uint32(cdi.cpupool)
+   di.DomainType = int32(cdi.domain_type)
+
+   return
+}
+
 /*
  * Context
  */
@@ -356,3 +452,39 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, 
err error) {
 
return
 }
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var cdi C.libxl_dominfo
+   C.libxl_dominfo_init(&cdi)
+
+   ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(&cdi), 
C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   di = cdi.toGo()
+   C.libxl_dominfo_dispose(&cdi)
+
+   return
+}
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+

Re: [Xen-devel] [PATCH v2 5/5] golang/xenlight: Add tests host related functionality functions

2017-03-02 Thread Ronald Rojas
On Thu, Mar 02, 2017 at 05:53:00PM +, George Dunlap wrote:
> On 02/03/17 17:36, Ian Jackson wrote:
> > Ronald Rojas writes ("[PATCH v2 5/5] golang/xenlight: Add tests host 
> > related functionality functions"):
> >> Create tests for the following functions:
> >> - GetVersionInfo
> >> - GetPhysinfo
> >> - GetDominfo
> >> - GetMaxCpus
> >> - GetOnlineCpus
> >> - GetMaxNodes
> >> - GetFreeMemory
> > 
> > I assume this whole series is RFC still ?
> 
> I think the earlier patches looked pretty close to being checked in.  I
> think having a basic chunk of functionality checked in will make it
> easier to actually collaborate on improving things.
> 
> > I don't feel competent to review the golang code.  But I did spot some
> > C to review :-)
> > 
> >> diff --git a/tools/golang/xenlight/test/xeninfo/freememory.c 
> >> b/tools/golang/xenlight/test/xeninfo/freememory.c
> >> new file mode 100644
> >> index 000..04ee90d
> >> --- /dev/null
> >> +++ b/tools/golang/xenlight/test/xeninfo/freememory.c
> >> @@ -0,0 +1,24 @@
> >> +#include 
> >> +#include 
> >> +#include 
> >> +#include "print.h"
> >> +
> >> +int main(){
> > 
> > This is an unusual definition of main.  (I think it's still legal, but
> > probably not what you meant.)
> > 

I did this because I'm not expecting any arguments  to be passed into
main. I can change it to the standard definition instead.

> >> +libxl_ctx *context;
> >> +libxl_ctx_alloc(&context,LIBXL_VERSION, 0, NULL);
> >> +
> >> +uint64_t free_memory;
> >> +int err = libxl_get_free_memory(context, &free_memory);
> >> +if (err < 0)
> >> +{
> >> +printf("%d\n", err);
> >> +}
> >> +else
> >> +{
> >> +printf("%lu\n", free_memory);
> >> +}
> > 
> > This output is ambiguous.
> > 
> >> +libxl_ctx_free(context);
> >> +
> >> +}
> > 
> > Returns from main without returning a value.  Error code is lost.
> 
> He's not testing whether the call succeeds; he's testing if the call has
> the same result as the golang function.
> 
> But this won't quite work anymore, because as of v2 the golang return
> values are positive constants (to make it easy to use them for indexes).
>  So if there were an identical error, the output would be different even
> if the error number were identical.

You are right. I need to negate the value that I print in the go file.

> 
> That needs to be fixed; but I also agree it would probably be better to
> print something that distinguishes between success and failure.

I think it's always clear whether the function failed or succeeded. The
error code will always be a negative number while free_memory can only
be non-negative because it is an unsigned long. There is no overlap
between those two values.


Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2 3/5] golang/xenlight: Add host-related functionality

2017-03-03 Thread Ronald Rojas
On Fri, Mar 03, 2017 at 02:54:56PM +, George Dunlap wrote:
> On 02/03/17 16:07, Ronald Rojas wrote:
> > Add calls for the following host-related functionality:
> > - libxl_get_max_cpus
> > - libxl_get_online_cpus
> > - libxl_get_max_nodes
> > - libxl_get_free_memory
> > - libxl_get_physinfo
> > - libxl_get_version_info
> > 
> > Include Golang versions of the following structs:
> > - libxl_physinfo as Physinfo
> > - libxl_version_info as VersionInfo
> > - libxl_hwcap as Hwcap
> > 
> > Signed-off-by: Ronald Rojas 
> 
> Looks good -- just two minor comments...
> 
> > ---
> > Changes since last version
> > 
> > - Refactored creating Physinfo and VersionInfo types into
> > seperate toGo() functions.
> > 
> > - Used libxl__init() and libxl__dispose() on IDL
> > type physinfo
> > 
> > - Whitespace fixes
> > 
> > CC: xen-devel@lists.xen.org
> > CC: george.dun...@citrix.com
> > CC: ian.jack...@eu.citrix.com
> > CC: wei.l...@citrix.com
> > ---
> > ---
> >  tools/golang/xenlight/xenlight.go | 200 
> > ++
> >  1 file changed, 200 insertions(+)
> > 
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > index cbd3527..63cc805 100644
> > --- a/tools/golang/xenlight/xenlight.go
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -106,6 +106,103 @@ type Context struct {
> > ctx *C.libxl_ctx
> >  }
> >  
> > +type Hwcap []C.uint32_t
> > +
> > +func (chwcap C.libxl_hwcap) CToGo() (ghwcap Hwcap) {
> 
> Was there a reason you left this as CToGo() rather than just toGo()?
> 

No. This should be changed to toGo()

[snip]

> > +//int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo)
> > +func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err error) {
> > +   err = Ctx.CheckOpen()
> > +   if err != nil {
> > +   return
> > +   }
> > +   var cphys C.libxl_physinfo
> > +   C.libxl_physinfo_init(&cphys)
> > +
> > +   ret := C.libxl_get_physinfo(Ctx.ctx, &cphys)
> > +
> > +   if ret < 0 {
> > +   err = Error(ret)
> > +   return
> > +   }
> > +   physinfo = cphys.toGo()
> > +   C.libxl_physinfo_dispose(&cphys)
> 
> I think it would probably be more idiomatic to write "defer
> C.libxl_physinfo_dispose()" just after the physinfo_init.
> 
> If the init() actually allocated any memory, the current code would
> return without disposing of it if there was an error.  `defer` avoids
> that by ensuring that *all* return paths call the clean-up function.

Yep. Using defer is the better approach here. I will change
it in all instances where I use the init/dispose functions.

> 
> Other than that, looks great, thanks!
> 
>  -George
> 

Thanks,
Ronald

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


  1   2   >