Sunday, 24 February 2013

Disposable abstract class

public abstract class Disposable : IDisposable {
    public abstract void Dispose();
    protected void DisposeDisposableMembers() {
        const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        foreach (var fieldInfo in GetType().GetFields(bindingFlags)) {
            var disposable = fieldInfo.GetValue(this) as IDisposable;
            if (disposable != null) {
                disposable.Dispose();
                fieldInfo.SetValue(this, null);
            }
        }
    }
}

Saturday, 29 December 2012

Type conversion extension method

Converting types in C# can get verbose. For those like me, who can't help but try to reduce the verbosity of their code, I pieced together this set of extension methods to make type conversion as clean as possible.
public static class TypeConversionExtensions
{
 #region Non-generic
 private static Object To(this Object @object, Type type, Boolean returnDefaultOnFailedConversion)
 {
  Type underlyingTypeOfNullable = Nullable.GetUnderlyingType(type);
  try
  {
   return Convert.ChangeType(@object, underlyingTypeOfNullable ?? type);
  }
  catch (Exception exception)
  {
   if (returnDefaultOnFailedConversion)
    return type.IsValueType ? Activator.CreateInstance(type) : null;
   String typeName = type.Name;
   if (underlyingTypeOfNullable != null)
    typeName += " of " + underlyingTypeOfNullable.Name;
   throw new InvalidCastException("Object can't be cast to " + typeName, exception);
  }
 }
 public static Object To(this Object @object, Type type)
 {
  return @object.To(type, returnDefaultOnFailedConversion: false);
 }
 public static Object ToOrDefault(this Object @object, Type type)
 {
  return @object.To(type, returnDefaultOnFailedConversion: true);
 }
 #endregion
 #region Generic
 private static T To(this Object @object, Boolean returnDefaultOnFailedConversion)
 {
  return (T)@object.To(typeof(T), returnDefaultOnFailedConversion);
 }
 public static T To(this Object @object)
 {
  return @object.To(returnDefaultOnFailedConversion: false);
 }
 public static T ToOrDefault(this Object @object)
 {
  return @object.To(returnDefaultOnFailedConversion: true);
 }
 #endregion
}

Monday, 17 December 2012

Cross-platform function to get your cache line size

I wrote this function for a cache line aligned memory allocator which is for eventual use in my thread pool. It returns the line size (in bytes) of the host machine’s CPU cache, or 0 on failure. You can download it here. The source is below. Feel free to do whatever you want with it.
#ifndef GET_CACHE_LINE_SIZE_H_INCLUDED
#define GET_CACHE_LINE_SIZE_H_INCLUDED
 
// Author: Nick Strupat
// Date: October 29, 2010
// Returns the cache line size (in bytes) of the processor, or 0 on failure
 
#include <stddef.h>
size_t cache_line_size();
 
#if defined(__APPLE__)
 
#include <sys/sysctl.h>
size_t cache_line_size() {
 size_t line_size = 0;
 size_t sizeof_line_size = sizeof(line_size);
 sysctlbyname("hw.cachelinesize", &line_size, &sizeof_line_size, 0, 0);
 return line_size;
}
 
#elif defined(_WIN32)
 
#include <stdlib.h>
#include <windows.h>
size_t cache_line_size() {
 size_t line_size = 0;
 DWORD buffer_size = 0;
 DWORD i = 0;
 SYSTEM_LOGICAL_PROCESSOR_INFORMATION * buffer = 0;
 
 GetLogicalProcessorInformation(0, &buffer_size);
 buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)malloc(buffer_size);
 GetLogicalProcessorInformation(&buffer[0], &buffer_size);
 
 for (i = 0; i != buffer_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
  if (buffer[i].Relationship == RelationCache && buffer[i].Cache.Level == 1) {
   line_size = buffer[i].Cache.LineSize;
   break;
  }
 }
 
 free(buffer);
 return line_size;
}
 
#elif defined(linux)
 
#include <stdio.h>
size_t cache_line_size() {
 FILE * p = 0;
 p = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
 unsigned int i = 0;
 if (p) {
  fscanf(p, "%d", &i);
  fclose(p);
 }
 return i;
}
 
#else
#error Unrecognized platform
#endif
 
#endif