slab: add kmem_cache_zalloc()

You could argue that the caller could do this with a ctor, though it
depends on when we run the ctors.  Do we cache constructed objects in
magazines?  I'd guess 'yes', without a lot of thought, so then each
separate allocation wouldn't be zeroed.

The other reason to make a separate function for this is that it's
easier to just implement it.  We have the object size in the kc, but the
ctor function pointer actually *doesn't* have that info, so we'd need to
pass it through.  Minor pain, chance to mess it up, etc.

The other other reason is that Linux has this function.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/include/slab.h b/kern/include/slab.h
index 812985c..182b2bc 100644
--- a/kern/include/slab.h
+++ b/kern/include/slab.h
@@ -155,6 +155,7 @@
 void kmem_cache_destroy(struct kmem_cache *cp);
 /* Front end: clients of caches use these */
 void *kmem_cache_alloc(struct kmem_cache *cp, int flags);
+void *kmem_cache_zalloc(struct kmem_cache *cp, int flags);
 void kmem_cache_free(struct kmem_cache *cp, void *buf);
 /* Back end: internal functions */
 void kmem_cache_init(void);
diff --git a/kern/src/slab.c b/kern/src/slab.c
index 520932d..86411fb 100644
--- a/kern/src/slab.c
+++ b/kern/src/slab.c
@@ -636,6 +636,16 @@
 	return ret;
 }
 
+void *kmem_cache_zalloc(struct kmem_cache *kc, int flags)
+{
+	void *obj = kmem_cache_alloc(kc, flags);
+
+	if (!obj)
+		return NULL;
+	memset(obj, 0, kc->obj_size);
+	return obj;
+}
+
 /* Returns an object to the slab layer.  Caller must deconstruct the objects.
  * Note that objects in the slabs are unconstructed. */
 static void __kmem_free_to_slab(struct kmem_cache *cp, void *buf)